TimerGestorePuliziaMessaggiAnomaliLib.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.timers;

  21. import java.sql.Connection;
  22. import java.util.ArrayList;
  23. import java.util.List;

  24. import org.openspcoop2.pdd.config.OpenSPCoop2Properties;
  25. import org.openspcoop2.pdd.core.CostantiPdD;
  26. import org.openspcoop2.pdd.core.GestoreMessaggi;
  27. import org.openspcoop2.pdd.core.state.OpenSPCoopStateful;
  28. import org.openspcoop2.pdd.logger.MsgDiagnostico;
  29. import org.openspcoop2.pdd.services.OpenSPCoop2Startup;
  30. import org.openspcoop2.protocol.engine.constants.Costanti;
  31. import org.openspcoop2.protocol.engine.driver.RollbackRepositoryBuste;
  32. import org.openspcoop2.protocol.sdk.state.StateMessage;
  33. import org.openspcoop2.utils.TipiDatabase;
  34. import org.openspcoop2.utils.Utilities;
  35. import org.openspcoop2.utils.date.DateManager;
  36. import org.openspcoop2.utils.id.serial.InfoStatistics;
  37. import org.openspcoop2.utils.semaphore.Semaphore;
  38. import org.openspcoop2.utils.semaphore.SemaphoreConfiguration;
  39. import org.openspcoop2.utils.semaphore.SemaphoreMapping;
  40. import org.slf4j.Logger;

  41. /**
  42.  * Implementazione dell'interfaccia {@link TimerGestorePuliziaMessaggiAnomali} del Gestore
  43.  * dei threads di servizio di OpenSPCoop.
  44.  *
  45.  *  
  46.  * @author Poli Andrea (apoli@link.it)
  47.  * @author $Author$
  48.  * @version $Rev$, $Date$
  49.  */

  50. public class TimerGestorePuliziaMessaggiAnomaliLib{

  51.     private static TimerState STATE = TimerState.OFF; // abilitato in OpenSPCoop2Startup al momento dell'avvio
  52.    
  53.     public static TimerState getSTATE() {
  54.         return STATE;
  55.     }
  56.     public static void setSTATE(TimerState sTATE) {
  57.         STATE = sTATE;
  58.     }

  59.     private MsgDiagnostico msgDiag = null;
  60.     private Logger logTimer = null;
  61.     private OpenSPCoop2Properties propertiesReader = null;
  62.     private boolean logQuery = false;
  63.     private int limit = CostantiPdD.LIMIT_MESSAGGI_GESTORI;
  64.     private boolean orderByQuery;

  65.     private TimerLock timerLock = null;

  66.     /** Semaforo */
  67.     private Semaphore semaphore = null;
  68.     private InfoStatistics semaphore_statistics;

  69.     public TimerGestorePuliziaMessaggiAnomaliLib(MsgDiagnostico msgDiag,Logger log,OpenSPCoop2Properties p,boolean logQuery,
  70.             int limit,boolean orderByQuery) throws TimerException{
  71.         this.msgDiag = msgDiag;
  72.         this.logTimer = log;
  73.         this.propertiesReader = p;
  74.         this.logQuery = logQuery;
  75.         this.limit = limit;
  76.         this.orderByQuery = orderByQuery;
  77.        
  78.         this.timerLock = new TimerLock(TipoLock.GESTIONE_PULIZIA_MESSAGGI_ANOMALI);

  79.         if(this.propertiesReader.isTimerLockByDatabase()) {
  80.             this.semaphore_statistics = new InfoStatistics();

  81.             SemaphoreConfiguration config = GestoreMessaggi.newSemaphoreConfiguration(this.propertiesReader.getTimerGestorePuliziaMessaggiAnomaliLockMaxLife(),
  82.                     this.propertiesReader.getTimerGestorePuliziaMessaggiAnomaliLockIdleTime());

  83.             TipiDatabase databaseType = TipiDatabase.toEnumConstant(this.propertiesReader.getDatabaseType());
  84.             try {
  85.                 this.semaphore = new Semaphore(this.semaphore_statistics, SemaphoreMapping.newInstance(this.timerLock.getIdLock()),
  86.                         config, databaseType, this.logTimer);
  87.             }catch(Exception e) {
  88.                 throw new TimerException(e.getMessage(),e);
  89.             }
  90.         }
  91.     }

  92.     public void check() throws TimerException {

  93.         // Controllo che il sistema non sia andando in shutdown
  94.         if(OpenSPCoop2Startup.contextDestroyed){
  95.             this.logTimer.error("["+TimerGestorePuliziaMessaggiAnomali.ID_MODULO+"] Rilevato sistema in shutdown");
  96.             return;
  97.         }

  98.         // Controllo che l'inizializzazione corretta delle risorse sia effettuata
  99.         if(!OpenSPCoop2Startup.initialize){
  100.             this.msgDiag.logFatalError("inizializzazione di OpenSPCoop non effettuata", "Check Inizializzazione");
  101.             String msgErrore = "Riscontrato errore: inizializzazione del Timer o di OpenSPCoop non effettuata";
  102.             this.logTimer.error(msgErrore);
  103.             throw new TimerException(msgErrore);
  104.         }

  105.         // Controllo risorse di sistema disponibili
  106.         if( !TimerMonitoraggioRisorseThread.isRisorseDisponibili()){
  107.             this.logTimer.error("["+TimerGestorePuliziaMessaggiAnomali.ID_MODULO+"] Risorse di sistema non disponibili: "+TimerMonitoraggioRisorseThread.getRisorsaNonDisponibile().getMessage(),TimerMonitoraggioRisorseThread.getRisorsaNonDisponibile());
  108.             return;
  109.         }
  110.         if( !MsgDiagnostico.gestoreDiagnosticaDisponibile){
  111.             this.logTimer.error("["+TimerGestorePuliziaMessaggiAnomali.ID_MODULO+"] Sistema di diagnostica non disponibile: "+MsgDiagnostico.motivoMalfunzionamentoDiagnostici.getMessage(),MsgDiagnostico.motivoMalfunzionamentoDiagnostici);
  112.             return;
  113.         }
  114.        
  115.         // Controllo che il timer non sia stato momentaneamente disabilitato
  116.         if(!TimerState.ENABLED.equals(STATE)) {
  117.             this.msgDiag.logPersonalizzato("disabilitato");
  118.             this.logTimer.info(this.msgDiag.getMessaggio_replaceKeywords("disabilitato"));
  119.             return;
  120.         }


  121.         this.msgDiag.logPersonalizzato("controlloInCorso");
  122.         this.logTimer.info(this.msgDiag.getMessaggio_replaceKeywords("controlloInCorso"));
  123.         long startControlloRepositoryMessaggi = DateManager.getTimeMillis();


  124.         RollbackRepositoryBuste rollbackMessaggio = null;

  125.         OpenSPCoopStateful openspcoopstate = new OpenSPCoopStateful();

  126.         try {

  127.             openspcoopstate.initResource(this.propertiesReader.getIdentitaPortaDefaultWithoutProtocol(), TimerGestorePuliziaMessaggiAnomali.ID_MODULO, null);
  128.             Connection connectionDB = ((StateMessage)openspcoopstate.getStatoRichiesta()).getConnectionDB();
  129.            

  130.             // Messaggi da eliminare
  131.             GestoreMessaggi gestoreMsgSearch = new GestoreMessaggi(openspcoopstate, true,this.logTimer, this.msgDiag,null);
  132.             String causaMessaggiDaRipulire = "Eliminazione buste non più riferite da messaggi";
  133.             List<String> busteInutiliINBOX = null;
  134.             List<String> busteInutiliOUTBOX = null;
  135.             try{
  136.                 GestoreMessaggi.acquireLock(
  137.                         this.semaphore, connectionDB, this.timerLock,
  138.                         this.msgDiag, causaMessaggiDaRipulire,
  139.                         this.propertiesReader.getTimerGestorePuliziaMessaggiAnomali_getLockAttesaAttiva(),
  140.                         this.propertiesReader.getTimerGestorePuliziaMessaggiAnomali_getLockCheckInterval());
  141.                
  142.                 busteInutiliINBOX = gestoreMsgSearch.readBusteNonRiferiteDaMessaggiFromInBox(this.limit,this.logQuery,
  143.                         this.propertiesReader.isForceIndex(),this.orderByQuery);
  144.                 busteInutiliOUTBOX = gestoreMsgSearch.readBusteNonRiferiteDaMessaggiFromOutBox(this.limit,this.logQuery,
  145.                         this.propertiesReader.isForceIndex(),this.orderByQuery);
  146.    
  147.                 if(this.logQuery){
  148.                     if( ! (busteInutiliINBOX.size()>0 ||   busteInutiliOUTBOX.size() > 0)){
  149.                         this.logTimer.info("Non sono stati trovati messaggi anomali");
  150.                     }
  151.                 }
  152.    
  153.    
  154.                 while( busteInutiliINBOX.size()>0 ||
  155.                         busteInutiliOUTBOX.size() > 0){
  156.    
  157.                     this.msgDiag.addKeyword(CostantiPdD.KEY_TIMER_GESTORE_MESSAGGI_INCONSISTENTI_NUM_MSG_INBOX, busteInutiliINBOX.size()+"");
  158.                     this.msgDiag.addKeyword(CostantiPdD.KEY_TIMER_GESTORE_MESSAGGI_INCONSISTENTI_NUM_MSG_OUTBOX, busteInutiliOUTBOX.size()+"");
  159.    
  160.                     this.msgDiag.logPersonalizzato("ricercaMessaggiDaEliminare");
  161.    
  162.    
  163.                     // Buste non piu' riferite da messaggi
  164.                     // Eliminazione Messaggi from INBOX
  165.                     if(this.logQuery)
  166.                         this.logTimer.info("Trovate "+busteInutiliINBOX.size()+" buste non piu' riferita da messaggi da eliminare (INBOX) ...");
  167.                     this.msgDiag.addKeyword(CostantiPdD.KEY_TIPO_MESSAGGIO,Costanti.INBOX);
  168.                     for(int i=0; i<busteInutiliINBOX.size(); i++){
  169.    
  170.                         String idMsgDaEliminare = busteInutiliINBOX.get(i);
  171.                         this.msgDiag.addKeyword(CostantiPdD.KEY_ID_MESSAGGIO_DA_ELIMINARE,idMsgDaEliminare);
  172.    
  173.                         try{
  174.                             GestoreMessaggi.updateLock(
  175.                                     this.semaphore, connectionDB, this.timerLock,
  176.                                     this.msgDiag, "Eliminazione busta anomala in INBOX con id ["+idMsgDaEliminare+"] ...");
  177.                         }catch(Throwable e){
  178.                             this.msgDiag.logErroreGenerico(e,"EliminazioneBustaInbox("+idMsgDaEliminare+")-UpdateLock");
  179.                             this.logTimer.error("ErroreEliminazioneBustaInbox("+idMsgDaEliminare+")-UpdateLock: "+e.getMessage(),e);
  180.                             break;
  181.                         }
  182.                        
  183.                         try{
  184.                             //  rollback messaggio scaduto (eventuale profilo + accesso_pdd)
  185.                             rollbackMessaggio = new RollbackRepositoryBuste(idMsgDaEliminare,openspcoopstate.getStatoRichiesta(),true);
  186.                             rollbackMessaggio.rollbackBustaIntoInBox(false); //l'history viene eliminato con la scadenza della busta
  187.                             ((StateMessage)openspcoopstate.getStatoRichiesta()).executePreparedStatement();
  188.    
  189.                             this.msgDiag.logPersonalizzato("eliminazioneMessaggio");
  190.                             if(this.logQuery){
  191.                                 this.logTimer.debug(this.msgDiag.getMessaggio_replaceKeywords("eliminazioneMessaggio"));
  192.                             }
  193.    
  194.                         }catch(Exception e){
  195.                             if(rollbackMessaggio!=null){
  196.                                 ((StateMessage)openspcoopstate.getStatoRichiesta()).closePreparedStatement();
  197.                                 rollbackMessaggio = null;
  198.                             }
  199.                             this.msgDiag.logErroreGenerico(e,"EliminazioneBustaInbox("+idMsgDaEliminare+")");
  200.                             this.logTimer.error("ErroreEliminazioneBustaInbox("+idMsgDaEliminare+"): "+e.getMessage(),e);
  201.                         }
  202.                     }
  203.                     if(this.logQuery)
  204.                         this.logTimer.info("Eliminate "+busteInutiliINBOX.size()+" buste non piu' riferita da messaggi (INBOX)");
  205.    
  206.    
  207.                     // Buste non piu' riferite da messaggi
  208.                     // Eliminazione Messaggi from OUTBOX
  209.                     if(this.logQuery)
  210.                         this.logTimer.info("Trovate "+busteInutiliOUTBOX.size()+" buste non piu' riferita da messaggi da eliminare (OUTBOX) ...");
  211.                     this.msgDiag.addKeyword(CostantiPdD.KEY_TIPO_MESSAGGIO,Costanti.OUTBOX);
  212.                     for(int i=0; i<busteInutiliOUTBOX.size(); i++){
  213.    
  214.                         String idMsgDaEliminare = busteInutiliOUTBOX.get(i);
  215.                         this.msgDiag.addKeyword(CostantiPdD.KEY_ID_MESSAGGIO_DA_ELIMINARE,idMsgDaEliminare);
  216.    
  217.                         try{
  218.                             GestoreMessaggi.updateLock(
  219.                                     this.semaphore, connectionDB, this.timerLock,
  220.                                     this.msgDiag, "Eliminazione busta anomala in OUTBOX con id ["+idMsgDaEliminare+"] ...");
  221.                         }catch(Throwable e){
  222.                             this.msgDiag.logErroreGenerico(e,"EliminazioneBustaOutbox("+idMsgDaEliminare+")-UpdateLock");
  223.                             this.logTimer.error("EliminazioneBustaOutbox("+idMsgDaEliminare+")-UpdateLock: "+e.getMessage(),e);
  224.                             break;
  225.                         }
  226.                        
  227.                         try{
  228.                             //  rollback messaggio scaduto (eventuale profilo + accesso_pdd)
  229.                             rollbackMessaggio = new RollbackRepositoryBuste(idMsgDaEliminare,openspcoopstate.getStatoRichiesta(),true);
  230.                             rollbackMessaggio.rollbackBustaIntoOutBox(false); //l'history viene eliminato con la scadenza della busta
  231.                             ((StateMessage)openspcoopstate.getStatoRichiesta()).executePreparedStatement();
  232.    
  233.                             this.msgDiag.logPersonalizzato("eliminazioneMessaggio");
  234.                             if(this.logQuery){
  235.                                 this.logTimer.debug(this.msgDiag.getMessaggio_replaceKeywords("eliminazioneMessaggio"));
  236.                             }
  237.    
  238.                         }catch(Exception e){
  239.                             if(rollbackMessaggio!=null){
  240.                                 ((StateMessage)openspcoopstate.getStatoRichiesta()).closePreparedStatement();
  241.                                 rollbackMessaggio = null;
  242.                             }
  243.                             this.msgDiag.logErroreGenerico(e,"EliminazioneBustaOutbox("+idMsgDaEliminare+")");
  244.                             this.logTimer.error("EliminazioneBustaOutbox("+idMsgDaEliminare+"): "+e.getMessage(),e);
  245.                         }
  246.                     }
  247.                     if(this.logQuery)
  248.                         this.logTimer.info("Eliminate "+busteInutiliOUTBOX.size()+" buste non piu' riferita da messaggi (OUTBOX)");
  249.    
  250.                     boolean cerca = true;
  251.                     try{
  252.                         GestoreMessaggi.updateLock(
  253.                                 this.semaphore, connectionDB, this.timerLock,
  254.                                 this.msgDiag, "Ricerca nuove buste non più riferite da messaggi ...");                      
  255.                     }catch(Throwable e){
  256.                         this.msgDiag.logErroreGenerico(e,"RicercaNuoveBusteOneWayNonRiscontrate-UpdateLock");
  257.                         this.logTimer.error("ErroreRicercaNuoveBusteOneWayNonRiscontrate-UpdateLock: "+e.getMessage(),e);
  258.                         cerca = false;
  259.                     }
  260.                    
  261.                     // Check altri riscontri da inviare
  262.                     if(cerca) {
  263.                         // Check altri messaggi da eliminare
  264.                         busteInutiliINBOX = gestoreMsgSearch.readBusteNonRiferiteDaMessaggiFromInBox(this.limit,this.logQuery,
  265.                                 this.propertiesReader.isForceIndex(),this.orderByQuery);
  266.                         busteInutiliOUTBOX = gestoreMsgSearch.readBusteNonRiferiteDaMessaggiFromOutBox(this.limit,this.logQuery,
  267.                                 this.propertiesReader.isForceIndex(),this.orderByQuery);
  268.                     }
  269.                     else {
  270.                         busteInutiliINBOX = new ArrayList<>(); // per uscire dal while
  271.                         busteInutiliOUTBOX = new ArrayList<>(); // per uscire dal while
  272.                     }
  273.    
  274.                 }
  275.             }finally{
  276.                 try{
  277.                     GestoreMessaggi.releaseLock(
  278.                             this.semaphore, connectionDB, this.timerLock,
  279.                             this.msgDiag, causaMessaggiDaRipulire);
  280.                 }catch(Exception e){
  281.                     // ignore
  282.                 }
  283.             }
  284.                

  285.             // end
  286.             long endControlloRepositoryMessaggi = DateManager.getTimeMillis();
  287.             long diff = (endControlloRepositoryMessaggi-startControlloRepositoryMessaggi);
  288.             this.logTimer.info("Pulizia Messaggi Anomali terminata in "+Utilities.convertSystemTimeIntoStringMillisecondi(diff, true));

  289.         }
  290.         catch(TimerLockNotAvailableException t) {
  291.             // msg diagnostico emesso durante l'emissione dell'eccezione
  292.             this.logTimer.info(t.getMessage(),t);
  293.         }
  294.         catch (Exception e) {
  295.             this.msgDiag.logErroreGenerico(e,"GestioneMessaggiInconsistenti");
  296.             this.logTimer.error("Riscontrato errore durante la pulizia dei messaggi anomali: "+e.getMessage(),e);
  297.         }finally{
  298.             if(openspcoopstate!=null)
  299.                 openspcoopstate.releaseResource();
  300.         }
  301.     }

  302. }