FiltroDuplicati.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.transazioni;

  21. import java.sql.Connection;
  22. import java.sql.PreparedStatement;
  23. import java.sql.ResultSet;
  24. import java.sql.Timestamp;
  25. import java.text.SimpleDateFormat;

  26. import org.slf4j.Logger;
  27. import org.openspcoop2.core.constants.CostantiDB;
  28. import org.openspcoop2.core.constants.TipoPdD;
  29. import org.openspcoop2.core.transazioni.Transazione;
  30. import org.openspcoop2.core.transazioni.dao.jdbc.converter.TransazioneFieldConverter;
  31. import org.openspcoop2.pdd.config.DBTransazioniManager;
  32. import org.openspcoop2.pdd.config.OpenSPCoop2Properties;
  33. import org.openspcoop2.pdd.config.Resource;
  34. import org.openspcoop2.pdd.core.PdDContext;
  35. import org.openspcoop2.pdd.core.state.OpenSPCoopState;
  36. import org.openspcoop2.pdd.logger.OpenSPCoop2Logger;
  37. import org.openspcoop2.protocol.engine.driver.IFiltroDuplicati;
  38. import org.openspcoop2.protocol.sdk.Busta;
  39. import org.openspcoop2.protocol.sdk.IProtocolFactory;
  40. import org.openspcoop2.protocol.sdk.ProtocolException;
  41. import org.openspcoop2.protocol.sdk.builder.IBustaBuilder;
  42. import org.openspcoop2.protocol.sdk.state.RequestInfo;
  43. import org.openspcoop2.utils.date.DateManager;
  44. import org.openspcoop2.utils.date.DateUtils;
  45. import org.openspcoop2.utils.sql.ISQLQueryObject;
  46. import org.openspcoop2.utils.sql.SQLObjectFactory;

  47. /**    
  48.  * FiltroDuplicati
  49.  *
  50.  * @author Poli Andrea (poli@link.it)
  51.  * @author $Author$
  52.  * @version $Rev$, $Date$
  53.  */
  54. public class FiltroDuplicati implements IFiltroDuplicati {

  55.     private OpenSPCoop2Properties openspcoop2Properties;
  56.    
  57.     private String idTransazione = null;
  58.     private RequestInfo requestInfo = null;
  59.    
  60.     private org.openspcoop2.protocol.engine.driver.FiltroDuplicati filtroDuplicatiProtocol;
  61.        
  62.     private OpenSPCoopState openspcoop2State = null;
  63.     private Boolean initDsResource = null;
  64.     private Connection connection = null;
  65.     private boolean isDirectConnection = false;
  66.     @SuppressWarnings("unused")
  67.     private String modeGetConnection = null;
  68.     private boolean releaseRuntimeResourceBeforeCheck = false;
  69.     private String tipoDatabaseRuntime = null;
  70.     private Logger log = null;
  71.     private Logger logSql = null;
  72.     private boolean debug = false;
  73.    
  74.     private TransazioneFieldConverter transazioneFieldConverter = null;
  75.     private String nomeTabellaTransazioni = null;

  76.     private String colonna_pdd_ruolo = null;
  77.    
  78.     private String colonna_duplicati_richiesta = null;
  79.     private String colonna_data_id_msg_richiesta = null;
  80.     private String colonna_id_messaggio_richiesta = null;

  81.     private String colonna_duplicati_risposta = null;
  82.     private String colonna_data_id_msg_risposta = null;
  83.     private String colonna_id_messaggio_risposta = null;
  84.    
  85.     private boolean useTransactionIdForTest = false; // solo per test
  86.     public boolean isUseTransactionIdForTest() {
  87.         return this.useTransactionIdForTest;
  88.     }
  89.     public void setUseTransactionIdForTest(boolean useTransactionIdForTest) {
  90.         this.useTransactionIdForTest = useTransactionIdForTest;
  91.     }

  92.     private static final String ID_MODULO = "FiltroDuplicati";
  93.    

  94.     @Override
  95.     public void init(Object context) throws ProtocolException{
  96.        
  97.         this.openspcoop2Properties = OpenSPCoop2Properties.getInstance();
  98.        
  99.         if(this.openspcoop2Properties.isTransazioniFiltroDuplicatiTramiteTransazioniEnabled() == false) {
  100.             this.filtroDuplicatiProtocol = new org.openspcoop2.protocol.engine.driver.FiltroDuplicati();
  101.             this.filtroDuplicatiProtocol.init(context);
  102.         }
  103.         else {
  104.             PdDContext pddContext = (PdDContext)context;
  105.             if(pddContext==null) {
  106.                 throw new ProtocolException("PdDContext non fornito");
  107.             }
  108.             this.idTransazione = (String) pddContext.getObject(org.openspcoop2.core.constants.Costanti.ID_TRANSAZIONE);
  109.             if(this.idTransazione==null){
  110.                 throw new ProtocolException("Id di transazione non fornito");
  111.             }
  112.            
  113.             if(pddContext!=null && pddContext.containsKey(org.openspcoop2.core.constants.Costanti.REQUEST_INFO)) {
  114.                 this.requestInfo = (RequestInfo) pddContext.getObject(org.openspcoop2.core.constants.Costanti.REQUEST_INFO);
  115.             }
  116.            
  117.             if(this.initDsResource==null && this.connection==null){
  118.                 this.init((PdDContext)context);
  119.             }
  120.         }
  121.        
  122.     }
  123.    
  124.     @Override
  125.     public boolean releaseRuntimeResourceBeforeCheck() {
  126.         return this.releaseRuntimeResourceBeforeCheck;
  127.     }
  128.    
  129.     @Override
  130.     public boolean isDuplicata(IProtocolFactory<?> protocolFactory, String idBustaParam) throws ProtocolException {
  131.        
  132.         String idBusta = this.useTransactionIdForTest ? this.idTransazione : idBustaParam;
  133.                
  134.         long timeStart = -1;
  135.         TransazioniFiltroDuplicatiProcessTimes times = null;
  136.         try {
  137.             if(this.openspcoop2Properties.isTransazioniRegistrazioneSlowLog()) {
  138.                 timeStart = DateManager.getTimeMillis();
  139.                 times = new TransazioniFiltroDuplicatiProcessTimes();
  140.             }
  141.        
  142.             if(this.filtroDuplicatiProtocol!=null) {
  143.                 return this.filtroDuplicatiProtocol.isDuplicata(protocolFactory, idBusta);
  144.             }
  145.            
  146.             //System.out.println("@@IS_DUPLICATA ["+idBusta+"] idTransaction("+this.idTransazione+") (useTransactionIdForTest:"+this.useTransactionIdForTest+") ...");
  147.            
  148.             // E' duplicata se esiste nel contesto una transazione con tale idBusta
  149.             if(TransactionContext.containsIdentificativoProtocollo(idBusta)){
  150.                 //System.out.println("@@IS_DUPLICATA ["+idBusta+"] TRUE (CONTEXT)");
  151.                 try{
  152.                     TransactionContext.getTransaction(this.idTransazione).addIdProtocolloDuplicato(idBusta);
  153.                 }catch(Exception e){
  154.                     throw new ProtocolException(e);
  155.                 }
  156.                 return true;
  157.             }
  158.            
  159.             // oppure se esiste una transazione registrata con tale idBusta sul database (Richiesta o Risposta).
  160.             //System.out.println("@@IS_DUPLICATA ["+idBusta+"] READ FROM DB");
  161.             if(esisteTransazione(protocolFactory,idBusta,idBusta,times)){
  162.                 //System.out.println("@@IS_DUPLICATA ["+idBusta+"] TRUE (DATABASE)");
  163.                 try{
  164.                     TransactionContext.getTransaction(this.idTransazione).addIdProtocolloDuplicato(idBusta);
  165.                 }catch(Exception e){
  166.                     throw new ProtocolException(e);
  167.                 }
  168.                 return true;
  169.             }
  170.            
  171.             // Se non esiste registro nel contesto questa transazione.
  172.             // Comunque OpenSPCoop se torno false, procedera a chiamare registraBusta, il quale metodo non fara' nulla (vedi implementazione sotto stante)
  173.             // Il metodo di registrazione dell'identificativo busta viene acceduto tramite un semaforo e controlla che non sia possibile registrare due identificativi busta.
  174.             // Tale implementazione garantisce che nel contesto puo' esistere solo un idBusta, e tale id viene eliminato SOLO dopo
  175.             // aver salvato la transazione nel database (vedi implementazione PostOutResponseHandler, metodo removeIdentificativoProtocollo)
  176.             // Se dopo aver eliminato dal contesto l'id, arriva una nuova busta con stesso id, questo metodo la trova nella tabelle delle transazioni
  177.             // e quindi ritornera' immediatamente l'informazione di busta duplicata.
  178.             try{
  179.                 //System.out.println("@@IS_DUPLICATA ["+idBusta+"] FALSE ....");
  180.                 TransactionContext.registraIdentificativoProtocollo(idBusta, this.idTransazione);
  181.                 //System.out.println("@@IS_DUPLICATA ["+idBusta+"] FALSE REGISTRATA");
  182.             }catch(Exception e){
  183.                 if(e.getMessage()!=null && "DUPLICATA".equals(e.getMessage())){
  184.                     //System.out.println("@@IS_DUPLICATA ["+idBusta+"] TRUE (ERRORE ECCEZIONE)");
  185.                     try{
  186.                         TransactionContext.getTransaction(this.idTransazione).addIdProtocolloDuplicato(idBusta);
  187.                     }catch(Exception eSetDuplicata){
  188.                         throw new ProtocolException(eSetDuplicata);
  189.                     }
  190.                     return true;
  191.                 }else{
  192.                     throw new ProtocolException(e);
  193.                 }
  194.             }
  195.            
  196.             //System.out.println("@@IS_DUPLICATA ["+idBusta+"] FALSE FINE");
  197.             return false;
  198.            
  199.         }finally {
  200.             if(this.openspcoop2Properties.isTransazioniRegistrazioneSlowLog()) {
  201.                 long timeEnd =  DateManager.getTimeMillis();
  202.                 long timeProcess = timeEnd-timeStart;
  203.                 if(timeProcess>=this.openspcoop2Properties.getTransazioniRegistrazioneSlowLogThresholdMs()) {
  204.                     StringBuilder sb = new StringBuilder();
  205.                     sb.append(timeProcess);
  206.                     if(this.idTransazione!=null) {
  207.                         sb.append(" <").append(this.idTransazione).append(">");
  208.                     }
  209.                     sb.append(" [isDuplicata]");
  210.                     sb.append(" ").append(idBusta);
  211.                     if(times!=null) {
  212.                         sb.append(" ").append(times.toString());
  213.                     }
  214.                     OpenSPCoop2Logger.getLoggerOpenSPCoopTransazioniSlowLog().info(sb.toString());
  215.                 }
  216.             }
  217.         }
  218.     }

  219.     @Override
  220.     public void incrementaNumeroDuplicati(IProtocolFactory<?> protocolFactory, String idBusta) throws ProtocolException {
  221.        
  222.         long timeStart = -1;
  223.         TransazioniFiltroDuplicatiProcessTimes times = null;
  224.         try {
  225.             if(this.openspcoop2Properties.isTransazioniRegistrazioneSlowLog()) {
  226.                 timeStart = DateManager.getTimeMillis();
  227.                 times = new TransazioniFiltroDuplicatiProcessTimes();
  228.             }
  229.        
  230.             if(this.filtroDuplicatiProtocol!=null) {
  231.                 this.filtroDuplicatiProtocol.incrementaNumeroDuplicati(protocolFactory, idBusta);
  232.                 return;
  233.             }
  234.            
  235.             //System.out.println("@@incrementaNumeroDuplicati ["+idBusta+"] ...");
  236.            
  237.             incrementDuplicatiTransazione(protocolFactory, idBusta, times);
  238.            
  239.             //System.out.println("@@incrementaNumeroDuplicati richiesta["+esisteRichiesta+"] risposta["+esisteRisposta+"] FINE");
  240.         }finally {
  241.             if(this.openspcoop2Properties.isTransazioniRegistrazioneSlowLog()) {
  242.                 long timeEnd =  DateManager.getTimeMillis();
  243.                 long timeProcess = timeEnd-timeStart;
  244.                 if(timeProcess>=this.openspcoop2Properties.getTransazioniRegistrazioneSlowLogThresholdMs()) {
  245.                     StringBuilder sb = new StringBuilder();
  246.                     sb.append(timeProcess);
  247.                     if(this.idTransazione!=null) {
  248.                         sb.append(" <").append(this.idTransazione).append(">");
  249.                     }
  250.                     sb.append(" [incrementaNumeroDuplicati]");
  251.                     sb.append(" ").append(idBusta);
  252.                     if(times!=null) {
  253.                         sb.append(" ").append(times.toString());
  254.                     }
  255.                     OpenSPCoop2Logger.getLoggerOpenSPCoopTransazioniSlowLog().info(sb.toString());
  256.                 }
  257.             }
  258.         }
  259.     }

  260.     @Override
  261.     public void registraBusta(IProtocolFactory<?> protocolFactory, Busta busta) throws ProtocolException {
  262.        
  263.         long timeStart = -1;
  264.         try {
  265.             if(this.openspcoop2Properties.isTransazioniRegistrazioneSlowLog()) {
  266.                 timeStart = DateManager.getTimeMillis();
  267.             }
  268.        
  269.             if(this.filtroDuplicatiProtocol!=null) {
  270.                 this.filtroDuplicatiProtocol.registraBusta(protocolFactory, busta);
  271.                 return;
  272.             }
  273.            
  274.             // Implementazione inserita in isDuplicata
  275.             //System.out.println("@@registraBusta ["+busta.getID()+"] NON IMPLEMENTATO");
  276.            
  277.         }finally {
  278.             if(this.openspcoop2Properties.isTransazioniRegistrazioneSlowLog()) {
  279.                 long timeEnd =  DateManager.getTimeMillis();
  280.                 long timeProcess = timeEnd-timeStart;
  281.                 if(timeProcess>=this.openspcoop2Properties.getTransazioniRegistrazioneSlowLogThresholdMs()) {
  282.                     StringBuilder sb = new StringBuilder();
  283.                     sb.append(timeProcess);
  284.                     if(this.idTransazione!=null) {
  285.                         sb.append(" <").append(this.idTransazione).append(">");
  286.                     }
  287.                     sb.append(" [registraBusta]");
  288.                     if(busta!=null) {
  289.                         sb.append(" ").append(busta.getID());
  290.                     }
  291.                     OpenSPCoop2Logger.getLoggerOpenSPCoopTransazioniSlowLog().info(sb.toString());
  292.                 }
  293.             }
  294.         }
  295.     }

  296.    
  297.    
  298.     /* **** METODI INTERNI **** */
  299.    
  300.     private synchronized void init(PdDContext pddContext) throws ProtocolException {

  301.         //if(this.dsRuntime==null && this.connection==null){
  302.         if(this.initDsResource==null && this.connection==null){
  303.            
  304.             try{
  305.                 // Debug
  306.                 this.debug = this.openspcoop2Properties.isTransazioniDebug();
  307.                 this.log = OpenSPCoop2Logger.getLoggerOpenSPCoopTransazioni(this.debug);
  308.                 this.logSql = OpenSPCoop2Logger.getLoggerOpenSPCoopTransazioniSql(this.debug);
  309.             }catch(Exception e){
  310.                 throw new ProtocolException("Errore durante l'inizializzazione del logger: "+e.getMessage(),e);
  311.             }
  312.            
  313.             try{
  314.                
  315.                 // TipoDatabase
  316.                 this.tipoDatabaseRuntime = this.openspcoop2Properties.getDatabaseType();
  317.                 if(this.tipoDatabaseRuntime==null){
  318.                     throw new Exception("Tipo Database non definito");
  319.                 }
  320.                
  321.                 // DB Resource
  322.                 Object openspcoopstate = pddContext.getObject(org.openspcoop2.core.constants.Costanti.OPENSPCOOP_STATE);
  323.                 if(openspcoopstate!=null) {
  324.                     this.openspcoop2State = (OpenSPCoopState) openspcoopstate;
  325.                 }
  326.                 if(this.openspcoop2State!=null && this.openspcoop2Properties.isTransazioniFiltroDuplicatiTramiteTransazioniUsePdDConnection()
  327.                         && DBTransazioniManager.getInstance().useRuntimePdD() && !this.openspcoop2State.resourceReleased()){
  328.                     //System.out.println("[FILTRO] INIZIALIZZO CONNESSIONE");
  329.                     this.connection = this.openspcoop2State.getConnectionDB();
  330.                     //this.datasourceRuntime = "DirectConnection";
  331.                     this.modeGetConnection = "DirectConnection";
  332.                     this.isDirectConnection = true;
  333.                 }
  334.                 else{
  335.                     //System.out.println("[FILTRO] INIZIALIZZO DS");
  336. //                  this.datasourceRuntime = PddInterceptorConfig.getDataSource();
  337. //                  if(this.datasourceRuntime==null){
  338. //                      throw new Exception("Datasource non definito");
  339. //                  }
  340.                     this.initDsResource = true;
  341.                     this.modeGetConnection = "DatasourceRuntime";
  342.                    
  343.                     this.releaseRuntimeResourceBeforeCheck = true; // per evitare deadlock
  344.                    
  345.                     // Inizializzazione datasource
  346. //                  GestoreJNDI jndi = new GestoreJNDI();
  347. //                  this.dsRuntime = (DataSource) jndi.lookup(this.datasourceRuntime);
  348.                 }
  349.                                
  350.                 //System.out.println("DS["+this.datasource+"] TIPODB["+this.tipoDatabase+"]");
  351.                                
  352.                 this.transazioneFieldConverter = new TransazioneFieldConverter(this.tipoDatabaseRuntime);
  353.                
  354.                 this.nomeTabellaTransazioni = this.transazioneFieldConverter.toTable(Transazione.model());
  355.                
  356.                 this.colonna_pdd_ruolo = this.transazioneFieldConverter.toColumn(Transazione.model().PDD_RUOLO, false);
  357.                            
  358.                 this.colonna_duplicati_richiesta = this.transazioneFieldConverter.toColumn(Transazione.model().DUPLICATI_RICHIESTA, false);
  359.                 this.colonna_data_id_msg_richiesta = this.transazioneFieldConverter.toColumn(Transazione.model().DATA_ID_MSG_RICHIESTA, false);
  360.                 this.colonna_id_messaggio_richiesta = this.transazioneFieldConverter.toColumn(Transazione.model().ID_MESSAGGIO_RICHIESTA, false);
  361.                
  362.                 this.colonna_duplicati_risposta = this.transazioneFieldConverter.toColumn(Transazione.model().DUPLICATI_RISPOSTA, false);
  363.                 this.colonna_data_id_msg_risposta = this.transazioneFieldConverter.toColumn(Transazione.model().DATA_ID_MSG_RISPOSTA, false);
  364.                 this.colonna_id_messaggio_risposta = this.transazioneFieldConverter.toColumn(Transazione.model().ID_MESSAGGIO_RISPOSTA, false);
  365.                
  366.             }catch(Exception e){
  367.                 throw new ProtocolException("Errore durante l'inizializzazione dell'appender: "+e.getMessage(),e);
  368.             }
  369.         }
  370.        
  371.     }
  372.    
  373.    
  374.    
  375.     private boolean esisteTransazione(IProtocolFactory<?> protocolFactory, String idBustaRichiesta,String idBustaRisposta,
  376.             TransazioniFiltroDuplicatiProcessTimes times) throws ProtocolException {
  377.         Connection con = null;
  378.         DBTransazioniManager dbManager = null;
  379.         Resource r = null;
  380.         String idModulo = ID_MODULO+".esisteTransazione"; //_"+idBustaRichiesta+"/"+idBustaRisposta;
  381.         try{
  382.            
  383.             IBustaBuilder<?> protocolBustaBuilder = null;
  384.             if(this.openspcoop2State!=null) {
  385.                 if(idBustaRichiesta!=null) {
  386.                     protocolBustaBuilder = protocolFactory.createBustaBuilder(this.openspcoop2State.getStatoRichiesta());
  387.                 }
  388.                 else {
  389.                     protocolBustaBuilder = protocolFactory.createBustaBuilder(this.openspcoop2State.getStatoRisposta());
  390.                 }
  391.             }
  392.             else {                  
  393.                 protocolBustaBuilder = protocolFactory.createBustaBuilder(null);
  394.             }
  395.            
  396.             if(idBustaRichiesta==null && idBustaRisposta==null){
  397.                 throw new ProtocolException("ID busta non forniti");
  398.             }
  399.            
  400.             long timeStart = -1;
  401.             try{
  402.                 if(times!=null) {
  403.                     timeStart = DateManager.getTimeMillis();
  404.                 }
  405.                 if(this.connection!=null){
  406.                     //System.out.println("[FILTRO] esisteTransazione idBustaRichiesta["+idBustaRichiesta+"] idBustaRisposta["+idBustaRisposta+"] BY CONNECTION");
  407.                     con = this.connection;
  408.                 }else{
  409.                     //System.out.println("[FILTRO] esisteTransazione idBustaRichiesta["+idBustaRichiesta+"] idBustaRisposta["+idBustaRisposta+"] BY DATASOURCE");
  410.                     dbManager = DBTransazioniManager.getInstance();
  411.                     r = dbManager.getResource(this.openspcoop2Properties.getIdentitaPortaDefault(protocolFactory.getProtocol(), this.requestInfo), idModulo, this.idTransazione);
  412.                     if(r==null){
  413.                         throw new Exception("Risorsa al database non disponibile");
  414.                     }
  415.                     con = (Connection) r.getResource();
  416.                 }
  417.                 if(con==null){
  418.                     throw new Exception("Connection is null");
  419.                 }
  420.             }finally {  
  421.                 if(times!=null) {
  422.                     long timeEnd =  DateManager.getTimeMillis();
  423.                     long timeProcess = timeEnd-timeStart;
  424.                     times.getConnection = timeProcess;
  425.                 }
  426.             }
  427.            
  428.             return esisteTransazione_query(protocolFactory, idBustaRichiesta, idBustaRisposta,
  429.                     con, protocolBustaBuilder, times);
  430.            
  431.         }catch(Exception e){
  432.             throw new ProtocolException(e);
  433.         }
  434.         finally{
  435.             if(this.isDirectConnection==false){
  436.                 try{
  437.                     if(r!=null)
  438.                         dbManager.releaseResource(this.openspcoop2Properties.getIdentitaPortaDefault(protocolFactory.getProtocol(), this.requestInfo), idModulo, r);
  439.                 }catch(Exception eClose){}
  440.             }
  441.         }
  442.        
  443.     }
  444.    
  445.     private void incrementDuplicatiTransazione(IProtocolFactory<?> protocolFactory, String idBusta,
  446.             TransazioniFiltroDuplicatiProcessTimes times) throws ProtocolException {
  447.         Connection con = null;
  448.         DBTransazioniManager dbManager = null;
  449.         Resource r = null;
  450.         String idModulo = ID_MODULO+".incrementDuplicatiTransazione"; //_"+idBustaRichiesta+"/"+idBustaRisposta;
  451.         try{
  452.            
  453.             IBustaBuilder<?> protocolBustaBuilder = null;
  454.             if(this.openspcoop2State!=null) {
  455.                 if(this.openspcoop2State.getStatoRichiesta()!=null) {
  456.                     protocolBustaBuilder = protocolFactory.createBustaBuilder(this.openspcoop2State.getStatoRichiesta());
  457.                 }
  458.                 else {
  459.                     protocolBustaBuilder = protocolFactory.createBustaBuilder(this.openspcoop2State.getStatoRisposta());
  460.                 }
  461.             }
  462.             else {                  
  463.                 protocolBustaBuilder = protocolFactory.createBustaBuilder(null);
  464.             }
  465.            
  466.             if(idBusta==null){
  467.                 throw new ProtocolException("ID busta non fornito");
  468.             }
  469.            
  470.             long timeStart = -1;
  471.             try{
  472.                 if(times!=null) {
  473.                     timeStart = DateManager.getTimeMillis();
  474.                 }
  475.                 if(this.connection!=null){
  476.                     //System.out.println("[FILTRO] esisteTransazione idBustaRichiesta["+idBustaRichiesta+"] idBustaRisposta["+idBustaRisposta+"] BY CONNECTION");
  477.                     con = this.connection;
  478.                 }else{
  479.                     //System.out.println("[FILTRO] esisteTransazione idBustaRichiesta["+idBustaRichiesta+"] idBustaRisposta["+idBustaRisposta+"] BY DATASOURCE");
  480.                     dbManager = DBTransazioniManager.getInstance();
  481.                     r = dbManager.getResource(this.openspcoop2Properties.getIdentitaPortaDefault(protocolFactory.getProtocol(), this.requestInfo), idModulo, this.idTransazione);
  482.                     if(r==null){
  483.                         throw new Exception("Risorsa al database non disponibile");
  484.                     }
  485.                     con = (Connection) r.getResource();
  486.                 }
  487.                 if(con==null){
  488.                     throw new Exception("Connection is null");
  489.                 }
  490.             }finally {  
  491.                 if(times!=null) {
  492.                     long timeEnd =  DateManager.getTimeMillis();
  493.                     long timeProcess = timeEnd-timeStart;
  494.                     times.getConnection = timeProcess;
  495.                 }
  496.             }
  497.            
  498.            
  499.             // Aggiorno numero duplicati per transazione che possiede tale idBusta (Richiesta o Risposta)
  500.             // Se non esiste una transazione sul database, devo attendere che questa compaia,
  501.             // significa che una precedente transazione con stesso idBusta e' ancora in gestione
  502.            
  503.             long timeRequest = -1;
  504.             long timeResponse = -1;
  505.             long timeSleep = -1;
  506.             boolean esisteRichiesta = false;
  507.             boolean esisteRisposta = false;
  508.             try{
  509.                 TransazioniFiltroDuplicatiProcessTimes checkRequest = null;
  510.                 TransazioniFiltroDuplicatiProcessTimes checkResponse = null;
  511.                
  512.                 if(times!=null) {
  513.                     checkRequest = new TransazioniFiltroDuplicatiProcessTimes();
  514.                 }
  515.                 esisteRichiesta = esisteTransazione_query(protocolFactory,idBusta,null,con,protocolBustaBuilder,checkRequest);
  516.                 if(times!=null) {
  517.                     timeRequest=checkRequest.read;
  518.                 }
  519.                
  520.                 if(!esisteRichiesta){
  521.                     if(times!=null) {
  522.                         checkResponse = new TransazioniFiltroDuplicatiProcessTimes();
  523.                     }
  524.                     esisteRisposta = esisteTransazione_query(protocolFactory,null,idBusta,con,protocolBustaBuilder,checkResponse);
  525.                     if(times!=null) {
  526.                         timeResponse=checkResponse.read;
  527.                     }
  528.                 }
  529.                 //System.out.println("@@incrementaNumeroDuplicati richiesta["+esisteRichiesta+"] risposta["+esisteRisposta+"] ...");
  530.                
  531.                 int i=0;
  532.                 while(!esisteRichiesta && !esisteRisposta && i<60){
  533.                     //System.out.println("@@incrementaNumeroDuplicati WHILE richiesta["+esisteRichiesta+"] risposta["+esisteRisposta+"]  SLEEP ...");
  534.                     // ATTENDI
  535.                     org.openspcoop2.utils.Utilities.sleep(1000);
  536.                     if(timeSleep==-1) {
  537.                         timeSleep=1000;
  538.                     }else {
  539.                         timeSleep = timeSleep + 1000;
  540.                     }
  541.                    
  542.                     i++;
  543.                    
  544.                     if(times!=null) {
  545.                         checkRequest = new TransazioniFiltroDuplicatiProcessTimes();
  546.                     }
  547.                     esisteRichiesta = esisteTransazione_query(protocolFactory,idBusta,null,con,protocolBustaBuilder,checkRequest);
  548.                     if(times!=null) {
  549.                         timeRequest = timeRequest + checkRequest.read;
  550.                     }
  551.                    
  552.                     if(!esisteRichiesta){
  553.                         if(times!=null) {
  554.                             checkResponse = new TransazioniFiltroDuplicatiProcessTimes();
  555.                         }
  556.                         esisteRisposta = esisteTransazione_query(protocolFactory,null,idBusta,con,protocolBustaBuilder,checkResponse);
  557.                         if(times!=null) {
  558.                             timeResponse = timeResponse + checkResponse.read;
  559.                         }
  560.                     }
  561.                     //System.out.println("@@incrementaNumeroDuplicati WHILE richiesta["+esisteRichiesta+"] risposta["+esisteRisposta+"]  SLEEP FINE ...");
  562.                 }
  563.             }finally {  
  564.                 if(times!=null) {
  565.                     times.checkExistsRequest = timeRequest;
  566.                     times.checkExistsResponse = timeResponse;
  567.                     times.checkSleep = timeSleep;
  568.                 }
  569.             }
  570.            
  571.             if(esisteRichiesta){
  572.                 incrementDuplicatiTransazione(protocolFactory,true, idBusta,
  573.                         con, protocolBustaBuilder, times);
  574.             }
  575.             else if(esisteRisposta){
  576.                 incrementDuplicatiTransazione(protocolFactory,false, idBusta,
  577.                         con, protocolBustaBuilder, times);
  578.             }
  579.             else{
  580.                 throw new ProtocolException("Precedente transazione con solito idBusta risulta in gestione da oltre 60 secondi");
  581.             }
  582.            
  583.            
  584.         }catch(Exception e){
  585.             throw new ProtocolException(e);
  586.         }
  587.         finally{
  588.             if(this.isDirectConnection==false){
  589.                 try{
  590.                     if(r!=null)
  591.                         dbManager.releaseResource(this.openspcoop2Properties.getIdentitaPortaDefault(protocolFactory.getProtocol(), this.requestInfo), idModulo, r);
  592.                 }catch(Exception eClose){}
  593.             }
  594.         }
  595.        
  596.     }
  597.    
  598.     private boolean esisteTransazione_query(IProtocolFactory<?> protocolFactory, String idBustaRichiesta,String idBustaRisposta,
  599.             Connection con, IBustaBuilder<?> protocolBustaBuilder, TransazioniFiltroDuplicatiProcessTimes times) throws ProtocolException {
  600.         PreparedStatement pstmt = null;
  601.         ResultSet rs = null;
  602.         try{
  603.            
  604.             long timeStart = -1;
  605.             try{
  606.                 if(times!=null) {
  607.                     timeStart = DateManager.getTimeMillis();
  608.                 }
  609.                 ISQLQueryObject sqlQueryObject = SQLObjectFactory.createSQLQueryObject(this.tipoDatabaseRuntime);
  610.                 if(this.openspcoop2Properties.isTransazioniFiltroDuplicatiTramiteTransazioniForceIndex()){
  611.                     if(this.openspcoop2Properties.isTransazioniFiltroDuplicatiSaveDateEnabled(protocolFactory)){
  612.                         //System.out.println("ADD FORCE INDEX esisteTransazione INDEX2");
  613.                         sqlQueryObject.addSelectForceIndex(this.nomeTabellaTransazioni, CostantiDB.TABLE_TRANSAZIONI_INDEX_FILTRO_REQ_2);
  614.                         sqlQueryObject.addSelectForceIndex(this.nomeTabellaTransazioni, CostantiDB.TABLE_TRANSAZIONI_INDEX_FILTRO_RES_2);
  615.                     }else{
  616.                         //System.out.println("ADD FORCE INDEX esisteTransazione INDEX1");
  617.                         sqlQueryObject.addSelectForceIndex(this.nomeTabellaTransazioni, CostantiDB.TABLE_TRANSAZIONI_INDEX_FILTRO_REQ_1);
  618.                         sqlQueryObject.addSelectForceIndex(this.nomeTabellaTransazioni, CostantiDB.TABLE_TRANSAZIONI_INDEX_FILTRO_RES_1);
  619.                     }
  620.                 }/*else{
  621.                     System.out.println("NON USO FORCE INDEX esisteTransazione");
  622.                 }*/
  623.                 sqlQueryObject.addFromTable(this.nomeTabellaTransazioni);
  624.                 if(idBustaRichiesta!=null){
  625.                     // Solo una porta applicativa puo' ricevere una busta di richiesta (serve per evitare i problemi in caso di loopback)
  626.                     if(this.openspcoop2Properties.isTransazioniFiltroDuplicatiSaveDateEnabled(protocolFactory)){
  627.                         sqlQueryObject.addWhereCondition(true,this.colonna_data_id_msg_richiesta+"=?",this.colonna_id_messaggio_richiesta+"=?",this.colonna_pdd_ruolo+"=?");    
  628.                     }
  629.                     else{
  630.                         sqlQueryObject.addWhereCondition(true,this.colonna_id_messaggio_richiesta+"=?",this.colonna_pdd_ruolo+"=?");    
  631.                     }
  632.                 }
  633.                 if(idBustaRisposta!=null){
  634.                      // Solo una porta delegata puo' ricevere una busta di risposta (serve per evitare i problemi in caso di loopback)
  635.                     if(this.openspcoop2Properties.isTransazioniFiltroDuplicatiSaveDateEnabled(protocolFactory)){
  636.                         sqlQueryObject.addWhereCondition(true,this.colonna_data_id_msg_risposta+"=?",this.colonna_id_messaggio_risposta+"=?",this.colonna_pdd_ruolo+"=?");
  637.                     }
  638.                     else{
  639.                         sqlQueryObject.addWhereCondition(true,this.colonna_id_messaggio_risposta+"=?",this.colonna_pdd_ruolo+"=?");
  640.                     }
  641.                 }
  642.                 sqlQueryObject.setANDLogicOperator(false); // OR
  643.                
  644.                 String sql = sqlQueryObject.createSQLQuery();
  645.                 pstmt = con.prepareStatement(sql);
  646.                 int index = 1;
  647.                 Timestamp t = null;
  648.                 if(idBustaRichiesta!=null){
  649.                     if(this.openspcoop2Properties.isTransazioniFiltroDuplicatiSaveDateEnabled(protocolFactory)){
  650.                         t = DateUtility.getTimestampIntoIdProtocollo(this.log,protocolBustaBuilder,idBustaRichiesta);
  651.                         if(t==null && (!this.useTransactionIdForTest)){
  652.                             throw new Exception("Estrazione data dall'id busta ["+idBustaRichiesta+"] non riuscita");
  653.                         }
  654.                         pstmt.setTimestamp(index++, t);
  655.                     }
  656.                     pstmt.setString(index++, idBustaRichiesta);
  657.                     pstmt.setString(index++, TipoPdD.APPLICATIVA.getTipo());
  658.                 }
  659.                 if(idBustaRisposta!=null){
  660.                     if(this.openspcoop2Properties.isTransazioniFiltroDuplicatiSaveDateEnabled(protocolFactory)){
  661.                         t = DateUtility.getTimestampIntoIdProtocollo(this.log,protocolBustaBuilder,idBustaRisposta);
  662.                         if(t==null && (!this.useTransactionIdForTest)){
  663.                             throw new Exception("Estrazione data dall'id busta ["+idBustaRisposta+"] non riuscita");
  664.                         }
  665.                         pstmt.setTimestamp(index++, t);
  666.                     }
  667.                     pstmt.setString(index++, idBustaRisposta);
  668.                     pstmt.setString(index++, TipoPdD.DELEGATA.getTipo());
  669.                 }
  670.                
  671.                 if(this.debug){
  672.                     SimpleDateFormat dateformat = null;
  673.                     if(this.openspcoop2Properties.isTransazioniFiltroDuplicatiSaveDateEnabled(protocolFactory) && t!=null){
  674.                         dateformat = DateUtils.getDefaultDateTimeFormatter("yyyy-MM-dd HH:mm");
  675.                     }
  676.                     if(idBustaRichiesta!=null){
  677.                         if(this.openspcoop2Properties.isTransazioniFiltroDuplicatiSaveDateEnabled(protocolFactory) && dateformat!=null){
  678.                             sql = sql.replaceFirst("\\?", "'"+dateformat.format(t)+"'");
  679.                         }
  680.                         sql = sql.replaceFirst("\\?", "'"+idBustaRichiesta+"'");
  681.                         sql = sql.replaceFirst("\\?", "'"+TipoPdD.APPLICATIVA.getTipo()+"'");
  682.                     }
  683.                     if(idBustaRisposta!=null){
  684.                         if(this.openspcoop2Properties.isTransazioniFiltroDuplicatiSaveDateEnabled(protocolFactory) && dateformat!=null){
  685.                             sql = sql.replaceFirst("\\?", "'"+dateformat.format(t)+"'");
  686.                         }
  687.                         sql = sql.replaceFirst("\\?", "'"+idBustaRisposta+"'");
  688.                         sql = sql.replaceFirst("\\?", "'"+TipoPdD.DELEGATA.getTipo()+"'");
  689.                     }
  690.                     this.logSql.debug("Eseguo query: "+sql);
  691.                 }
  692.                 //System.out.println("esisteTransazione SQL: "+sql);
  693.                
  694.                 rs = pstmt.executeQuery();
  695.                 if(rs.next()){
  696.                     if(this.debug){
  697.                         this.logSql.debug("Risultato query: "+true);
  698.                     }
  699.                     return true;
  700.                 }else{
  701.                     if(this.debug){
  702.                         this.logSql.debug("Risultato query: "+false);
  703.                     }
  704.                     return false;
  705.                 }
  706.             }finally {  
  707.                 if(times!=null) {
  708.                     long timeEnd =  DateManager.getTimeMillis();
  709.                     long timeProcess = timeEnd-timeStart;
  710.                     times.read = timeProcess;
  711.                 }
  712.             }
  713.            
  714.         }catch(Exception e){
  715.             throw new ProtocolException(e);
  716.         }
  717.         finally{
  718.             try{
  719.                 if(rs!=null)
  720.                     rs.close();
  721.             }catch(Exception eClose){}
  722.             try{
  723.                 if(pstmt!=null)
  724.                     pstmt.close();
  725.             }catch(Exception eClose){
  726.                 // close
  727.             }
  728.         }
  729.        
  730.     }
  731.    
  732.     private void incrementDuplicatiTransazione(IProtocolFactory<?> protocolFactory, boolean richiesta,String idBusta,
  733.             Connection con, IBustaBuilder<?> protocolBustaBuilder, TransazioniFiltroDuplicatiProcessTimes times) throws ProtocolException {
  734.         PreparedStatement pstmt = null;
  735.         try{
  736.            
  737.             if(idBusta==null){
  738.                 throw new ProtocolException("ID busta non fornito");
  739.             }
  740.            
  741.             long timeStart = -1;
  742.             try{
  743.                 if(times!=null) {
  744.                     timeStart = DateManager.getTimeMillis();
  745.                 }
  746.            
  747.                 ISQLQueryObject sqlQueryObject = SQLObjectFactory.createSQLQueryObject(this.tipoDatabaseRuntime);
  748.                 if(this.openspcoop2Properties.isTransazioniFiltroDuplicatiTramiteTransazioniForceIndex()){
  749.                     if(this.openspcoop2Properties.isTransazioniFiltroDuplicatiSaveDateEnabled(protocolFactory)){
  750.                         //  System.out.println("ADD FORCE INDEX esisteTransazione INDEX1");
  751.                         sqlQueryObject.addSelectForceIndex(this.nomeTabellaTransazioni, CostantiDB.TABLE_TRANSAZIONI_INDEX_FILTRO_REQ_2);
  752.                         sqlQueryObject.addSelectForceIndex(this.nomeTabellaTransazioni, CostantiDB.TABLE_TRANSAZIONI_INDEX_FILTRO_RES_2);
  753.                     }else{
  754.                         //  System.out.println("ADD FORCE INDEX esisteTransazione INDEX2");
  755.                         sqlQueryObject.addSelectForceIndex(this.nomeTabellaTransazioni, CostantiDB.TABLE_TRANSAZIONI_INDEX_FILTRO_REQ_1);
  756.                         sqlQueryObject.addSelectForceIndex(this.nomeTabellaTransazioni, CostantiDB.TABLE_TRANSAZIONI_INDEX_FILTRO_RES_1);
  757.                     }
  758.                 }
  759.                 sqlQueryObject.addUpdateTable(this.nomeTabellaTransazioni);
  760.                 if(richiesta){
  761.                     sqlQueryObject.addUpdateField(this.colonna_duplicati_richiesta, this.colonna_duplicati_richiesta+"+1");
  762.                     if(this.openspcoop2Properties.isTransazioniFiltroDuplicatiSaveDateEnabled(protocolFactory)){
  763.                         sqlQueryObject.addWhereCondition(this.colonna_data_id_msg_richiesta+"=?");
  764.                     }
  765.                     sqlQueryObject.addWhereCondition(this.colonna_id_messaggio_richiesta+"=?");
  766.                     sqlQueryObject.addWhereCondition(this.colonna_duplicati_richiesta+">=?");
  767.                     // Solo una porta applicativa puo' ricevere una busta di richiesta (serve per evitare i problemi in caso di loopback)
  768.                     sqlQueryObject.addWhereCondition(this.colonna_pdd_ruolo+"=?");  
  769.                 }
  770.                 else{
  771.                     sqlQueryObject.addUpdateField(this.colonna_duplicati_risposta, this.colonna_duplicati_risposta+"+1");
  772.                     if(this.openspcoop2Properties.isTransazioniFiltroDuplicatiSaveDateEnabled(protocolFactory)){
  773.                         sqlQueryObject.addWhereCondition(this.colonna_data_id_msg_risposta+"=?");
  774.                     }
  775.                     sqlQueryObject.addWhereCondition(this.colonna_id_messaggio_risposta+"=?");
  776.                     sqlQueryObject.addWhereCondition(this.colonna_duplicati_risposta+">=?");
  777.                     // Solo una porta delegata puo' ricevere una busta di risposta (serve per evitare i problemi in caso di loopback)
  778.                     sqlQueryObject.addWhereCondition(this.colonna_pdd_ruolo+"=?");  
  779.                 }
  780.                 sqlQueryObject.setANDLogicOperator(true);
  781.                
  782.                 Timestamp timestampId = DateUtility.getTimestampIntoIdProtocollo(this.log,protocolBustaBuilder,idBusta);
  783.                 if(timestampId==null && this.openspcoop2Properties.isTransazioniFiltroDuplicatiSaveDateEnabled(protocolFactory) && (!this.useTransactionIdForTest)){
  784.                     throw new Exception("Estrazione data dall'id busta ["+idBusta+"] non riuscita");
  785.                 }
  786.                
  787.                 String sql = sqlQueryObject.createSQLUpdate();
  788.                 //System.out.println("incrementDuplicatiTransazione SQL: "+sql);
  789.                 pstmt = con.prepareStatement(sql);
  790.                 int index = 1;
  791.                 if(this.openspcoop2Properties.isTransazioniFiltroDuplicatiSaveDateEnabled(protocolFactory)){
  792.                     pstmt.setTimestamp(index++, timestampId);
  793.                 }
  794.                 pstmt.setString(index++, idBusta);
  795.                 pstmt.setInt(index++, 0);
  796.                 if(richiesta){
  797.                     pstmt.setString(index++, TipoPdD.APPLICATIVA.getTipo());
  798.                 }
  799.                 else {
  800.                     pstmt.setString(index++, TipoPdD.DELEGATA.getTipo());
  801.                 }
  802.                
  803.                 if(this.debug){
  804.                     if(this.openspcoop2Properties.isTransazioniFiltroDuplicatiSaveDateEnabled(protocolFactory)){
  805.                         SimpleDateFormat dateformat = DateUtils.getDefaultDateTimeFormatter("yyyy-MM-dd HH:mm");
  806.                         sql = sql.replaceFirst("\\?", "'"+dateformat.format(timestampId)+"'");
  807.                     }
  808.                     if(idBusta!=null){
  809.                         sql = sql.replaceFirst("\\?", "'"+idBusta+"'");
  810.                     }
  811.                     sql = sql.replaceFirst("\\?", "0");
  812.                     if(richiesta){
  813.                         sql = sql.replaceFirst("\\?", "'"+TipoPdD.APPLICATIVA.getTipo()+"'");
  814.                     }
  815.                     else {
  816.                         sql = sql.replaceFirst("\\?", "'"+TipoPdD.DELEGATA.getTipo()+"'");
  817.                     }
  818.                     this.logSql.debug("Eseguo query: "+sql);
  819.                 }
  820.                
  821.                 int righeModificate = pstmt.executeUpdate();
  822.                 if(this.debug){
  823.                     this.logSql.debug("ID["+idBusta+"] richiesta["+richiesta+"] modificate righe: "+righeModificate);
  824.                 }
  825.                
  826.             }finally {  
  827.                 if(times!=null) {
  828.                     long timeEnd =  DateManager.getTimeMillis();
  829.                     long timeProcess = timeEnd-timeStart;
  830.                     times.update = timeProcess;
  831.                 }
  832.             }
  833.            
  834.         }catch(Exception e){
  835.             throw new ProtocolException(e);
  836.         }
  837.         finally{
  838.             try{
  839.                 if(pstmt!=null)
  840.                     pstmt.close();
  841.             }catch(Exception eClose){
  842.                 // close
  843.             }
  844.         }
  845.        
  846.     }
  847. }

  848. class TransazioniFiltroDuplicatiProcessTimes{

  849.     long getConnection = -1;
  850.     long read = -1;
  851.     long update = -1;
  852.     long checkExistsRequest = -1;
  853.     long checkExistsResponse = -1;
  854.     long checkSleep = -1;
  855.    
  856.     @Override
  857.     public String toString() {
  858.         StringBuilder sb = new StringBuilder();
  859.         if(this.getConnection>=0) {
  860.             if(sb.length()>0) {
  861.                 sb.append(" ");
  862.             }
  863.             sb.append("getConnection:").append(this.getConnection);
  864.         }
  865.         if(this.read>=0) {
  866.             if(sb.length()>0) {
  867.                 sb.append(" ");
  868.             }
  869.             sb.append("read:").append(this.read);
  870.         }
  871.         if(this.update>=0) {
  872.             if(sb.length()>0) {
  873.                 sb.append(" ");
  874.             }
  875.             sb.append("update:").append(this.update);
  876.         }
  877.         if(this.checkExistsRequest>=0) {
  878.             if(sb.length()>0) {
  879.                 sb.append(" ");
  880.             }
  881.             sb.append("checkExistsRequest:").append(this.checkExistsRequest);
  882.         }
  883.         if(this.checkExistsResponse>=0) {
  884.             if(sb.length()>0) {
  885.                 sb.append(" ");
  886.             }
  887.             sb.append("checkExistsResponse:").append(this.checkExistsResponse);
  888.         }
  889.         if(this.checkSleep>=0) {
  890.             if(sb.length()>0) {
  891.                 sb.append(" ");
  892.             }
  893.             sb.append("checkSleep:").append(this.checkSleep);
  894.         }
  895.         return sb.toString();
  896.     }
  897. }