Introducció
El maig del 2021 es va reportar un problema en la recuperació de les respostes de PICA que es fan a través del connector de Sarcat de Canigó des de la seva versió 1.0.0. L’error es produeix perquè la PICA ha fet modificacions en els prefixos dels namespace de les respostes i el connector intentava cercar els nodes de resposta amb un namespace prefixat. El problema ha estat resolt a la versió 3.4.6 del Framework Canigó.
L’objectiu d’aquest article és mostrar com resoldre en problema en versions anteriors del connector.
Detall del problema
El mòdul d’integració amb Sarcat fa servir un mètode per a parsejar les respostes a les crides al servei. Aquest mètode intenta recuperar la resposta amb un prefix i, actualment, la PICA respon amb un prefix diferent.
Per exemple:
Node nodeResposta = SarcatXMLUtils.findNode(resposta.getDomNode(), "alta:SarcatAlAltaResponse");
SarcatAlAltaResponseDocument respostaAlta = null;
Quan la PICA retorna una resposta com la següent:
<ns2:SarcatAlAltaResponse xmlns:ns2="http://gencat.net/scsp/esquemes/peticion/alta">
<ns2:error>
<ns3:codi xmlns:ns3="http://gencat.net/scsp/esquemes/peticion/common">0</ns3:codi>
<ns3:descripcio xmlns:ns3="http://gencat.net/scsp/esquemes/peticion/common"/>
<ns3:descripcioExtesa xmlns:ns3="http://gencat.net/scsp/esquemes/peticion/common"/>
</ns2:error>
<ns2:assentamentRetorn anyPK="2021" codiURPK="0278" dataAlta="28/04/2021 10:35:22" numPK="183">
<ns2:errorAssentament>
<ns3:codi xmlns:ns3="http://gencat.net/scsp/esquemes/peticion/common">0</ns3:codi>
<ns3:descripcio xmlns:ns3="http://gencat.net/scsp/esquemes/peticion/common"/>
<ns3:descripcioExtesa xmlns:ns3="http://gencat.net/scsp/esquemes/peticion/common"/>
</ns2:errorAssentament>
</ns2:assentamentRetorn>
</ns2:SarcatAlAltaResponse>
On es pot comprovar que la resposta no disposa del prefix “alta” esperat.
Solució al problema en versions anteriors
Per a resoldre el problema en versions anteriors a la versió 2.0.0 del connector, cal reimplementar els mètodes del mòdul que fan la crida a SarcatXMLUtils.findNode per a especificar que no hi ha prefix en la crida:
Node nodeResposta = SarcatXMLUtils.findNode(resposta.getDomNode(), ":SarcatAlAltaResponse");
SarcatAlAltaResponseDocument respostaAlta = null;
A mode d’exemple, reimplementarem el mètode insertarAssentamentSafata de
cat.gencat.ctti.canigo.arch.integration.sarcat.pica.impl.SarcatConnectorImpl
que acaba utilitzant findNode
de cat.gencat.ctti.canigo.arch.integration.sarcat.pica.utils.SarcatXMLUtils
:
public class SarcatConnectorCustomImpl extends SarcatConnectorImpl implements SarcatConnector {
...
@Override
public SarcatAlAltaResponseDocument insertarAssentamentSafata(SarcatAlAltaRequestDocument document)
throws SarcatException {
this.log("[insertarAssentamentSafata] - Inici", 1);
long t1 = System.currentTimeMillis();
document.getSarcatAlAltaRequest().setDadesSessio(this.getDadesSessio("OP_INSERTAR_ASSENTAMENTS_SAFATA"));
SarcatAlAltaResponseDocument resposta = this.sarcatAlAlta(document);
this.log("[insertarAssentamentSafata] - Fi (" + (System.currentTimeMillis() - t1) + "ms)", 1);
return resposta;
}
private SarcatAlAltaResponseDocument sarcatAlAlta(SarcatAlAltaRequestDocument document) throws SarcatException {
IPICAServiceSincron servei = this.picaService.getPicaWebServiceSincronInstance("SARCAT_AL_ALTA");
servei.setDadesEspecifiques(this.crearDadesEspecifiques("SOL_01", document));
CridaSincronaResponseDocument resposta = this.realitzarPeticio(servei);
Node nodeResposta = SarcatXMLUtils.findNode(resposta.getDomNode(), ":SarcatAlAltaResponse");
SarcatAlAltaResponseDocument respostaAlta = null;
try {
respostaAlta = net.gencat.scsp.esquemes.peticion.alta.SarcatAlAltaResponseDocument.Factory
.parse(nodeResposta);
return respostaAlta;
} catch (XmlException var7) {
throw new SarcatException(this.getClass().toString(), "sarcatAlAlta",
"Error al parsejar l'objecte de resposta", var7);
}
}
...
}
Serà necessari reimplementar també el mètode findNode de la classe
cat.gencat.ctti.canigo.arch.integration.sarcat.pica.utils.SarcatXMLUtils
per a cercar el node independentment del prefix:
package cat.gencat.ctti.canigo.arch.integration.sarcat.pica.utils;
import cat.gencat.ctti.canigo.arch.integration.sarcat.pica.exceptions.SarcatException;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.XMLConstants;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;
/**
* The type Pica xml utils.
*
* @author cscanigo
*/
public class SarcatXMLUtils {
...
/**
* Mètode que busca el node dessitjat dintre d'un node pare.
*
* @param nodeInicial Node --> Node pare, que conté el node que volem buscar.
* @param nodeBuscar String --> Nom del node a buscar.
* @return Node --> Node a buscar.
*/
public static Node findNode(Node nodeInicial, String nodeBuscar) {
if (nodeInicial != null && nodeInicial.getNodeName() != null && nodeInicial.getNodeName().contains(nodeBuscar)) {
return nodeInicial;
} else if (nodeInicial != null && nodeInicial.getChildNodes() != null) {
NodeList llistaNodes = nodeInicial.getChildNodes();
for (int i = 0; i < llistaNodes.getLength(); i++) {
Node node = findNode(llistaNodes.item(i), nodeBuscar);
if (node != null) {
return node;
}
}
}
return null;
}
...
}
Amb la instanciació del bean, per exemple amb xml a app-custom-beans.xml
ubicat a /src/main/resources/spring/
:
<bean id="sarcatServiceCustom" class="cat.gencat.ctti.canigo.arch.integration.sarcat.pica.impl.SarcatConnectorCustomImpl" scope="prototype">
<description>
S@RCAT service for Canigo 3.0
</description>
<property name="passwordType" value="${pica.modes.passwordType}"/>
<property name="picaService" ref="${sarcat.picaServiceBeanName:picaService}"/>
<property name="finalitat" value="${sarcat.finalitat}"/>
<property name="nifEmisor" value="${sarcat.nifEmisor}" />
<property name="nomEmisor" value="${sarcat.nomEmisor}" />
<property name="urlPica" value="${sarcat.urlPica}"/>
<property name="usuari" value="${sarcat.usuari}"/>
<property name="password" value="${sarcat.password}"/>
<property name="funcionari" ref="funcionari" />
</bean>
O bé instanciant-lo amb Java.
Finalment, al vostre projecte, caldrà aplicar la nova implementació:
@Autowired
@Qualifier("sarcatServiceCustom")
private SarcatConnector sarcatConnector;
Conclusió
En cas de fer ús del connector de Sarcat de PICA del Framework Canigó 3.4.x (des de versió 2.0.0 fins a la versió 2.3.1 del connector) recomanem actualitzar-se a la versió 2.3.2. En cas de fer ús del connector de Sarcat de PICA del Framework Canigó inferior a 3.4.x (des de versió 1.0.0 fins a la versió 1.2.3 del connector) serà necessari reimplementar el connector tal com s’ha mostrat en aquest article.
Informació
Per a més informació, podeu consultar:
-
Reimplementació del mètode insertarAssentamentSafata a cat.gencat.ctti.canigo.arch.integration.sarcat.pica.impl.SarcatConnectorCustomImpl
-
Reimplementació de cat.gencat.ctti.canigo.arch.integration.sarcat.pica.utils.SarcatXMLUtils