InResponseHandler.java
- /*
- * GovWay - A customizable API Gateway
- * https://govway.org
- *
- * Copyright (c) 2005-2025 Link.it srl (https://link.it).
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3, as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- package org.openspcoop2.pdd.core.handlers.transazioni;
- import java.io.ByteArrayOutputStream;
- import java.util.Date;
- import org.apache.commons.lang.StringUtils;
- import org.openspcoop2.core.constants.Costanti;
- import org.openspcoop2.core.constants.TipoPdD;
- import org.openspcoop2.message.OpenSPCoop2RestMessage;
- import org.openspcoop2.message.OpenSPCoop2SoapMessage;
- import org.openspcoop2.message.constants.MessageRole;
- import org.openspcoop2.message.constants.ServiceBinding;
- import org.openspcoop2.message.xml.MessageXMLUtils;
- import org.openspcoop2.pdd.config.OpenSPCoop2Properties;
- import org.openspcoop2.pdd.core.CostantiPdD;
- import org.openspcoop2.pdd.core.connettori.ConnettoreBase;
- import org.openspcoop2.pdd.core.handlers.HandlerException;
- import org.openspcoop2.pdd.core.handlers.InResponseContext;
- import org.openspcoop2.pdd.core.transazioni.InResponseStatefulObject;
- import org.openspcoop2.pdd.core.transazioni.RepositoryGestioneStateful;
- import org.openspcoop2.pdd.core.transazioni.Transaction;
- import org.openspcoop2.pdd.core.transazioni.TransactionContext;
- import org.openspcoop2.pdd.core.transazioni.TransactionDeletedException;
- import org.openspcoop2.pdd.core.transazioni.TransactionNotExistsException;
- import org.openspcoop2.pdd.core.transazioni.TransactionStatefulNotSupportedException;
- import org.openspcoop2.pdd.logger.DumpUtility;
- import org.openspcoop2.pdd.logger.OpenSPCoop2Logger;
- import org.openspcoop2.utils.json.JSONUtils;
- import org.openspcoop2.utils.transport.http.HttpRequestMethod;
- import org.slf4j.Logger;
- import com.fasterxml.jackson.databind.JsonNode;
- /**
- * InResponseHandler
- *
- * @author Poli Andrea (poli@link.it)
- * @author $Author$
- * @version $Rev$, $Date$
- */
- public class InResponseHandler extends FirstPositionHandler implements org.openspcoop2.pdd.core.handlers.InResponseHandler{
- @Override
- public void invoke(InResponseContext context) throws HandlerException {
-
- OpenSPCoop2Properties op2Properties = OpenSPCoop2Properties.getInstance();
- if(op2Properties.isTransazioniEnabled()==false) {
- return;
- }
- String idTransazione = null;
- if(context!=null && context.getPddContext()!=null) {
- idTransazione = (String) context.getPddContext().getObject(Costanti.ID_TRANSAZIONE);
- }
-
- //System.out.println("------------- InResponseHandler ("+idTransazione+")("+context.getTipoPorta().getTipo()+") -------------------");
-
-
-
- // Gestione FAULT
- String fault = null;
- String formatoFault = null;
- try{
- if(context!=null && context.getMessaggio()!=null){
- if(ServiceBinding.SOAP.equals(context.getMessaggio().getServiceBinding())) {
- OpenSPCoop2SoapMessage soapMsg = context.getMessaggio().castAsSoap();
- if(soapMsg.hasSOAPFault()){
-
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- bout.write(context.getMessaggio().getAsByte(soapMsg.getSOAPPart().getEnvelope(), false));
- bout.flush();
- bout.close();
-
- Logger log = OpenSPCoop2Logger.getLoggerOpenSPCoopTransazioni(op2Properties.isTransazioniDebug());
- if(op2Properties.isTransazioniFaultPrettyPrint()){
- // Faccio una pretty-print: potevo fare anche direttamente passando il fault a metodo prettyPrint,
- // Pero' non veniva stampato correttamente il SOAPFault. Mi appoggio allora a SoapUtils.
- //byte [] content = org.openspcoop2.message.soap.TunnelSoapUtils.sbustamentoMessaggio(context.getMessaggio());
- byte [] content = bout.toByteArray();
- fault = DumpUtility.toString(MessageXMLUtils.getInstance(soapMsg.getFactory()).newDocument(content), log, context.getMessaggio());
- //System.out.println("IMPOSTATO FAULT IN TRANSACTION ["+fault+"]");
- }
- else{
-
- fault = bout.toString();
- }
-
- formatoFault = soapMsg.getMessageType().name();
-
- }
- }
- else {
- OpenSPCoop2RestMessage<?> restMsg = context.getMessaggio().castAsRest();
- if(restMsg.isProblemDetailsForHttpApis_RFC7807() || MessageRole.FAULT.equals(restMsg.getMessageRole())) {
- switch (restMsg.getMessageType()) {
- case XML:
-
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- restMsg.writeTo(bout, false);
- bout.flush();
- bout.close();
-
- Logger log = OpenSPCoop2Logger.getLoggerOpenSPCoopTransazioni(op2Properties.isTransazioniDebug());
- if(op2Properties.isTransazioniFaultPrettyPrint()){
- // Faccio una pretty-print: potevo fare anche direttamente passando il fault a metodo prettyPrint,
- // Pero' non veniva stampato correttamente il SOAPFault. Mi appoggio allora a SoapUtils.
- //byte [] content = org.openspcoop2.message.soap.TunnelSoapUtils.sbustamentoMessaggio(context.getMessaggio());
- byte [] content = bout.toByteArray();
- fault = DumpUtility.toString(MessageXMLUtils.getInstance(restMsg.getFactory()).newDocument(content), log, context.getMessaggio());
- //System.out.println("IMPOSTATO FAULT IN TRANSACTION ["+fault+"]");
- }
- else{
-
- fault = bout.toString();
- }
-
- formatoFault = restMsg.getMessageType().name();
-
- break;
-
- case JSON:
-
- bout = new ByteArrayOutputStream();
- restMsg.writeTo(bout, false);
- bout.flush();
- bout.close();
-
- if(op2Properties.isTransazioniFaultPrettyPrint()){
-
- JSONUtils jsonUtils = JSONUtils.getInstance(true);
- byte [] content = bout.toByteArray();
- JsonNode jsonNode = jsonUtils.getAsNode(content);
- fault = jsonUtils.toString(jsonNode);
-
- }
- else{
-
- fault = bout.toString();
- }
-
- formatoFault = restMsg.getMessageType().name();
-
- break;
- default:
- break;
- }
- }
- }
- }
- }catch(Exception e){
- throw new HandlerException("Errore durante il dump del soap fault",e);
- }
-
-
-
-
- if(context!=null && context.getTransazioneApplicativoServer()!=null) {
-
- try{
-
- // date
- context.getTransazioneApplicativoServer().setDataAccettazioneRisposta(context.getDataAccettazioneRisposta());
-
- Date dataIngressoRisposta = context.getDataElaborazioneMessaggio();
- if(context.getDataTerminataInvocazioneConnettore()!=null) {
- dataIngressoRisposta = context.getDataTerminataInvocazioneConnettore(); // nella latenza porta deve rientrare anche la negoziazione della connessione
- }
- context.getTransazioneApplicativoServer().setDataIngressoRisposta(dataIngressoRisposta);
-
- if(context.getDataPrimaInvocazioneConnettore()!=null) {
- // aggiorno informazione sulla data, poiche' piu' precisa (nella latenza porta deve rientrare anche il dump ed il rilascio della connessione)
- context.getTransazioneApplicativoServer().setDataUscitaRichiesta(context.getDataPrimaInvocazioneConnettore());
- }
-
- if(context.getDataRichiestaInoltrata()!=null) {
- context.getTransazioneApplicativoServer().setDataUscitaRichiestaStream(context.getDataRichiestaInoltrata());
- }
-
-
- // return code
- context.getTransazioneApplicativoServer().setCodiceRisposta(context.getReturnCode()+"");
-
- // eventuali errori
- context.getTransazioneApplicativoServer().setUltimoErrore(context.getErroreConsegna());
-
-
- // aggiorno location
- if(context.getConnettore()!=null){
- context.getTransazioneApplicativoServer().setLocationConnettore(context.getConnettore().getLocation());
- }
-
- // fault
- if(fault!=null){
- context.getTransazioneApplicativoServer().setFault(fault);
- context.getTransazioneApplicativoServer().setFormatoFault(formatoFault);
- }
-
- }catch(Exception e){
- throw new HandlerException("Errore durante il processamento delle informazioni relative alla consegna per l'applicativo '"+context.getTransazioneApplicativoServer().getServizioApplicativoErogatore()+"': "+e.getMessage(),e);
- }
-
- }
- else {
-
-
- boolean gestioneStateful = false;
- Transaction tr = null;
- try{
- tr = TransactionContext.getTransaction(idTransazione);
- }catch(TransactionNotExistsException e){
- gestioneStateful = true;
- }
-
- try{
-
- InResponseStatefulObject sObject = null;
-
- if(tr==null && gestioneStateful){
-
- sObject = new InResponseStatefulObject();
-
- //System.out.println("@@@@@REPOSITORY@@@@@ InResponseHandler ID TRANSAZIONE ["+idTransazione+"] GESTIONE COMPLETA");
-
- Date dataRichiestaInoltrata = context.getDataRichiestaInoltrata();
- // La porta di dominio mi passa sempre questa informazione.
- // Nel PddMonitor, invece, la data deve essere visualizzata solo se la dimensione e' diverso da 0 e cioe' se c'e' un messaggio di risposta.
- //if(dimensione!=null && dimensione>0){
- // L'INFORMAZIONE DEVE INVECE ESSERE SEMPRE SALVATA PER LA SIMULAZIONE DEI MESSAGGI DIAGNOSTICI
- // INEFFICIENTE: RepositoryGestioneStateful.addDataAccettazioneRisposta(idTransazione, dataAccettazioneRisposta);
- sObject.setDataRichiestaInoltrata(dataRichiestaInoltrata);
-
- Date dataAccettazioneRisposta = context.getDataAccettazioneRisposta();
- // La porta di dominio mi passa sempre questa informazione.
- // Nel PddMonitor, invece, la data deve essere visualizzata solo se la dimensione e' diverso da 0 e cioe' se c'e' un messaggio di risposta.
- //if(dimensione!=null && dimensione>0){
- // L'INFORMAZIONE DEVE INVECE ESSERE SEMPRE SALVATA PER LA SIMULAZIONE DEI MESSAGGI DIAGNOSTICI
- // INEFFICIENTE: RepositoryGestioneStateful.addDataAccettazioneRisposta(idTransazione, dataAccettazioneRisposta);
- sObject.setDataAccettazioneRisposta(dataAccettazioneRisposta);
-
- Date dataIngressoRisposta = context.getDataElaborazioneMessaggio();
- if(context.getDataTerminataInvocazioneConnettore()!=null) {
- dataIngressoRisposta = context.getDataTerminataInvocazioneConnettore(); // nella latenza porta deve rientrare anche la negoziazione della connessione
- }
- // La porta di dominio mi passa sempre questa informazione.
- // Nel PddMonitor, invece, la data deve essere visualizzata solo se la dimensione e' diverso da 0 e cioe' se c'e' un messaggio di risposta.
- //if(dimensione!=null && dimensione>0){
- // L'INFORMAZIONE DEVE INVECE ESSERE SEMPRE SALVATA PER LA SIMULAZIONE DEI MESSAGGI DIAGNOSTICI
- // INEFFICIENTE: RepositoryGestioneStateful.addDataIngressoRisposta(idTransazione, dataElaborazioneMessaggio);
- sObject.setDataIngressoRisposta(dataIngressoRisposta);
-
- if(context.getDataPrimaInvocazioneConnettore()!=null) {
- // aggiorno informazione sulla data, poiche' piu' precisa (nella latenza porta deve rientrare anche il dump ed il rilascio della connessione)
- sObject.setDataUscitaRichiesta(context.getDataPrimaInvocazioneConnettore());
- }
-
- // INEFFICIENTE: RepositoryGestioneStateful.addCodiceTrasportoRichiesta(idTransazione, context.getReturnCode()+"");
- sObject.setReturnCode(context.getReturnCode()+"");
-
- if(context.getConnettore()!=null){
-
- // INEFFICIENTE: RepositoryGestioneStateful.addLocation(idTransazione, context.getConnettore().getLocation());
- sObject.setLocation(context.getConnettore().getLocation());
-
- }
-
- if(fault!=null){
- if(TipoPdD.APPLICATIVA.equals(context.getTipoPorta())){
- sObject.setFaultIntegrazione(fault);
- sObject.setFormatoFaultIntegrazione(formatoFault);
- }
- else{
- sObject.setFaultCooperazione(fault);
- sObject.setFormatoFaultCooperazione(formatoFault);
- }
- }
-
- }else{
-
- if(tr==null) {
- throw new HandlerException("Transaction is null");
- }
- if(context==null) {
- throw new HandlerException("Context is null");
- }
-
- Date dataRichiestaInoltrata = context.getDataRichiestaInoltrata();
- // La porta di dominio mi passa sempre questa informazione.
- // Nel PddMonitor, invece, la data deve essere visualizzata solo se la dimensione e' diverso da 0 e cioe' se c'e' un messaggio di risposta.
- //if(dimensione!=null && dimensione>0){
- // L'INFORMAZIONE DEVE INVECE ESSERE SEMPRE SALVATA PER LA SIMULAZIONE DEI MESSAGGI DIAGNOSTICI
- try{
- tr.setDataRichiestaInoltrata(dataRichiestaInoltrata);
- //System.out.println("SET DATA ("+dataAccettazioneRisposta.toString()+")");
- }catch(TransactionDeletedException e){
- //System.out.println("@@@@@REPOSITORY@@@@@ InResponseHandler SET DATA ("+dataAccettazioneRisposta.toString()+")");
- // INEFFICIENTE: RepositoryGestioneStateful.addDataAccettazioneRisposta(idTransazione, dataAccettazioneRisposta);
- if(sObject==null)
- sObject = new InResponseStatefulObject();
- sObject.setDataRichiestaInoltrata(dataRichiestaInoltrata);
- }
-
- Date dataAccettazioneRisposta = context.getDataAccettazioneRisposta();
- // La porta di dominio mi passa sempre questa informazione.
- // Nel PddMonitor, invece, la data deve essere visualizzata solo se la dimensione e' diverso da 0 e cioe' se c'e' un messaggio di risposta.
- //if(dimensione!=null && dimensione>0){
- // L'INFORMAZIONE DEVE INVECE ESSERE SEMPRE SALVATA PER LA SIMULAZIONE DEI MESSAGGI DIAGNOSTICI
- try{
- tr.setDataAccettazioneRisposta(dataAccettazioneRisposta);
- //System.out.println("SET DATA ("+dataAccettazioneRisposta.toString()+")");
- }catch(TransactionDeletedException e){
- //System.out.println("@@@@@REPOSITORY@@@@@ InResponseHandler SET DATA ("+dataAccettazioneRisposta.toString()+")");
- // INEFFICIENTE: RepositoryGestioneStateful.addDataAccettazioneRisposta(idTransazione, dataAccettazioneRisposta);
- if(sObject==null)
- sObject = new InResponseStatefulObject();
- sObject.setDataAccettazioneRisposta(dataAccettazioneRisposta);
- }
-
- Date dataIngressoRisposta = context.getDataElaborazioneMessaggio();
- if(context.getDataTerminataInvocazioneConnettore()!=null) {
- dataIngressoRisposta = context.getDataTerminataInvocazioneConnettore(); // nella latenza porta deve rientrare anche la negoziazione della connessione
- }
- // La porta di dominio mi passa sempre questa informazione.
- // Nel PddMonitor, invece, la data deve essere visualizzata solo se la dimensione e' diverso da 0 e cioe' se c'e' un messaggio di risposta.
- //if(dimensione!=null && dimensione>0){
- // L'INFORMAZIONE DEVE INVECE ESSERE SEMPRE SALVATA PER LA SIMULAZIONE DEI MESSAGGI DIAGNOSTICI
- try{
- tr.setDataIngressoRisposta(dataIngressoRisposta);
- //System.out.println("SET DATA ("+dataElaborazioneMessaggio.toString()+")");
- }catch(TransactionDeletedException e){
- //System.out.println("@@@@@REPOSITORY@@@@@ InResponseHandler SET DATA ("+dataElaborazioneMessaggio.toString()+")");
- // INEFFICIENTE: RepositoryGestioneStateful.addDataIngressoRisposta(idTransazione, dataElaborazioneMessaggio);
- if(sObject==null)
- sObject = new InResponseStatefulObject();
- sObject.setDataIngressoRisposta(dataIngressoRisposta);
- }
-
- if(context.getDataPrimaInvocazioneConnettore()!=null) {
- // aggiorno informazione sulla data, poiche' piu' precisa (nella latenza porta deve rientrare anche il dump ed il rilascio della connessione)
- try{
- tr.setDataUscitaRichiesta(context.getDataPrimaInvocazioneConnettore());
- //System.out.println("SET DATA ("+dataElaborazioneMessaggio.toString()+")");
- }catch(TransactionDeletedException e){
- //System.out.println("@@@@@REPOSITORY@@@@@ InResponseHandler SET DATA ("+dataElaborazioneMessaggio.toString()+")");
- // INEFFICIENTE: RepositoryGestioneStateful.addDataIngressoRisposta(idTransazione, dataElaborazioneMessaggio);
- if(sObject==null)
- sObject = new InResponseStatefulObject();
- sObject.setDataUscitaRichiesta(context.getDataPrimaInvocazioneConnettore());
- }
- }
-
- try{
- //System.out.println("SET CODICE TRASPORTO RICHIESTA ["+context.getReturnCode()+"]");
- if(context!=null) {
- tr.setCodiceTrasportoRichiesta(context.getReturnCode()+"");
- }
- }catch(TransactionDeletedException e){
- //System.out.println("@@@@@REPOSITORY@@@@@ InResponseHandler SET CODICE TRASPORTO RICHIESTA ["+context.getReturnCode()+"]");
- // INEFFICIENTE: RepositoryGestioneStateful.addCodiceTrasportoRichiesta(idTransazione, context.getReturnCode()+"");
- if(sObject==null)
- sObject = new InResponseStatefulObject();
- sObject.setReturnCode(context.getReturnCode()+"");
- }
-
- try{
- // update location impostata nel OutRequest (location modificata dal connettore)
- //System.out.println("SET LOCATION ["+context.getConnettore().getLocation()+"]");
- String connettoreRequestUrl = null;
- String connettoreRequestMethod = null;
- if(context.getPddContext()!=null) {
- if(context.getPddContext().containsKey(CostantiPdD.CONNETTORE_REQUEST_URL)) {
- connettoreRequestUrl = (String) context.getPddContext().getObject(CostantiPdD.CONNETTORE_REQUEST_URL);
- }
- if(context.getPddContext().containsKey(CostantiPdD.CONNETTORE_REQUEST_METHOD)) {
- Object o = context.getPddContext().getObject(CostantiPdD.CONNETTORE_REQUEST_METHOD);
- if(o instanceof String) {
- connettoreRequestMethod = (String) o;
- }
- else if(o instanceof HttpRequestMethod) {
- HttpRequestMethod oConnettoreRequestMethod = (HttpRequestMethod) o;
- connettoreRequestMethod = oConnettoreRequestMethod.name();
- }
- }
- }
- if(!StringUtils.isEmpty(connettoreRequestUrl) && !StringUtils.isEmpty(connettoreRequestMethod)) {
- String prefix = "";
- if(ConnettoreBase.LOCATION_CACHED.equals(context.getConnettore().getLocation())){
- prefix = context.getConnettore().getLocation()+ConnettoreBase.LOCATION_CACHED_SEPARATOR_REQUEST_URL;
- }
- tr.setLocation(prefix+CostantiPdD.getConnettoreRequest(connettoreRequestUrl, connettoreRequestMethod));
- }
- else {
- if(context!=null && context.getConnettore()!=null) {
- tr.setLocation(context.getConnettore().getLocation());
- }
- }
- }catch(TransactionDeletedException e){
- //System.out.println("@@@@@REPOSITORY@@@@@ OutRequestHandler SET LOCATION ["+context.getConnettore().getLocation()+"]");
- // INEFFICIENTE: RepositoryGestioneStateful.addLocation(idTransazione, context.getConnettore().getLocation());
- if(sObject==null)
- sObject = new InResponseStatefulObject();
- sObject.setLocation(context.getConnettore().getLocation());
- }
-
- try{
- if(fault!=null){
- if(TipoPdD.APPLICATIVA.equals(context.getTipoPorta())){
- tr.setFaultIntegrazione(fault);
- tr.setFormatoFaultIntegrazione(formatoFault);
- }
- else{
- tr.setFaultCooperazione(fault);
- tr.setFormatoFaultCooperazione(formatoFault);
- }
- }
- }catch(TransactionDeletedException e){
- if(fault!=null){
- if(sObject==null)
- sObject = new InResponseStatefulObject();
- if(TipoPdD.APPLICATIVA.equals(context.getTipoPorta())){
- sObject.setFaultIntegrazione(fault);
- sObject.setFormatoFaultIntegrazione(formatoFault);
- }
- else{
- sObject.setFaultCooperazione(fault);
- sObject.setFormatoFaultCooperazione(formatoFault);
- }
- }
- }
-
- }
-
- if(sObject!=null){
- // Gestione stateful
- RepositoryGestioneStateful.addInResponseStatefulObject(context.getProtocolFactory().getProtocol(),idTransazione, sObject);
- }
-
- }catch(TransactionStatefulNotSupportedException e){
- throw new HandlerException("Errore durante il processamento dell'handler: "+e.getMessage(),e);
- }
-
- }
-
- }
- }