ConnettoreBase.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */

  20. package org.openspcoop2.pdd.core.connettori;

  21. import java.io.File;
  22. import java.io.InputStream;
  23. import java.text.SimpleDateFormat;
  24. import java.util.ArrayList;
  25. import java.util.Date;
  26. import java.util.HashMap;
  27. import java.util.Iterator;
  28. import java.util.List;
  29. import java.util.Map;

  30. import org.apache.commons.lang.StringUtils;
  31. import org.openspcoop2.core.config.DumpConfigurazione;
  32. import org.openspcoop2.core.config.InvocazioneCredenziali;
  33. import org.openspcoop2.core.config.PortaApplicativa;
  34. import org.openspcoop2.core.config.PortaDelegata;
  35. import org.openspcoop2.core.config.Proprieta;
  36. import org.openspcoop2.core.config.ResponseCachingConfigurazione;
  37. import org.openspcoop2.core.config.ResponseCachingConfigurazioneControl;
  38. import org.openspcoop2.core.config.ResponseCachingConfigurazioneRegola;
  39. import org.openspcoop2.core.config.constants.CostantiConfigurazione;
  40. import org.openspcoop2.core.config.constants.StatoFunzionalita;
  41. import org.openspcoop2.core.constants.Costanti;
  42. import org.openspcoop2.core.constants.CostantiConnettori;
  43. import org.openspcoop2.core.constants.TipoPdD;
  44. import org.openspcoop2.core.id.IDAccordo;
  45. import org.openspcoop2.core.id.IDPortaApplicativa;
  46. import org.openspcoop2.core.id.IDPortaDelegata;
  47. import org.openspcoop2.core.id.IDSoggetto;
  48. import org.openspcoop2.core.transazioni.constants.TipoMessaggio;
  49. import org.openspcoop2.message.OpenSPCoop2Message;
  50. import org.openspcoop2.message.OpenSPCoop2MessageProperties;
  51. import org.openspcoop2.message.constants.MessageRole;
  52. import org.openspcoop2.message.constants.MessageType;
  53. import org.openspcoop2.message.constants.ServiceBinding;
  54. import org.openspcoop2.message.exception.ParseExceptionUtils;
  55. import org.openspcoop2.pdd.config.ConfigurazionePdDManager;
  56. import org.openspcoop2.pdd.config.OpenSPCoop2Properties;
  57. import org.openspcoop2.pdd.core.AbstractCore;
  58. import org.openspcoop2.pdd.core.CostantiPdD;
  59. import org.openspcoop2.pdd.core.PdDContext;
  60. import org.openspcoop2.pdd.core.controllo_traffico.PolicyTimeoutConfig;
  61. import org.openspcoop2.pdd.core.controllo_traffico.SogliaDimensioneMessaggio;
  62. import org.openspcoop2.pdd.core.dynamic.DynamicInfo;
  63. import org.openspcoop2.pdd.core.dynamic.DynamicUtils;
  64. import org.openspcoop2.pdd.core.handlers.GestoreHandlers;
  65. import org.openspcoop2.pdd.core.handlers.HandlerException;
  66. import org.openspcoop2.pdd.core.handlers.OutRequestContext;
  67. import org.openspcoop2.pdd.core.handlers.PostOutRequestContext;
  68. import org.openspcoop2.pdd.core.handlers.PreInResponseContext;
  69. import org.openspcoop2.pdd.core.response_caching.GestoreCacheResponseCaching;
  70. import org.openspcoop2.pdd.core.response_caching.ResponseCached;
  71. import org.openspcoop2.pdd.core.token.EsitoNegoziazioneToken;
  72. import org.openspcoop2.pdd.core.token.GestoreToken;
  73. import org.openspcoop2.pdd.core.token.PolicyNegoziazioneToken;
  74. import org.openspcoop2.pdd.core.transazioni.Transaction;
  75. import org.openspcoop2.pdd.core.transazioni.TransactionContext;
  76. import org.openspcoop2.pdd.core.transazioni.TransactionNotExistsException;
  77. import org.openspcoop2.pdd.logger.MsgDiagnostico;
  78. import org.openspcoop2.pdd.logger.OpenSPCoop2Logger;
  79. import org.openspcoop2.pdd.logger.transazioni.ConfigurazioneTracciamento;
  80. import org.openspcoop2.pdd.mdb.ConsegnaContenutiApplicativi;
  81. import org.openspcoop2.protocol.sdk.Busta;
  82. import org.openspcoop2.protocol.sdk.dump.DumpException;
  83. import org.openspcoop2.protocol.sdk.dump.Messaggio;
  84. import org.openspcoop2.protocol.sdk.state.IState;
  85. import org.openspcoop2.protocol.sdk.state.RequestInfo;
  86. import org.openspcoop2.protocol.utils.ModIUtils;
  87. import org.openspcoop2.protocol.utils.ModIValidazioneSemanticaProfiloSicurezza;
  88. import org.openspcoop2.utils.MapKey;
  89. import org.openspcoop2.utils.NameValue;
  90. import org.openspcoop2.utils.Utilities;
  91. import org.openspcoop2.utils.date.DateManager;
  92. import org.openspcoop2.utils.date.DateUtils;
  93. import org.openspcoop2.utils.io.DumpByteArrayOutputStream;
  94. import org.openspcoop2.utils.io.notifier.NotifierInputStreamParams;
  95. import org.openspcoop2.utils.resources.Loader;
  96. import org.openspcoop2.utils.transport.TransportUtils;
  97. import org.openspcoop2.utils.transport.http.HttpConstants;
  98. import org.openspcoop2.utils.transport.http.HttpUtilities;
  99. import org.slf4j.Logger;

  100. /**
  101.  * Contiene una classe base per i connettori
  102.  *
  103.  * @author Poli Andrea (apoli@link.it)
  104.  * @author $Author$
  105.  * @version $Rev$, $Date$
  106.  */
  107. public abstract class ConnettoreBase extends AbstractCore implements IConnettore {

  108.     public static final MapKey<String> RESPONSE_FROM_CACHE = org.openspcoop2.utils.Map.newMapKey("RESPONSE_READED_FROM_CACHE");
  109.     public static final String LOCATION_CACHED = "govway://responseCaching";
  110.     public static final String LOCATION_CACHED_SEPARATOR_REQUEST_URL = "\n";
  111.    
  112.     /** Proprieta' del connettore */
  113.     protected java.util.Map<String,String> properties;
  114.    
  115.     /** Tipo di Connettore */
  116.     protected String tipoConnettore;
  117.    
  118.     /** Msg di richiesta */
  119.     protected OpenSPCoop2Message requestMsg;    
  120.     protected boolean isSoap = false;
  121.     protected boolean isRest = false;
  122.    
  123.     /** Indicazione su di un eventuale sbustamento SOAP */
  124.     protected boolean sbustamentoSoap;
  125.    
  126.     /** Proprieta' del trasporto che deve gestire il connettore */
  127.     protected Map<String, List<String>> propertiesTrasporto;
  128.    
  129.     /** Proprieta' urlBased che deve gestire il connettore */
  130.     protected Map<String, List<String>> propertiesUrlBased;
  131.    
  132.     /** Tipo di Autenticazione */
  133.     //private String tipoAutenticazione;
  134.     /** Credenziali per l'autenticazione */
  135.     protected InvocazioneCredenziali credenziali;
  136.    
  137.     /** Busta */
  138.     protected Busta busta;
  139.    
  140.     /** Indicazione se siamo in modalita' debug */
  141.     protected boolean debug = false;

  142.     /** OpenSPCoopProperties */
  143.     protected OpenSPCoop2Properties openspcoopProperties = null;

  144.     /** Identificativo */
  145.     protected String idMessaggio;
  146.    
  147.     /** Logger */
  148.     protected ConnettoreLogger logger = null;

  149.     /** Loader loader */
  150.     protected Loader loader = null;
  151.    
  152.     /** Errore generato con un prefisso del connettore */
  153.     protected boolean generateErrorWithConnectorPrefix = true;
  154.    
  155.     /** Identificativo Modulo */
  156.     protected String idModulo = null;
  157.    
  158.     /** motivo di un eventuale errore */
  159.     protected String errore = null;
  160.     /** Messaggio di risposta */
  161.     protected OpenSPCoop2Message responseMsg = null;
  162.     /** Codice Operazione Effettuata */
  163.     protected int codice;
  164.     /** ContentLength */
  165.     protected long contentLength = -1;
  166.     /** File tmp */
  167.     protected String location = null;
  168.     /** Eccezione processamento */
  169.     protected Exception eccezioneProcessamento = null;
  170.     /** Proprieta' del trasporto della risposta */
  171.     protected Map<String, List<String>> propertiesTrasportoRisposta = new HashMap<>();
  172.     /** CreationDate */
  173.     protected Date creationDate;
  174.    
  175.     /** MessaggioDiagnostico */
  176.     protected MsgDiagnostico msgDiagnostico;
  177.     /** OutRequestContext */
  178.     protected OutRequestContext outRequestContext;
  179.     /** PostOutRequestContext */
  180.     protected PostOutRequestContext postOutRequestContext;
  181.     /** PreInResponseContext */
  182.     protected PreInResponseContext preInResponseContext;
  183.     /** State */
  184.     protected IState state;
  185.    
  186.     /** SOAPAction */
  187.     protected String soapAction = null;
  188.    
  189.     /** RequestInfo */
  190.     protected RequestInfo requestInfo;
  191.    
  192.     /** Caching Response */
  193.     private boolean responseAlready = false;
  194.     private ResponseCachingConfigurazione responseCachingConfig = null;
  195.     private String responseCachingDigest = null;

  196.     /** Policy Token */
  197.     private PolicyNegoziazioneToken policyNegoziazioneToken;
  198.     protected PolicyTimeoutConfig policyTimeoutConfig;
  199.    
  200.     protected Date dataRichiestaInoltrata;
  201.     @Override
  202.     public Date getDataRichiestaInoltrata() {
  203.         return this.dataRichiestaInoltrata;
  204.     }
  205.    
  206.     protected Date dataAccettazioneRisposta;
  207.     @Override
  208.     public Date getDataAccettazioneRisposta(){
  209.         return this.dataAccettazioneRisposta;
  210.     }
  211.    
  212.     protected DumpRaw dumpRaw = null;
  213.     protected boolean logFileTrace_headers = false;
  214.     protected boolean logFileTrace_payload = false;
  215.    
  216.     private boolean registerSendIntoContext = true;
  217.     public void setRegisterSendIntoContext(boolean registerSendIntoContext) {
  218.         this.registerSendIntoContext = registerSendIntoContext;
  219.     }

  220.     private IDAccordo idAccordo = null;
  221.     protected IDAccordo getIdAccordo() {
  222.         return this.idAccordo;
  223.     }

  224.     protected String idTransazione;
  225.    
  226.     protected int dumpBinario_soglia;
  227.     protected File dumpBinario_repositoryFile;
  228.    
  229.     protected PortaApplicativa pa;
  230.     protected String nomeConnettoreAsincrono;
  231.     protected PortaDelegata pd;
  232.    
  233.     protected boolean useTimeoutInputStream = false;
  234.    
  235.     protected boolean useLimitedInputStream = false;
  236.     protected SogliaDimensioneMessaggio limitBytes = null;
  237.    
  238.     protected boolean useDiagnosticInputStream = false;
  239.    
  240.     protected List<Proprieta> proprietaPorta;
  241.    
  242.     protected ConnettoreBase(){
  243.         this.creationDate = DateManager.getDate();
  244.     }
  245.    
  246.     public void setPa(PortaApplicativa pa) {
  247.         this.pa = pa;
  248.     }

  249.     public void setPd(PortaDelegata pd) {
  250.         this.pd = pd;
  251.     }
  252.    
  253.     protected boolean initialize(ConnettoreMsg request, boolean connectorPropertiesRequired, ResponseCachingConfigurazione responseCachingConfig){
  254.        
  255.         this.openspcoopProperties = OpenSPCoop2Properties.getInstance();
  256.         this.loader = Loader.getInstance();

  257.         if(request==null){
  258.             this.errore = "Messaggio da consegnare is Null (ConnettoreMsg)";
  259.             return false;
  260.         }
  261.        
  262.         // Raccolta parametri per costruttore logger
  263.         this.properties = request.getConnectorProperties();
  264.         if(connectorPropertiesRequired){
  265.             if(this.properties == null)
  266.                 this.errore = "Proprieta' del connettore non definite";
  267.             else if(this.properties.size() == 0)
  268.                 this.errore = "Proprieta' del connettore non definite";
  269.         }
  270.        
  271.         // tipoConnetore
  272.         this.tipoConnettore = request.getTipoConnettore();
  273.        
  274.         // generateErrorWithConnectorPrefix
  275.         this.generateErrorWithConnectorPrefix = request.isGenerateErrorWithConnectorPrefix();
  276.        
  277.         // - Busta
  278.         this.busta = request.getBusta();
  279.         if(this.busta!=null)
  280.             this.idMessaggio=this.busta.getID();
  281.        
  282.         // - Debug mode
  283.         if(this.properties!=null && this.properties.get(CostantiConnettori.CONNETTORE_DEBUG)!=null){
  284.             if("true".equalsIgnoreCase(this.properties.get(CostantiConnettori.CONNETTORE_DEBUG).trim()))
  285.                 this.debug = true;
  286.         }
  287.    
  288.         // Logger
  289.         this.logger = new ConnettoreLogger(this.debug, this.idMessaggio, this.getPddContext());
  290.        
  291.         // MessageConfiguration
  292.         if(this.getPddContext()!=null && this.getPddContext().containsKey(org.openspcoop2.core.constants.Costanti.REQUEST_INFO)){
  293.             this.requestInfo = (RequestInfo) this.getPddContext().getObject(org.openspcoop2.core.constants.Costanti.REQUEST_INFO);
  294.         }
  295.        
  296.         // State
  297.         this.state = request.getState();
  298.        
  299.         // Raccolta altri parametri
  300.         try{
  301.             this.requestMsg =  request.getRequestMessage(this.requestInfo, this.getPddContext());
  302.         }catch(Exception e){
  303.             this.eccezioneProcessamento = e;
  304.             this.logger.error("Errore durante la lettura del messaggio da consegnare: "+this.readExceptionMessageFromException(e),e);
  305.             this.errore = "Errore durante la lettura del messaggio da consegnare: "+this.readExceptionMessageFromException(e);
  306.             return false;
  307.         }
  308.         if(this.requestMsg==null){
  309.             this.errore = "Messaggio da consegnare is Null (Msg)";
  310.             return false;
  311.         }
  312.         if(ServiceBinding.SOAP.equals(this.requestMsg.getServiceBinding())){
  313.             this.isSoap = true;
  314.         }
  315.         else{
  316.             this.isRest = true;
  317.         }
  318.         this.sbustamentoSoap = request.isSbustamentoSOAP();
  319.         this.propertiesTrasporto = request.getPropertiesTrasporto();
  320.         this.propertiesUrlBased = request.getPropertiesUrlBased();

  321.         // Credenziali
  322.         //this.tipoAutenticazione = request.getAutenticazione();
  323.         this.credenziali = request.getCredenziali();

  324.         // Identificativo modulo
  325.         this.idModulo = request.getIdModulo();
  326.        
  327.         // PolicyConfig
  328.         this.policyTimeoutConfig = request.getPolicyTimeoutConfig();
  329.                
  330.         // Context per invocazioni handler
  331.         this.outRequestContext = request.getOutRequestContext();
  332.         this.msgDiagnostico = request.getMsgDiagnostico();

  333.         // Limit
  334.         if(this.getPddContext()!=null && this.getPddContext().containsKey(org.openspcoop2.core.constants.Costanti.LIMITED_STREAM)){
  335.             Object o = this.getPddContext().getObject(org.openspcoop2.core.constants.Costanti.LIMITED_STREAM);
  336.             if(o!=null && o instanceof SogliaDimensioneMessaggio) {
  337.                 try {
  338.                     SogliaDimensioneMessaggio soglia = (SogliaDimensioneMessaggio) o;
  339.                     if(soglia!=null && soglia.getSogliaKb()>0) {
  340.                         this.useLimitedInputStream = true;
  341.                         this.limitBytes = soglia;
  342.                     }
  343.                 }catch(Throwable t) {
  344.                     // ignore
  345.                 }
  346.             }
  347.         }
  348.        
  349.         // Timeout, Dump
  350.         this.useTimeoutInputStream = this.openspcoopProperties.isConnettoriUseTimeoutInputStream();
  351.         boolean dumpBinario = this.debug;
  352.         DumpConfigurazione dumpConfigurazione = null;
  353.         String protocol = this.getProtocolFactory()!=null ? this.getProtocolFactory().getProtocol() : null;
  354.         IDSoggetto dominio = this.requestInfo!=null ? this.requestInfo.getIdentitaPdD() : this.openspcoopProperties.getIdentitaPortaDefault(protocol, this.requestInfo);
  355.         String nomePorta = (this.requestInfo!=null && this.requestInfo.getProtocolContext()!=null) ? this.requestInfo.getProtocolContext().getInterfaceName() : null;
  356.         if(this.policyTimeoutConfig!=null) {
  357.             // entro qua tramite la gestione dei token di validazione, negoziazione e attribute authority
  358.             try {
  359.                 ConfigurazionePdDManager configurazionePdDManager = ConfigurazionePdDManager.getInstance();
  360.                 if(this.pa!=null) {
  361.                     this.useTimeoutInputStream = configurazionePdDManager.isConnettoriUseTimeoutInputStream(this.pa);
  362.                     this.proprietaPorta = this.pa.getProprietaList();
  363.                 }
  364.                 else if(this.pd!=null) {
  365.                     this.useTimeoutInputStream = configurazionePdDManager.isConnettoriUseTimeoutInputStream(this.pd);
  366.                     this.proprietaPorta = this.pd.getProprietaList();
  367.                 }
  368.             }catch(Exception e){
  369.                 this.eccezioneProcessamento = e;
  370.                 this.logger.error("Errore durante l'inizializzazione della configurazione di timeout: "+this.readExceptionMessageFromException(e),e);
  371.                 this.errore = "Errore durante l'inizializzazione della configurazione di timeout: "+this.readExceptionMessageFromException(e);
  372.                 return false;
  373.             }
  374.         }
  375.         else if(this.idModulo!=null) {
  376.             try {
  377.                 // Soglia Dump
  378.                 this.dumpBinario_soglia = this.openspcoopProperties.getDumpBinarioInMemoryThreshold();
  379.                 this.dumpBinario_repositoryFile = this.openspcoopProperties.getDumpBinarioRepository();
  380.                
  381.                 ConfigurazionePdDManager configurazionePdDManager = ConfigurazionePdDManager.getInstance();
  382.                 if(ConsegnaContenutiApplicativi.ID_MODULO.equals(this.idModulo)){
  383.                    
  384.                     IDPortaApplicativa idPA = null;
  385.                     if(request.getIdPortaApplicativa()!=null) {
  386.                         idPA = request.getIdPortaApplicativa();
  387.                     }
  388.                     else if(nomePorta!=null) {
  389.                         idPA = new IDPortaApplicativa();
  390.                         idPA.setNome(nomePorta);
  391.                     }
  392.                    
  393.                     ConfigurazioneTracciamento configurazioneTracciamento = new ConfigurazioneTracciamento(this.logger.getLogger(), configurazionePdDManager, TipoPdD.APPLICATIVA);
  394.                     this.logFileTrace_headers = configurazioneTracciamento.isTransazioniFileTraceDumpBinarioConnettoreHeaderEnabled();
  395.                     this.logFileTrace_payload = configurazioneTracciamento.isTransazioniFileTraceDumpBinarioConnettorePayloadEnabled();
  396.                    
  397.                     if(idPA!=null) {
  398.                         this.pa = configurazionePdDManager.getPortaApplicativaSafeMethod(idPA, this.requestInfo);
  399.                         if(this.pa!=null) {
  400.                             this.useTimeoutInputStream = configurazionePdDManager.isConnettoriUseTimeoutInputStream(this.pa);
  401.                             dumpConfigurazione = configurazionePdDManager.getDumpConfigurazione(this.pa);
  402.                             configurazioneTracciamento = new ConfigurazioneTracciamento(this.logger.getLogger(), configurazionePdDManager, this.pa);
  403.                             this.logFileTrace_headers = configurazioneTracciamento.isTransazioniFileTraceDumpBinarioConnettoreHeaderEnabled();
  404.                             this.logFileTrace_payload = configurazioneTracciamento.isTransazioniFileTraceDumpBinarioConnettorePayloadEnabled();
  405.                             this.proprietaPorta = this.pa.getProprietaList();
  406.                             if(request.getTransazioneApplicativoServer()!=null) {
  407.                                 this.nomeConnettoreAsincrono = request.getTransazioneApplicativoServer().getConnettoreNome();
  408.                             }
  409.                         }
  410.                     }
  411.                    
  412.                 }
  413.                 else {
  414.                    
  415.                     IDPortaDelegata idPD = null;
  416.                     if(nomePorta!=null) {
  417.                         idPD = new IDPortaDelegata();
  418.                         idPD.setNome(nomePorta);
  419.                     }
  420.                    
  421.                     ConfigurazioneTracciamento configurazioneTracciamento = new ConfigurazioneTracciamento(this.logger.getLogger(), configurazionePdDManager, TipoPdD.DELEGATA);
  422.                     this.logFileTrace_headers = configurazioneTracciamento.isTransazioniFileTraceDumpBinarioConnettoreHeaderEnabled();
  423.                     this.logFileTrace_payload = configurazioneTracciamento.isTransazioniFileTraceDumpBinarioConnettorePayloadEnabled();
  424.                    
  425.                     if(idPD!=null) {
  426.                         this.pd = configurazionePdDManager.getPortaDelegataSafeMethod(idPD, this.requestInfo);
  427.                         if(this.pd!=null) {
  428.                             this.useTimeoutInputStream = configurazionePdDManager.isConnettoriUseTimeoutInputStream(this.pd);
  429.                             dumpConfigurazione = configurazionePdDManager.getDumpConfigurazione(this.pd);
  430.                             configurazioneTracciamento = new ConfigurazioneTracciamento(this.logger.getLogger(), configurazionePdDManager, this.pd);
  431.                             this.logFileTrace_headers = configurazioneTracciamento.isTransazioniFileTraceDumpBinarioConnettoreHeaderEnabled();
  432.                             this.logFileTrace_payload = configurazioneTracciamento.isTransazioniFileTraceDumpBinarioConnettorePayloadEnabled();
  433.                             this.proprietaPorta = this.pd.getProprietaList();
  434.                         }
  435.                     }
  436.                    
  437.                 }
  438.            
  439.                 if(request.getTransazioneApplicativoServer()!=null) {
  440.                     this.logFileTrace_headers = false;
  441.                     this.logFileTrace_payload = false;
  442.                 }
  443.                
  444.                 this.dumpRaw = new DumpRaw(this.logger,dominio,this.idModulo,this.outRequestContext.getTipoPorta(),
  445.                         dumpBinario,
  446.                         dumpConfigurazione,
  447.                         this.logFileTrace_headers, this.logFileTrace_payload);
  448.                 if(this.dumpRaw.isActiveDumpDatabase()) {
  449.                     if(request.getTransazioneApplicativoServer()!=null) {
  450.                         this.dumpRaw.initDump(nomePorta, this.outRequestContext.getPddContext(),
  451.                                 request.getTransazioneApplicativoServer(),
  452.                                 request.getIdPortaApplicativa(), request.getDataConsegnaTransazioneApplicativoServer());
  453.                     }
  454.                     else {
  455.                         this.dumpRaw.initDump(nomePorta, this.outRequestContext.getPddContext());
  456.                     }
  457.                 }
  458.             }catch(Exception e){
  459.                 this.eccezioneProcessamento = e;
  460.                 this.logger.error("Errore durante l'inizializzazione del dump binario: "+this.readExceptionMessageFromException(e),e);
  461.                 this.errore = "Errore durante l'inizializzazione del dump binario: "+this.readExceptionMessageFromException(e);
  462.                 return false;
  463.             }
  464.         }
  465.        
  466.         // Diagnostic Input Stream
  467.         if(this.idModulo!=null && this.msgDiagnostico!=null) {
  468.             if(ConsegnaContenutiApplicativi.ID_MODULO.equals(this.idModulo)){
  469.                 this.useDiagnosticInputStream = this.openspcoopProperties.isConnettoriUseDiagnosticInputStream_consegnaContenutiApplicativi();
  470.             }
  471.             else {
  472.                 this.useDiagnosticInputStream = this.openspcoopProperties.isConnettoriUseDiagnosticInputStream_inoltroBuste();
  473.             }
  474.         }
  475.        
  476.        
  477.         // IdTransazione
  478.         if(this.getPddContext()!=null) {
  479.             Object oIdTransazione = this.getPddContext().getObject(Costanti.ID_TRANSAZIONE);
  480.             if(oIdTransazione!=null && (oIdTransazione instanceof String)){
  481.                 this.idTransazione = (String) oIdTransazione;
  482.             }
  483.         }
  484.        
  485.         // Cache Response
  486.         this.responseCachingConfig = responseCachingConfig;
  487.         if(this.responseCachingConfig!=null && StatoFunzionalita.ABILITATO.equals(this.responseCachingConfig.getStato())) {
  488.             if(this.requestMsg!=null) {
  489.                 Object digestO = this.requestMsg.getContextProperty(CostantiPdD.RESPONSE_CACHE_REQUEST_DIGEST);
  490.                 if(digestO!=null) {
  491.                    
  492.                     Transaction transactionNullable = null;
  493.                     try{
  494.                         if(this.idTransazione!=null) {
  495.                             transactionNullable = TransactionContext.getTransaction(this.idTransazione);
  496.                         }
  497.                     }catch(Throwable e){
  498.                         // La transazione potrebbe essere stata eliminata nelle comunicazioni stateful
  499.                     }
  500.                    
  501.                     if(transactionNullable!=null) {
  502.                         transactionNullable.getTempiElaborazione().startResponseCachingReadFromCache();
  503.                     }
  504.                    
  505.                     this.responseCachingDigest = (String) digestO;
  506.                     try{
  507.                         ResponseCached responseCached =  GestoreCacheResponseCaching.getInstance().readByDigest(this.responseCachingDigest);
  508.                         if(responseCached!=null) {
  509.                        
  510.                             // esiste una risposta cachata, verifico eventuali direttive
  511.                             ResponseCachingConfigurazioneControl cacheControl = this.responseCachingConfig.getControl();
  512.                             if(cacheControl==null) {
  513.                                 cacheControl = new ResponseCachingConfigurazioneControl(); // uso i valori di default
  514.                             }
  515.                             if(cacheControl!=null) {
  516.                        
  517.                                 Map<String, List<String>> trasportoRichiesta = null;
  518.                                 if(this.requestMsg!=null && this.requestMsg.getTransportRequestContext()!=null &&
  519.                                         this.requestMsg.getTransportRequestContext().getHeaders()!=null) {
  520.                                     trasportoRichiesta = this.requestMsg.getTransportRequestContext().getHeaders();
  521.                                 }
  522.                                
  523.                                 if(cacheControl.isNoCache()) {
  524.                                     if(HttpUtilities.isDirectiveNoCache(trasportoRichiesta)) {
  525.                                         GestoreCacheResponseCaching.getInstance().removeByUUID(responseCached.getUuid());
  526.                                         responseCached = null;
  527.                                     }
  528.                                 }
  529.                                
  530.                                 if(responseCached!=null) {
  531.                                     if(cacheControl.isMaxAge()) {
  532.                                         Integer maxAge = HttpUtilities.getDirectiveCacheMaxAge(trasportoRichiesta);
  533.                                         if(maxAge!=null && maxAge.intValue()>0) {
  534.                                             if(responseCached.getAgeInSeconds() > maxAge.intValue()) {
  535.                                                 GestoreCacheResponseCaching.getInstance().removeByUUID(responseCached.getUuid());
  536.                                                 responseCached = null;
  537.                                             }
  538.                                         }
  539.                                     }
  540.                                 }
  541.                                    
  542.                             }
  543.                            
  544.                             if(responseCached!=null) {
  545.                            
  546.                                 OpenSPCoop2Message msgResponse = responseCached.toOpenSPCoop2Message(
  547.                                         org.openspcoop2.pdd.core.Utilities.getOpenspcoop2MessageFactory(this.logger.getLogger(), this.requestMsg, this.requestInfo, MessageRole.RESPONSE),
  548.                                         this.openspcoopProperties.getAttachmentsProcessingMode(),
  549.                                         this.openspcoopProperties.getCachingResponseHeaderCacheKey());
  550.                                                        
  551.                                 this.responseMsg = msgResponse;
  552.                                
  553.                                 this.dataAccettazioneRisposta = DateManager.getDate();
  554.                                
  555.                                 org.openspcoop2.utils.transport.TransportResponseContext transportResponseContenxt = msgResponse.getTransportResponseContext();
  556.                                
  557.                                 if(transportResponseContenxt!=null && transportResponseContenxt.getCodiceTrasporto()!=null){
  558.                                     try {
  559.                                         this.codice = Integer.parseInt(transportResponseContenxt.getCodiceTrasporto());
  560.                                     }catch(Exception e) {
  561.                                         this.logger.error("Errore durante la conversione del codice di trasporto ["+transportResponseContenxt.getCodiceTrasporto()+"]");
  562.                                         this.codice = 200;
  563.                                     }
  564.                                 }
  565.                                 else {
  566.                                     this.codice = 200;
  567.                                 }
  568.                                
  569.                                 if(transportResponseContenxt!=null) {
  570.                                     this.propertiesTrasportoRisposta = transportResponseContenxt.getHeaders();
  571.                                 }
  572.                                
  573.                                 this.contentLength = responseCached.getMessageLength();
  574.                                
  575.                                 if(this.getPddContext()!=null) {
  576.                                     this.getPddContext().addObject(RESPONSE_FROM_CACHE, true);
  577.                                 }
  578.                                
  579.                                 this.location = LOCATION_CACHED;
  580.                                
  581.                                
  582.                                 this.responseAlready = true;
  583.                                
  584.                             }
  585.                         }
  586.                     }catch(Exception e){
  587.                         this.eccezioneProcessamento = e;
  588.                         this.logger.error("Errore durante la lettura della cache delle risposte: "+this.readExceptionMessageFromException(e),e);
  589.                         this.errore = "Errore durante la lettura della cache delle risposte: "+this.readExceptionMessageFromException(e);
  590.                         return false;
  591.                     }finally {
  592.                         if(transactionNullable!=null) {
  593.                             transactionNullable.getTempiElaborazione().endResponseCachingReadFromCache();
  594.                         }
  595.                     }
  596.                 }
  597.             }
  598.         }

  599.         // Negoziazione Token
  600.         this.policyNegoziazioneToken = request.getPolicyNegoziazioneToken();
  601.                
  602.         // API
  603.         this.idAccordo = request.getIdAccordo();
  604.        
  605.         return true;
  606.     }
  607.    
  608.     private static final String format = "yyyy-MM-dd HH:mm:ss.SSS";
  609.     protected NameValue getTokenHeader() throws ConnettoreException {
  610.         return this.getTokenParameter(true);
  611.     }
  612.     protected NameValue getTokenQueryParameter() throws ConnettoreException {
  613.         return this.getTokenParameter(false);
  614.     }
  615.     private ModIValidazioneSemanticaProfiloSicurezza modIValidazioneSemanticaProfiloSicurezza;
  616.     public void setModIValidazioneSemanticaProfiloSicurezza(
  617.             ModIValidazioneSemanticaProfiloSicurezza modIValidazioneSemanticaProfiloSicurezza) {
  618.         this.modIValidazioneSemanticaProfiloSicurezza = modIValidazioneSemanticaProfiloSicurezza;
  619.     }
  620.     private NameValue getTokenParameter(boolean header) throws ConnettoreException {
  621.         if(this.policyNegoziazioneToken!=null) {
  622.             try {
  623.                 GestoreToken.validazioneConfigurazione(this.policyNegoziazioneToken); // assicura che la configurazione sia corretta
  624.                
  625.                 String forwardMode = this.policyNegoziazioneToken.getForwardTokenMode();
  626.                 NameValue n = null;
  627.                 if(org.openspcoop2.pdd.core.token.Costanti.POLICY_RETRIEVE_TOKEN_FORWARD_MODE_RFC6750_HEADER.equals(forwardMode)) {
  628.                     if(header) {
  629.                         n = new NameValue();
  630.                         n.setName(HttpConstants.AUTHORIZATION);
  631.                         n.setValue(HttpConstants.AUTHORIZATION_PREFIX_BEARER);
  632.                     }
  633.                     else {
  634.                         return null;
  635.                     }
  636.                 }
  637.                 else if(org.openspcoop2.pdd.core.token.Costanti.POLICY_TOKEN_FORWARD_TRASPARENTE_MODE_RFC6750_URL.equals(forwardMode)) {
  638.                     if(!header) {
  639.                         n = new NameValue();
  640.                         n.setName(org.openspcoop2.pdd.core.token.Costanti.RFC6750_URI_QUERY_PARAMETER_ACCESS_TOKEN);
  641.                     }
  642.                     else {
  643.                         return null;
  644.                     }
  645.                 }
  646.                 else if(org.openspcoop2.pdd.core.token.Costanti.POLICY_TOKEN_FORWARD_TRASPARENTE_MODE_CUSTOM_HEADER.equals(forwardMode)) {
  647.                     if(header) {
  648.                         n = new NameValue();
  649.                         n.setName(this.policyNegoziazioneToken.getForwardTokenModeCustomHeader());
  650.                     }
  651.                     else {
  652.                         return null;
  653.                     }
  654.                 }
  655.                 else if(org.openspcoop2.pdd.core.token.Costanti.POLICY_TOKEN_FORWARD_TRASPARENTE_MODE_CUSTOM_URL.equals(forwardMode)) {
  656.                     if(!header) {
  657.                         n = new NameValue();
  658.                         n.setName(this.policyNegoziazioneToken.getForwardTokenModeCustomUrl());
  659.                     }
  660.                     else {
  661.                         return null;
  662.                     }
  663.                 }
  664.                
  665.                 if(this.debug) {
  666.                     this.logger.debug("Negoziazione token '"+this.policyNegoziazioneToken.getName()+"' ...");
  667.                 }
  668.                 if(this.msgDiagnostico!=null) {
  669.                     try {
  670.                         this.msgDiagnostico.logPersonalizzato("negoziazioneToken.inCorso");
  671.                     }catch(Throwable t) {
  672.                         this.logger.error("Emissione diagnostica 'negoziazioneToken.inCorso' fallita: "+t.getMessage(),t);
  673.                     }
  674.                 }
  675.                 EsitoNegoziazioneToken esitoNegoziazione = GestoreToken.endpointToken(this.debug, this.logger.getLogger(), this.policyNegoziazioneToken,
  676.                         this.busta, this.requestInfo,
  677.                         ConsegnaContenutiApplicativi.ID_MODULO.equals(this.idModulo) ? TipoPdD.APPLICATIVA : TipoPdD.DELEGATA, this.idModulo, this.pa, this.pd,
  678.                         this.getPddContext(), this.getProtocolFactory());
  679.                 if(this.debug) {
  680.                     this.logger.debug("Negoziazione token '"+this.policyNegoziazioneToken.getName()+"' terminata");
  681.                 }
  682.                
  683.                 SimpleDateFormat sdf = DateUtils.getDefaultDateTimeFormatter(format);
  684.                                
  685.                 if(esitoNegoziazione==null) {
  686.                     throw new Exception("Esito Negoziazione non ritornato ?");
  687.                 }
  688.                 if(!esitoNegoziazione.isValido()) {
  689.                     throw new Exception(esitoNegoziazione.getDetails(),esitoNegoziazione.getEccezioneProcessamento());
  690.                 }
  691.                 if(esitoNegoziazione.isInCache()) {
  692.                     if(esitoNegoziazione.getInformazioniNegoziazioneToken().getExpiresIn()!=null) {
  693.                         this.logger.debug("Presente in cache access_token '"+esitoNegoziazione.getToken()+"'; expire in ("+sdf.format(esitoNegoziazione.getInformazioniNegoziazioneToken().getExpiresIn())+")");
  694.                     }
  695.                     else {
  696.                         this.logger.debug("Presente in cache access_token '"+esitoNegoziazione.getToken()+"'; no expire");
  697.                     }
  698.                     if(this.msgDiagnostico!=null) {
  699.                         try {
  700.                             this.msgDiagnostico.logPersonalizzato("negoziazioneToken.inCache");
  701.                         }catch(Exception t) {
  702.                             this.logger.error("Emissione diagnostica 'negoziazioneToken.inCache' fallita: "+t.getMessage(),t);
  703.                         }
  704.                     }
  705.                 }
  706.                 else {
  707.                     if(esitoNegoziazione.getInformazioniNegoziazioneToken().getExpiresIn()!=null) {
  708.                         this.logger.debug("Recuperato access_token '"+esitoNegoziazione.getToken()+"'; expire in ("+sdf.format(esitoNegoziazione.getInformazioniNegoziazioneToken().getExpiresIn())+")");
  709.                     }
  710.                     else {
  711.                         this.logger.debug("Recuperato access_token '"+esitoNegoziazione.getToken()+"'; no expire");
  712.                     }
  713.                     if(this.msgDiagnostico!=null) {
  714.                         try {
  715.                             this.msgDiagnostico.logPersonalizzato("negoziazioneToken.completata");
  716.                         }catch(Exception t) {
  717.                             this.logger.error("Emissione diagnostica 'negoziazioneToken.completata' fallita: "+t.getMessage(),t);
  718.                         }
  719.                     }
  720.                 }
  721.                
  722.                 if(this.modIValidazioneSemanticaProfiloSicurezza!=null) {
  723.                     String jti = ModIUtils.readJti(esitoNegoziazione.getToken(), this.logger.getLogger());
  724.                     if(jti!=null && StringUtils.isNotEmpty(jti)) {
  725.                         ModIUtils.replaceBustaIdWithJtiTokenId(this.modIValidazioneSemanticaProfiloSicurezza, jti);
  726.                         if(this.msgDiagnostico!=null) {
  727.                             this.msgDiagnostico.updateKeywordIdMessaggioRichiesta(this.busta.getID());
  728.                         }
  729.                         if(this.getPddContext()!=null) {
  730.                             this.getPddContext().put(org.openspcoop2.core.constants.Costanti.MODI_JTI_REQUEST_ID, jti);
  731.                         }
  732.                     }
  733.                    
  734.                     if(this.msgDiagnostico!=null) {
  735.                         try {
  736.                             this.msgDiagnostico.logPersonalizzato("inoltroInCorso");
  737.                         }catch(Exception t) {
  738.                             this.logger.error("Emissione diagnostica 'inoltroInCorso' fallita: "+t.getMessage(),t);
  739.                         }
  740.                     }
  741.                 }
  742.                
  743.                 if(n.getValue()!=null) {
  744.                     n.setValue(n.getValue()+esitoNegoziazione.getToken());
  745.                 }
  746.                 else {
  747.                     n.setValue(esitoNegoziazione.getToken());
  748.                 }
  749.                 return n;

  750.             }catch(Exception e) {
  751.                 if(this.getPddContext()!=null) {
  752.                     this.getPddContext().addObject(org.openspcoop2.core.constants.Costanti.ERRORE_NEGOZIAZIONE_TOKEN, "true");
  753.                 }
  754.                 throw new ConnettoreException(e.getMessage(),e);
  755.             }
  756.         }
  757.        
  758.         return null;
  759.     }
  760.    
  761.     private void saveResponseInCache() {
  762.        
  763.         Transaction transactionNullable = null;
  764.         try{
  765.             if(this.getPddContext()!=null) {
  766.                 Object oIdTransazione = this.getPddContext().getObject(Costanti.ID_TRANSAZIONE);
  767.                 String idTransazione = null;
  768.                 if(oIdTransazione!=null && (oIdTransazione instanceof String)){
  769.                     idTransazione = (String) oIdTransazione;
  770.                 }
  771.                 transactionNullable = TransactionContext.getTransaction(idTransazione);
  772.             }
  773.         }catch(Throwable e){
  774.             // La transazione potrebbe essere stata eliminata nelle comunicazioni stateful
  775.         }
  776.        
  777.         if(transactionNullable!=null) {
  778.             transactionNullable.getTempiElaborazione().startResponseCachingSaveInCache();
  779.         }
  780.        
  781.         try {
  782.             if(this.responseCachingConfig!=null && StatoFunzionalita.ABILITATO.equals(this.responseCachingConfig.getStato()) &&
  783.                     this.responseMsg!=null) { // jms, null ha la response null
  784.                
  785.                 boolean saveInCache = true;
  786.                
  787.                 int cacheTimeoutSeconds = this.responseCachingConfig.getCacheTimeoutSeconds().intValue();
  788.                
  789.                 Long kbMax = this.responseCachingConfig.getMaxMessageSize();
  790.                 long byteMax = -1;
  791.                 if(kbMax!=null) {
  792.                     byteMax = kbMax.longValue() * 1024;
  793.                 }
  794.                
  795.                 Map<String, List<String>> trasportoRichiesta = null;
  796.                 if(this.requestMsg!=null && this.requestMsg.getTransportRequestContext()!=null &&
  797.                         this.requestMsg.getTransportRequestContext().getHeaders()!=null) {
  798.                     trasportoRichiesta = this.requestMsg.getTransportRequestContext().getHeaders();
  799.                 }
  800.                
  801.                 ResponseCachingConfigurazioneControl cacheControl = this.responseCachingConfig.getControl();
  802.                 if(cacheControl==null) {
  803.                     cacheControl = new ResponseCachingConfigurazioneControl(); // uso i valori di default
  804.                 }
  805.                 if(cacheControl!=null) {
  806.                     if(cacheControl.isNoStore()) {
  807.                         if(HttpUtilities.isDirectiveNoStore(trasportoRichiesta)) {
  808.                             saveInCache = false;
  809.                         }
  810.                     }
  811.                 }
  812.                
  813.                 if(saveInCache) {
  814.                     if(this.responseCachingConfig.sizeRegolaList()>0) {
  815.                        
  816.                         int returnCode = -1;
  817.                         try {
  818.                             if(this.responseMsg.getTransportResponseContext()!=null && this.responseMsg.getTransportResponseContext().getCodiceTrasporto()!=null) {
  819.                                 returnCode = Integer.parseInt(this.responseMsg.getTransportResponseContext().getCodiceTrasporto());
  820.                             }
  821.                         }catch(Exception e) {}
  822.                        
  823.                         boolean isFault = this.responseMsg.isFault();
  824.                        
  825.                         ResponseCachingConfigurazioneRegola regolaGeneraleIncludeFault = null;
  826.                        
  827.                         saveInCache = false; // se ci sono delle regole, salvo solamente se la regola ha un match
  828.                         for (ResponseCachingConfigurazioneRegola regola : this.responseCachingConfig.getRegolaList()) {
  829.                            
  830.                             if(returnCode>0 && regola.getReturnCodeMin()!=null) {
  831.                                 if(returnCode<regola.getReturnCodeMin().intValue()) {
  832.                                     continue;
  833.                                 }
  834.                             }
  835.                             if(returnCode>0 && regola.getReturnCodeMax()!=null) {
  836.                                 if(returnCode>regola.getReturnCodeMax().intValue()) {
  837.                                     continue;
  838.                                 }
  839.                             }
  840.                            
  841.                             if(isFault && !regola.isFault()) {
  842.                                 continue;
  843.                             }
  844.                             else if(!isFault && regola.isFault()) {
  845.                                 // in questo caso la regola va bene poichè l'istruzione fault indica semplicemente se includere o meno un fault
  846.                                 // e quindi essendo il messaggio non un fault la regola match.
  847.                                 // Però prima di usarla verifico se esiste una regola specifica senza fault
  848.                                 if(regolaGeneraleIncludeFault==null) {
  849.                                     regolaGeneraleIncludeFault = regola;
  850.                                 }
  851.                                 continue;
  852.                             }
  853.                            
  854.                             // ho un match
  855.                             saveInCache = true;
  856.                             if(regola.getCacheTimeoutSeconds()!=null) {
  857.                                 cacheTimeoutSeconds = regola.getCacheTimeoutSeconds().intValue();
  858.                             }
  859.                             break;
  860.                         }
  861.                        
  862.                         if(!saveInCache && regolaGeneraleIncludeFault!=null) {
  863.                             // ho il match di un messaggio che non è un fault con una regola che fa includere anche i fault
  864.                             saveInCache = true;
  865.                             if(regolaGeneraleIncludeFault.getCacheTimeoutSeconds()!=null) {
  866.                                 cacheTimeoutSeconds = regolaGeneraleIncludeFault.getCacheTimeoutSeconds().intValue();
  867.                             }
  868.                         }
  869.                     }
  870.                 }
  871.                
  872.                 if(saveInCache) {              
  873.                     if(kbMax!=null) {
  874.                         if(this.contentLength>0) {
  875.                             if(this.contentLength>byteMax) {
  876.                                 this.logger.debug("Messaggio non salvato in cache, nonostante la configurazione lo richiesta poichè la sua dimensione ("+this.contentLength+
  877.                                         " bytes) supera la dimensione massima consentita ("+byteMax+" bytes)");
  878.                                 saveInCache = false;
  879.                             }
  880.                         }
  881.                     }
  882.                 }
  883.                
  884.                 if(saveInCache) {
  885.                     ResponseCached responseCached = ResponseCached.toResponseCached(this.responseMsg, cacheTimeoutSeconds);
  886.                     if(kbMax!=null && this.contentLength<=0) {
  887.                         // ricontrollo poichè non era disponibile l'informazione
  888.                         if(responseCached.getMessageLength()>byteMax) {
  889.                             this.logger.debug("Messaggio non salvato in cache, nonostante la configurazione lo richiesta poichè la sua dimensione ("+responseCached.getMessageLength()+
  890.                                     " bytes) supera la dimensione massima consentita ("+byteMax+" bytes)");
  891.                             saveInCache = false;
  892.                         }
  893.                     }
  894.                     if(saveInCache) {
  895.                         GestoreCacheResponseCaching.getInstance().save(this.responseCachingDigest, responseCached);
  896.                     }
  897.                 }
  898.             }
  899.         }catch(Throwable e){
  900.             this.logger.error("Errore durante il salvataggio nella cache delle risposte: "+this.readExceptionMessageFromException(e),e);
  901.         }finally {
  902.             if(transactionNullable!=null) {
  903.                 transactionNullable.getTempiElaborazione().endResponseCachingSaveInCache();
  904.             }
  905.         }
  906.     }
  907.    
  908.     protected abstract boolean initializePreSend(ResponseCachingConfigurazione responseCachingConfig, ConnettoreMsg request);
  909.    
  910.     protected abstract boolean send(ConnettoreMsg request);
  911.    
  912.     @Override
  913.     public boolean send(ResponseCachingConfigurazione responseCachingConfig, ConnettoreMsg request){
  914.        
  915.         if(this.initializePreSend(responseCachingConfig, request)==false){
  916.             return false;
  917.         }
  918.        
  919.         // caching response
  920.         if(this.responseAlready) {
  921.             return true;
  922.         }
  923.        
  924.         boolean returnEsitoSend = send(request);
  925.         if(returnEsitoSend) {
  926.             saveResponseInCache();
  927.         }
  928.         return returnEsitoSend;
  929.     }
  930.    
  931.     /**
  932.      * In caso di avvenuto errore in fase di consegna, questo metodo ritorna il motivo dell'errore.
  933.      *
  934.      * @return motivo dell'errore (se avvenuto in fase di consegna).
  935.      *
  936.      */
  937.     @Override
  938.     public String getErrore(){
  939.         return this.errore;
  940.     }

  941.     /**
  942.      * In caso di avvenuta consegna, questo metodo ritorna il codice di trasporto della consegna.
  943.      *
  944.      * @return se avvenuta una consegna ritorna il codice di trasporto della consegna.
  945.      *
  946.      */
  947.     @Override
  948.     public int getCodiceTrasporto(){
  949.         return this.codice;
  950.     }

  951.     /**
  952.      * In caso di avvenuta consegna, questo metodo ritorna l'header del trasporto
  953.      *
  954.      * @return se avvenuta una consegna ritorna l'header del trasporto
  955.      *
  956.      */
  957.     @Override
  958.     public Map<String, List<String>> getHeaderTrasporto(){
  959.         if(this.propertiesTrasportoRisposta.size()<=0){
  960.             return null;
  961.         }else{
  962.             return this.propertiesTrasportoRisposta;
  963.         }
  964.     }
  965.    
  966.     /**
  967.      * Ritorna la risposta pervenuta in seguita alla consegna effettuata
  968.      *
  969.      * @return la risposta.
  970.      *
  971.      */
  972.     @Override
  973.     public OpenSPCoop2Message getResponse(){
  974.         if(this.responseMsg!=null) {
  975.             if(this.getProtocolFactory()!=null) {
  976.                 this.responseMsg.setProtocolName(this.getProtocolFactory().getProtocol());
  977.             }
  978.             if(this.getPddContext()!=null) {
  979.                 this.responseMsg.setTransactionId(PdDContext.getValue(org.openspcoop2.core.constants.Costanti.ID_TRANSAZIONE, this.getPddContext()));
  980.             }
  981.         }
  982.         return this.responseMsg;
  983.     }

  984.     /**
  985.      * In caso di avvenuta consegna, questo metodo ritorna, se disponibile, la dimensione della risposta (-1 se non disponibile)
  986.      *
  987.      * @return se avvenuta una consegna,  questo metodo ritorna, se disponibile, la dimensione della risposta (-1 se non disponibile)
  988.      *
  989.      */
  990.     @Override
  991.     public long getContentLength() {
  992.         return this.contentLength;
  993.     }
  994.    
  995.     /**
  996.      * Ritorna l'informazione su dove il connettore sta spedendo il messaggio
  997.      *
  998.      * @return location di inoltro del messaggio
  999.      */
  1000.     @Override
  1001.     public String getLocation() throws ConnettoreException{
  1002.         return this.location;
  1003.     }
  1004.    
  1005.     /**
  1006.      * Ritorna l'eccezione in caso di errore di processamento
  1007.      *
  1008.      * @return eccezione in caso di errore di processamento
  1009.      */
  1010.     @Override
  1011.     public Exception getEccezioneProcessamento(){
  1012.         return this.eccezioneProcessamento;
  1013.     }
  1014.    
  1015.     /**
  1016.      * Effettua la disconnessione
  1017.      */
  1018.     @Override
  1019.     public void disconnect() throws ConnettoreException{
  1020.        
  1021.         try{
  1022.        
  1023.             // Rilascio eventuali risorse associate al messaggio di risposte
  1024.             // Tali risorse non sono ancora rilasciate, se durante il flusso e' stato generato un nuovo messaggio.
  1025.             // Due chiamate della close non provocano problemi, la seconda non comporta nessun effetto essendo lo stream 'NotifierInputStream' gia' chiuso
  1026.             if(this.responseMsg!=null && this.responseMsg.getNotifierInputStream()!=null){
  1027.                 this.responseMsg.getNotifierInputStream().close();
  1028.             }
  1029.            
  1030.         }catch(Exception e){
  1031.             throw new ConnettoreException("Chiusura connessione non riuscita: "+e.getMessage(),e);
  1032.         }
  1033.        
  1034.     }
  1035.    
  1036.     /**
  1037.      * Data di creazione del connettore
  1038.      */
  1039.     @Override
  1040.     public Date getCreationDate() throws ConnettoreException{
  1041.         return this.creationDate;
  1042.     }
  1043.    
  1044.    
  1045.     /**
  1046.      * Ritorna le opzioni di NotifierInputStreamParams per la risposta
  1047.      *
  1048.      * @return NotifierInputStreamParams
  1049.      * @throws ConnettoreException
  1050.      */
  1051.     @Override
  1052.     public NotifierInputStreamParams getNotifierInputStreamParamsResponse() throws ConnettoreException{
  1053.         if(this.preInResponseContext !=null){
  1054.             return this.preInResponseContext.getNotifierInputStreamParams();
  1055.         }
  1056.         return null;
  1057.     }
  1058.    
  1059.    
  1060.     protected void postOutRequest() throws Exception{
  1061.        
  1062.         if(this.registerSendIntoContext && this.getPddContext()!=null) {
  1063.             this.getPddContext().addObject(Costanti.RICHIESTA_INOLTRATA_BACKEND, Costanti.RICHIESTA_INOLTRATA_BACKEND_VALORE);
  1064.         }
  1065.        
  1066.         if(this.msgDiagnostico!=null && this.outRequestContext!=null){
  1067.            
  1068.             this.postOutRequestContext = new PostOutRequestContext(this.outRequestContext);
  1069.             this.postOutRequestContext.setCodiceTrasporto(this.getCodiceTrasporto());
  1070.             this.postOutRequestContext.setResponseHeaders(this.getHeaderTrasporto());
  1071.            
  1072.             // invocazione handler
  1073.             try{
  1074.                 GestoreHandlers.postOutRequest(this.postOutRequestContext, this.msgDiagnostico, OpenSPCoop2Logger.getLoggerOpenSPCoopCore());
  1075.             }catch(Exception e){
  1076.                 if(e instanceof HandlerException){
  1077.                     HandlerException he = (HandlerException) e;
  1078.                     if(he.isEmettiDiagnostico()){
  1079.                         this.msgDiagnostico.logErroreGenerico(e, ((HandlerException)e).getIdentitaHandler());
  1080.                     }
  1081.                     else{
  1082.                         OpenSPCoop2Logger.getLoggerOpenSPCoopCore().error(e.getMessage(),e);
  1083.                     }
  1084.                 }else{
  1085.                     this.msgDiagnostico.logErroreGenerico(e, "PostOutRequestHandler");
  1086.                 }
  1087.                 throw e;
  1088.             }
  1089.         }
  1090.        
  1091.     }
  1092.    
  1093.     protected void preInResponse() throws Exception{
  1094.        
  1095.         this.dataAccettazioneRisposta = DateManager.getDate();
  1096.        
  1097.         if(this.msgDiagnostico!=null && this.outRequestContext!=null){
  1098.        
  1099.             PostOutRequestContext postContext = this.postOutRequestContext;
  1100.             if(postContext==null){
  1101.                 postContext = new PostOutRequestContext(this.outRequestContext);
  1102.                 postContext.setCodiceTrasporto(this.getCodiceTrasporto());
  1103.                 postContext.setResponseHeaders(this.getHeaderTrasporto());
  1104.             }
  1105.            
  1106.             this.preInResponseContext = new PreInResponseContext(postContext);
  1107.            
  1108.             // invocazione handler
  1109.             try{
  1110.                 GestoreHandlers.preInResponse(this.preInResponseContext, this.msgDiagnostico, OpenSPCoop2Logger.getLoggerOpenSPCoopCore());
  1111.             }catch(Exception e){
  1112.                 if(e instanceof HandlerException){
  1113.                     HandlerException he = (HandlerException) e;
  1114.                     if(he.isEmettiDiagnostico()){
  1115.                         this.msgDiagnostico.logErroreGenerico(e, ((HandlerException)e).getIdentitaHandler());
  1116.                     }
  1117.                     else{
  1118.                         OpenSPCoop2Logger.getLoggerOpenSPCoopCore().error(e.getMessage(),e);
  1119.                     }
  1120.                 }else{
  1121.                     this.msgDiagnostico.logErroreGenerico(e, "PreInResponseHandler");
  1122.                 }
  1123.                 throw e;
  1124.             }
  1125.         }
  1126.            
  1127.     }
  1128.        
  1129.     protected String readExceptionMessageFromException(Throwable e) {
  1130.         return readConnectionExceptionMessageFromException(e);
  1131.     }
  1132.     public static String readConnectionExceptionMessageFromException(Throwable e) {
  1133.        
  1134.         // In questo metodo è possibile gestire meglio la casistica dei messaggi di errore ritornati.
  1135.        
  1136.         // 1. Host Unknown
  1137.         // java.net.UnknownHostException
  1138.         if(e instanceof java.net.UnknownHostException){
  1139.             return "unknown host '"+e.getMessage()+"'";
  1140.         }
  1141.        
  1142.         // 2. java.net.SocketException
  1143.         if(e instanceof java.net.SocketException){
  1144.             java.net.SocketException s = (java.net.SocketException) e;
  1145.             if(_isNotNullMessageException(s)){
  1146.                 return s.getMessage();
  1147.             }
  1148.         }
  1149.         if(Utilities.existsInnerException(e, java.net.SocketException.class)){
  1150.             Throwable internal = Utilities.getInnerException(e, java.net.SocketException.class);
  1151.             if(_isNotNullMessageException(internal)){
  1152.                 return _buildException(e, internal);
  1153.             }
  1154.         }
  1155.        
  1156.         // 3. java.security.cert.CertificateException
  1157.         if(java.security.cert.CertificateException.class.isInstance(e)){
  1158.             java.security.cert.CertificateException ce = (java.security.cert.CertificateException) e;
  1159.             if(_isNotNullMessageException(ce)){
  1160.                 return ce.getMessage();
  1161.             }
  1162.         }
  1163.         if(Utilities.existsInnerInstanceException(e, java.security.cert.CertificateException.class)){
  1164.             boolean last = true;
  1165.            
  1166.             Throwable internalNotYetValid = Utilities.getInnerInstanceException(e, java.security.cert.CertificateNotYetValidException.class, last);
  1167.             if(internalNotYetValid!=null) {
  1168.                 if(_isNotNullMessageException(internalNotYetValid)){
  1169.                     return _buildException(e, internalNotYetValid);
  1170.                 }
  1171.             }
  1172.            
  1173.             Throwable internalExpired = Utilities.getInnerInstanceException(e, java.security.cert.CertificateExpiredException.class, last);
  1174.             if(internalExpired!=null) {
  1175.                 if(_isNotNullMessageException(internalExpired)){
  1176.                     return _buildException(e, internalExpired);
  1177.                 }
  1178.             }
  1179.            
  1180.             // Anche in questo caso vengono due eccezioni uguali
  1181. //          Throwable internalRevoked = Utilities.getInnerInstanceException(e, java.security.cert.CertificateRevokedException.class, last);
  1182. //          if(internalRevoked!=null) {
  1183. //              if(_isNotNullMessageException(internalRevoked)){
  1184. //                  return _buildException(e, internalRevoked);
  1185. //              }
  1186. //          }
  1187. //          
  1188.             // solo nei casi precedenti costruisco una eccezione con la parte interna.
  1189.             // Negli altri casi (es. certificato non presente nel truststore 'unable to find valid certification path to requested target') verrebbero due eccezioni uguali
  1190.             if(_isNotNullMessageException(e)){
  1191.                 return e.getMessage();
  1192.             }
  1193.         }
  1194.        
  1195.         // 4. java.io.IOException
  1196.         if(e instanceof java.io.IOException || java.io.IOException.class.isInstance(e)){
  1197.             java.io.IOException io = (java.io.IOException) e;
  1198.             if(_isNotNullMessageException(io)){
  1199.                 return io.getMessage();
  1200.             }
  1201.         }
  1202.         if(Utilities.existsInnerException(e, java.io.IOException.class)){
  1203.             Throwable internal = Utilities.getInnerException(e, java.io.IOException.class);
  1204.             if(_isNotNullMessageException(internal)){
  1205.                 return _buildException(e, internal);
  1206.             }
  1207.         }
  1208.        
  1209.         // 5. ClientAbortException (Succede nel caso il buffer del client non sia più disponibile)
  1210.         if(Utilities.existsInnerException(e, "org.apache.catalina.connector.ClientAbortException")){
  1211.             Throwable internal = Utilities.getInnerException(e, "org.apache.catalina.connector.ClientAbortException");
  1212.             if(_isNotNullMessageException(internal)){
  1213.                 return "ClientAbortException - "+ _buildException(e, internal);
  1214.             }
  1215.         }
  1216.                                
  1217.         // Check Null Message
  1218.         if(_isNotNullMessageException(e)){
  1219.             return e.getMessage();
  1220.         }
  1221.         else{
  1222.             Throwable tNotEmpty = ParseExceptionUtils.getInnerNotEmptyMessageException(e);
  1223.             if(tNotEmpty!=null){
  1224.                 return tNotEmpty.getMessage();
  1225.             }
  1226.             else{
  1227.                 return "ErrorOccurs - "+ e.getMessage();
  1228.             }
  1229.         }
  1230.        
  1231.     }
  1232.     protected String buildException(Throwable original,Throwable internal){
  1233.         return _buildException(original, internal);
  1234.     }
  1235.     private static String _buildException(Throwable original,Throwable internal){
  1236.         if(_isNotNullMessageException(original)){
  1237.             String internalMessage = internal.getMessage();
  1238.             String originalMessage = original.getMessage();
  1239.             if(originalMessage!=null && !originalMessage.equals(internalMessage)) {
  1240.                 return internalMessage + " (sourceException: "+originalMessage+")";
  1241.             }
  1242.             else {
  1243.                 return internal.getMessage();
  1244.             }
  1245.         }
  1246.         else{
  1247.             return internal.getMessage();
  1248.         }
  1249.     }
  1250.     protected boolean isNotNullMessageException(Throwable tmp){
  1251.         return _isNotNullMessageException(tmp);
  1252.     }
  1253.     private static boolean _isNotNullMessageException(Throwable tmp){
  1254.         return tmp.getMessage()!=null && !"".equals(tmp.getMessage()) && !"null".equalsIgnoreCase(tmp.getMessage());
  1255.     }
  1256.    
  1257.     protected boolean isDumpBinarioRichiesta() {
  1258.         return this.debug || (this.dumpRaw!=null && this.dumpRaw.isActiveDumpDatabaseRichiesta());
  1259.                 //this.logFileTrace;
  1260.     }
  1261.     protected boolean isDumpBinarioRisposta() {
  1262.         return this.debug || (this.dumpRaw!=null && this.dumpRaw.isActiveDumpDatabaseRisposta());
  1263.                 //this.logFileTrace;
  1264.     }
  1265.    
  1266.     private InfoConnettoreUscita infoConnettoreUscita = null;
  1267.     protected void emitDiagnosticStartDumpBinarioRichiestaUscita() {
  1268.         if(this.dumpRaw!=null && this.dumpRaw.isActiveDumpDatabaseRichiesta()) {
  1269.             this.dumpRaw.emitDiagnosticStartDumpBinarioRichiestaUscita();
  1270.         }
  1271.     }
  1272.     protected void dumpBinarioRichiestaUscita(DumpByteArrayOutputStream bout, MessageType messageType, String contentTypeRichiesta,String location, Map<String, List<String>> trasporto) throws DumpException {
  1273.         if(this.debug){
  1274.             String content = null;
  1275.             if(bout!=null) {
  1276.                 content = bout.toString();
  1277.                 this.logger.info("Messaggio inviato (ContentType:"+contentTypeRichiesta+") :\n"+content,false);
  1278.             }
  1279.             else {
  1280.                 this.logger.info("Messaggio inviato senza contenuto nell'http-payload", false);
  1281.             }
  1282.         }
  1283.         if(this.dumpRaw!=null && this.dumpRaw.isActiveDumpDatabaseRichiesta()) {
  1284.             this.infoConnettoreUscita = new InfoConnettoreUscita();
  1285.             this.infoConnettoreUscita.setLocation(location);
  1286.             this.infoConnettoreUscita.setHeaders(trasporto);
  1287.             this.dumpRaw.dumpRequest(bout, messageType, this.infoConnettoreUscita);
  1288.         }
  1289.     }
  1290.     protected void emitDiagnosticStartDumpBinarioRispostaIngresso() {
  1291.         if(this.dumpRaw!=null && this.dumpRaw.isActiveDumpDatabaseRisposta()) {
  1292.             this.dumpRaw.emitDiagnosticStartDumpBinarioRispostaIngresso();
  1293.         }
  1294.     }
  1295.     protected void dumpBinarioRispostaIngresso(DumpByteArrayOutputStream raw, MessageType messageType, Map<String, List<String>> trasportoRisposta) throws DumpException {
  1296.         if(this.dumpRaw!=null && this.dumpRaw.isActiveDumpDatabaseRisposta()) {
  1297.             this.dumpRaw.dumpResponse(raw, messageType, this.infoConnettoreUscita, trasportoRisposta);
  1298.         }
  1299.     }
  1300.    
  1301.     protected Map<String, Object> dynamicMap = null;
  1302.     protected Map<String, Object> buildDynamicMap(ConnettoreMsg connettoreMsg){
  1303.         if(this.dynamicMap==null) {
  1304.             this.dynamicMap = new HashMap<>();
  1305.         }
  1306.         DynamicInfo dInfo = new DynamicInfo(connettoreMsg, this.getPddContext());
  1307.         Logger log = null;
  1308.         if(this.logger!=null) {
  1309.             log = this.logger.getLogger();
  1310.         }
  1311.         if(log==null) {
  1312.             log = OpenSPCoop2Logger.getLoggerOpenSPCoopCore();
  1313.         }
  1314.         DynamicUtils.fillDynamicMap(log,this.dynamicMap, dInfo);
  1315.         return this.dynamicMap;
  1316.     }
  1317.    
  1318.     protected String getDynamicProperty(String tipoConnettore,boolean required,String name,Map<String,Object> dynamicMap) throws ConnettoreException{
  1319.         String tmp = this.properties.get(name);
  1320.         if(tmp!=null){
  1321.             tmp = tmp.trim();
  1322.         }
  1323.         if(tmp==null || "".equals(tmp)){
  1324.             if(required){
  1325.                 throw new ConnettoreException("Proprieta' '"+name+"' non fornita e richiesta da questo tipo di connettore ["+tipoConnettore+"]");
  1326.             }
  1327.             return null;
  1328.         }
  1329.         try {
  1330.             return DynamicUtils.convertDynamicPropertyValue(name, tmp, dynamicMap, this.getPddContext(), false);
  1331.         }catch(Exception e) {
  1332.             throw new ConnettoreException(e.getMessage(),e);
  1333.         }
  1334.     }
  1335.    
  1336.    
  1337.    
  1338.     protected boolean isBooleanProperty(String tipoConnettore,boolean defaultValue,String name){
  1339.         String tmp = this.properties.get(name);
  1340.         if(tmp!=null){
  1341.             tmp = tmp.trim();
  1342.         }
  1343.         if(tmp==null || "".equals(tmp)){
  1344.             return defaultValue;
  1345.         }
  1346.         return "true".equalsIgnoreCase(tmp) || CostantiConfigurazione.ABILITATO.getValue().equalsIgnoreCase(tmp);
  1347.     }
  1348.    
  1349.     protected Integer getIntegerProperty(String tipoConnettore,boolean required,String name) throws ConnettoreException{
  1350.         String tmp = this.properties.get(name);
  1351.         if(tmp!=null){
  1352.             tmp = tmp.trim();
  1353.         }
  1354.         if(tmp==null || "".equals(tmp)){
  1355.             if(required){
  1356.                 throw new ConnettoreException("Proprieta' '"+name+"' non fornita e richiesta da questo tipo di connettore ["+tipoConnettore+"]");
  1357.             }
  1358.             return null;
  1359.         }
  1360.         try{
  1361.             return Integer.parseInt(tmp);
  1362.         }catch(Exception e){
  1363.             throw new ConnettoreException("Proprieta' '"+name+"' contiene un valore non corretto: "+e.getMessage(),e);
  1364.         }

  1365.     }
  1366.    
  1367.    
  1368.     protected void forwardHttpRequestHeader() throws Exception{
  1369.         OpenSPCoop2MessageProperties forwardHeader = null;
  1370.         if(ServiceBinding.REST.equals(this.requestMsg.getServiceBinding())) {
  1371.             forwardHeader = this.requestMsg.getForwardTransportHeader(this.openspcoopProperties.getRESTServicesHeadersForwardConfig(true));
  1372.         }
  1373.         else {
  1374.             forwardHeader = this.requestMsg.getForwardTransportHeader(this.openspcoopProperties.getSOAPServicesHeadersForwardConfig(true));
  1375.         }
  1376.                
  1377.         if(forwardHeader!=null && forwardHeader.size()>0){
  1378.             if(this.debug)
  1379.                 this.logger.debug("Forward header di trasporto (size:"+forwardHeader.size()+") ...");
  1380.             if(this.propertiesTrasporto==null){
  1381.                 this.propertiesTrasporto = new HashMap<>();
  1382.             }
  1383.             Iterator<String> keys = forwardHeader.getKeys();
  1384.             while (keys.hasNext()) {
  1385.                 String key = (String) keys.next();
  1386.                 List<String> values = forwardHeader.getPropertyValues(key);
  1387.                 if(values!=null && !values.isEmpty()) {
  1388.                     List<String> vs = new ArrayList<>(values); // per evitare che la add sottostante aggiunga alla collezione e si continui a iterare
  1389.                     for (String value : vs) {
  1390.                         if(this.debug)
  1391.                             this.logger.debug("Forward Transport Header ["+key+"]=["+value+"]");
  1392.                         TransportUtils.addHeader(this.propertiesTrasporto, key, value);    
  1393.                     }
  1394.                 }
  1395.             }
  1396.         }
  1397.     }
  1398.    
  1399.    
  1400.     private Map<String,List<String>> headersImpostati = new HashMap<>(); // per evitare che header generati nel conettore siano sovrascritti da eventuali forward. Gli header del connettore vengono impostati prima del forward.
  1401.     protected void clearRequestHeader() {
  1402.         this.headersImpostati.clear();
  1403.     }
  1404.     private Messaggio messaggioDumpUscita = null;
  1405.     protected void setRequestHeader(String key,List<String> values) throws Exception {} // ridefinito nei connettori dove esistono header da spedire
  1406.     protected void setRequestHeader(String key, String value, Map<String, List<String>> propertiesTrasportoDebug) throws Exception {
  1407.         List<String> list = new ArrayList<>();
  1408.         list.add(value);
  1409.         this.setRequestHeader(key, list, propertiesTrasportoDebug);
  1410.     }
  1411.     protected void setRequestHeader(String key,List<String> values, Map<String, List<String>> propertiesTrasportoDebug) throws Exception {
  1412.         if(!this.headersImpostati.containsKey(key)) {
  1413.             this.headersImpostati.put(key,values);
  1414.             this.setRequestHeader(key,values);
  1415.             if(propertiesTrasportoDebug!=null) {
  1416.                 propertiesTrasportoDebug.put(key, values);
  1417.             }
  1418.         }
  1419.         else {
  1420.             // Update eventuale dump in TransazioneContext
  1421.             if(this.messaggioDumpUscita==null) {
  1422.                 if(this.openspcoopProperties.isTransazioniSaveDumpInUniqueTransaction() && this.getPddContext()!=null && this.getPddContext().containsKey(org.openspcoop2.core.constants.Costanti.ID_TRANSAZIONE)) {
  1423.                     try {
  1424.                         Transaction tr = TransactionContext.getTransaction((String)this.getPddContext().getObject(org.openspcoop2.core.constants.Costanti.ID_TRANSAZIONE));
  1425.                         if(tr!=null) {
  1426.                             for (Messaggio messaggio : tr.getMessaggi()) {
  1427.                                 if(TipoMessaggio.RICHIESTA_USCITA.equals(messaggio.getTipoMessaggio())) {
  1428.                                     this.messaggioDumpUscita = messaggio;
  1429.                                     break;
  1430.                                 }
  1431.                             }
  1432.                         }
  1433.                     }
  1434.                     catch(TransactionNotExistsException e) {
  1435.                         this.logger.debug("Adeguamento dump http header non riuscito (token ): "+e.getMessage());
  1436.                     }
  1437.                     catch(Throwable e){
  1438.                         this.logger.error("Adeguamento dump http header non riuscito: "+e.getMessage(),e);
  1439.                     }
  1440.                 }
  1441.             }
  1442.             if(this.messaggioDumpUscita!=null) {
  1443.                 if(this.messaggioDumpUscita.getHeaders()==null) {
  1444.                     this.messaggioDumpUscita.setHeaders(new HashMap<>());
  1445.                 }
  1446.                 TransportUtils.removeRawObject(this.messaggioDumpUscita.getHeaders(), key);
  1447.                 this.messaggioDumpUscita.getHeaders().put(key, this.headersImpostati.get(key));
  1448.             }
  1449.         }
  1450.     }
  1451.    
  1452.     private boolean emitDiagnosticResponseRead = false;
  1453.     protected void emitDiagnosticResponseRead(InputStream is) {
  1454.         if(is!=null && this.msgDiagnostico!=null && !this.emitDiagnosticResponseRead) {
  1455.             this.msgDiagnostico.logPersonalizzato("ricezioneRisposta.firstAccessRequestStream");
  1456.             this.emitDiagnosticResponseRead = true;
  1457.         }
  1458.     }
  1459. }