TimerFileSystemRecoveryThread.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.core.commons.CoreException;
  25. import org.openspcoop2.core.commons.dao.DAOFactory;
  26. import org.openspcoop2.core.commons.dao.DAOFactoryProperties;
  27. import org.openspcoop2.core.config.OpenspcoopAppender;
  28. import org.openspcoop2.core.config.Property;
  29. import org.openspcoop2.core.config.utils.OpenSPCoopAppenderUtilities;
  30. import org.openspcoop2.generic_project.utils.ServiceManagerProperties;
  31. import org.openspcoop2.monitor.engine.fs_recovery.FSRecoveryConfig;
  32. import org.openspcoop2.monitor.engine.fs_recovery.FSRecoveryLibrary;
  33. import org.openspcoop2.pdd.config.DBTransazioniManager;
  34. import org.openspcoop2.pdd.config.OpenSPCoop2Properties;
  35. import org.openspcoop2.pdd.config.Resource;
  36. import org.openspcoop2.protocol.sdk.diagnostica.IDiagnosticProducer;
  37. import org.openspcoop2.protocol.sdk.dump.IDumpProducer;
  38. import org.openspcoop2.protocol.sdk.tracciamento.ITracciaProducer;
  39. import org.openspcoop2.utils.threads.BaseThread;
  40. import org.slf4j.Logger;


  41. /**    
  42.  * TimerFileSystemRecoveryThread
  43.  *
  44.  * @author Poli Andrea (poli@link.it)
  45.  * @author $Author$
  46.  * @version $Rev$, $Date$
  47.  */
  48. public class TimerFileSystemRecoveryThread extends BaseThread{

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

  57.     public static final String ID_MODULO = "TimerFileSystemRecovery";
  58.        
  59.     /** Logger utilizzato per debug. */
  60.     private Logger logCore = null;
  61.     private Logger logSql = null;
  62.    
  63.     /** Indicazione se deve essere effettuato il log delle query */
  64.     private boolean debug = false;  
  65.    
  66.     private boolean recoveryEventi;
  67.     private boolean recoveryTransazioni;
  68.    
  69.     private long recoveryEventiProcessingFileAfterMs;
  70.     private long recoveryTransazioniProcessingFileAfterMs;
  71.    
  72.     private OpenSPCoop2Properties properties;
  73.    
  74.     /** Database */
  75.     private String tipoDatabaseRuntime = null; //tipoDatabase
  76.     private DAOFactory daoFactory = null;
  77.     private Logger daoFactoryLogger = null;
  78.     private ServiceManagerProperties daoFactoryServiceManagerPropertiesTransazioni = null;
  79.     private ServiceManagerProperties daoFactoryServiceManagerPropertiesPluginsEventi = null;
  80.     /** OpenSPCoopAppender */
  81.     /** Appender personalizzati per i tracciamenti di OpenSPCoop */
  82.     private ITracciaProducer loggerTracciamentoOpenSPCoopAppender = null;
  83.     /** Appender personalizzati per i messaggi diagnostici di OpenSPCoop2 */
  84.     private IDiagnosticProducer loggerMsgDiagnosticoOpenSPCoopAppender = null;
  85.     /** Appender personalizzati per i dump di OpenSPCoop2 */
  86.     private IDumpProducer loggerDumpOpenSPCoopAppender = null;
  87.     private boolean transazioniRegistrazioneDumpHeadersCompactEnabled = false;

  88.     private static final String ID_TIMER = "__timerFileSystemRecovery";
  89.    
  90.     /** Costruttore
  91.      * @throws CoreException */
  92.     public TimerFileSystemRecoveryThread(Logger logCore, Logger logSql) throws TimerException, CoreException{
  93.    
  94.         this.properties = OpenSPCoop2Properties.getInstance();
  95.        
  96.         this.logCore = logCore;
  97.         this.logSql = logSql;
  98.    
  99.         this.setTimeout(this.properties.getFileSystemRecoveryTimerIntervalSeconds());
  100.        
  101.         this.debug = this.properties.isFileSystemRecoveryDebug();
  102.        
  103.         this.recoveryEventi = this.properties.isFileSystemRecoveryTimerEventEnabled();
  104.         this.recoveryTransazioni = this.properties.isFileSystemRecoveryTimerTransactionEnabled();
  105.        
  106.         this.recoveryEventiProcessingFileAfterMs = this.properties.getFileSystemRecoveryEventsProcessingFileAfterMs();
  107.         this.recoveryTransazioniProcessingFileAfterMs = this.properties.getFileSystemRecoveryTransactionProcessingFileAfterMs();
  108.        
  109.         DAOFactoryProperties daoFactoryProperties = null;
  110.         try{
  111.            
  112.             this.tipoDatabaseRuntime = this.properties.getDatabaseType();          
  113.             if(this.tipoDatabaseRuntime==null){
  114.                 throw new TimerException("Tipo Database non definito");
  115.             }

  116.             // DAOFactory
  117.             this.daoFactoryLogger = this.logSql;
  118.             this.daoFactory = DAOFactory.getInstance(this.daoFactoryLogger);
  119.             daoFactoryProperties = DAOFactoryProperties.getInstance(this.daoFactoryLogger);
  120.            
  121.             if(this.recoveryTransazioni){
  122.                 this.daoFactoryServiceManagerPropertiesTransazioni = daoFactoryProperties.getServiceManagerProperties(org.openspcoop2.core.transazioni.utils.ProjectInfo.getInstance());
  123.                 this.daoFactoryServiceManagerPropertiesTransazioni.setShowSql(this.debug);
  124.                 this.daoFactoryServiceManagerPropertiesTransazioni.setDatabaseType(DBTransazioniManager.getInstance().getTipoDatabase());
  125.             }
  126.                        
  127.             if(this.recoveryEventi){
  128.                 this.daoFactoryServiceManagerPropertiesPluginsEventi = daoFactoryProperties.getServiceManagerProperties(org.openspcoop2.core.eventi.utils.ProjectInfo.getInstance());
  129.                 this.daoFactoryServiceManagerPropertiesPluginsEventi.setShowSql(this.debug);
  130.                 this.daoFactoryServiceManagerPropertiesPluginsEventi.setDatabaseType(DBTransazioniManager.getInstance().getTipoDatabase());
  131.             }
  132.            
  133.         }catch(Exception e){
  134.             throw new TimerException("Errore durante l'inizializzazione del datasource: "+e.getMessage(),e);
  135.         }
  136.        
  137.         if(this.recoveryTransazioni){
  138.            
  139.             boolean usePdDConnection = true;
  140.            
  141.             try{
  142.                
  143.                 // Init
  144.                 this.loggerTracciamentoOpenSPCoopAppender = new org.openspcoop2.pdd.logger.TracciamentoOpenSPCoopProtocolAppender();
  145.                 OpenspcoopAppender tracciamentoOpenSPCoopAppender = new OpenspcoopAppender();
  146.                 tracciamentoOpenSPCoopAppender.setTipo(ID_TIMER);
  147.                 List<Property> tracciamentoOpenSPCoopAppenderProperties = new ArrayList<>();
  148.    
  149.                 // Verra poi utilizzata la connessione ottenuta ogni volta che il timer viene eseguito, infatti si usa usePdDConnection
  150.                 OpenSPCoopAppenderUtilities.addParameters(this.daoFactoryLogger, tracciamentoOpenSPCoopAppenderProperties,
  151.                         null, // nessun datasource
  152.                         null, null, null, null,  // nessuna connection
  153.                         this.tipoDatabaseRuntime,
  154.                         usePdDConnection, // viene usata la connessione della PdD
  155.                         this.debug
  156.                         );
  157.                 OpenSPCoopAppenderUtilities.addCheckProperties(tracciamentoOpenSPCoopAppenderProperties, false);
  158.    
  159.                 tracciamentoOpenSPCoopAppender.setPropertyList(tracciamentoOpenSPCoopAppenderProperties);
  160.                 this.loggerTracciamentoOpenSPCoopAppender.initializeAppender(tracciamentoOpenSPCoopAppender);
  161.                 this.loggerTracciamentoOpenSPCoopAppender.isAlive();
  162.                
  163.             }catch(Exception e){
  164.                 throw new TimerException("Errore durante l'inizializzazione del TracciamentoAppender: "+e.getMessage(),e);
  165.             }
  166.            
  167.             try{
  168.                
  169.                 // Init
  170.                 this.loggerMsgDiagnosticoOpenSPCoopAppender = new org.openspcoop2.pdd.logger.MsgDiagnosticoOpenSPCoopProtocolAppender();
  171.                 OpenspcoopAppender diagnosticoOpenSPCoopAppender = new OpenspcoopAppender();
  172.                 diagnosticoOpenSPCoopAppender.setTipo(ID_TIMER);
  173.                 List<Property> diagnosticoOpenSPCoopAppenderProperties = new ArrayList<>();
  174.    
  175.                 // Verra poi utilizzata la connessione ottenuta ogni volta che il timer viene eseguito, infatti si usa usePdDConnection
  176.                 OpenSPCoopAppenderUtilities.addParameters(this.daoFactoryLogger, diagnosticoOpenSPCoopAppenderProperties,
  177.                         null, // nessun datasource
  178.                         null, null, null, null,  // nessuna connection
  179.                         this.tipoDatabaseRuntime,
  180.                         usePdDConnection, // viene usata la connessione della PdD
  181.                         this.debug
  182.                         );
  183.                 OpenSPCoopAppenderUtilities.addCheckProperties(diagnosticoOpenSPCoopAppenderProperties, false);
  184.    
  185.                 diagnosticoOpenSPCoopAppender.setPropertyList(diagnosticoOpenSPCoopAppenderProperties);
  186.                 this.loggerMsgDiagnosticoOpenSPCoopAppender.initializeAppender(diagnosticoOpenSPCoopAppender);
  187.                 this.loggerMsgDiagnosticoOpenSPCoopAppender.isAlive();
  188.                
  189.             }catch(Exception e){
  190.                 throw new TimerException("Errore durante l'inizializzazione del DiagnosticoAppender: "+e.getMessage(),e);
  191.             }
  192.            
  193.             try{
  194.                
  195.                 // Init
  196.                 this.loggerDumpOpenSPCoopAppender = new org.openspcoop2.pdd.logger.DumpOpenSPCoopProtocolAppender();
  197.                 OpenspcoopAppender dumpOpenSPCoopAppender = new OpenspcoopAppender();
  198.                 dumpOpenSPCoopAppender.setTipo(ID_TIMER);
  199.                 List<Property> dumpOpenSPCoopAppenderProperties = new ArrayList<>();
  200.    
  201.                 // Verra poi utilizzata la connessione ottenuta ogni volta che il timer viene eseguito, infatti si usa usePdDConnection
  202.                 OpenSPCoopAppenderUtilities.addParameters(this.daoFactoryLogger, dumpOpenSPCoopAppenderProperties,
  203.                         null, // nessun datasource
  204.                         null, null, null, null,  // nessuna connection
  205.                         this.tipoDatabaseRuntime,
  206.                         usePdDConnection, // viene usata la connessione della PdD
  207.                         this.debug
  208.                         );
  209.                 OpenSPCoopAppenderUtilities.addCheckProperties(dumpOpenSPCoopAppenderProperties, false);
  210.    
  211.                 dumpOpenSPCoopAppender.setPropertyList(dumpOpenSPCoopAppenderProperties);
  212.                 this.loggerDumpOpenSPCoopAppender.initializeAppender(dumpOpenSPCoopAppender);
  213.                 this.loggerDumpOpenSPCoopAppender.isAlive();
  214.                
  215.                 // Indicazioni sulle modalita' di salvataggio degli header del dump
  216.                 this.transazioniRegistrazioneDumpHeadersCompactEnabled = this.properties.isTransazioniRegistrazioneDumpHeadersCompactEnabled();
  217.                
  218.             }catch(Exception e){
  219.                 throw new TimerException("Errore durante l'inizializzazione del DumpAppender: "+e.getMessage(),e);
  220.             }
  221.            
  222.         }
  223.     }
  224.    
  225.     private FSRecoveryConfig conf = null;
  226.    
  227.     @Override
  228.     public boolean initialize(){
  229.         try{
  230.             this.conf = new FSRecoveryConfig(false);
  231.            
  232.             this.conf.setLogCore(this.logCore);
  233.            
  234.             this.conf.setLogSql(this.logSql);
  235.            
  236.             this.conf.setDebug(this.debug);
  237.            
  238.             this.conf.setDefaultProtocol(this.properties.getDefaultProtocolName());
  239.            
  240.             this.conf.setRepository(this.properties.getFileSystemRecoveryRepository().getAbsolutePath());
  241.            
  242.             this.conf.setRipristinoEventi(this.recoveryEventi);
  243.            
  244.             this.conf.setRipristinoTransazioni(this.recoveryTransazioni);
  245.            
  246.             this.conf.setTentativi(this.properties.getFileSystemRecoveryMaxAttempts());
  247.            
  248.             this.conf.setProcessingEventFileAfterMs(this.recoveryEventiProcessingFileAfterMs);
  249.            
  250.             this.conf.setProcessingTransactionFileAfterMs(this.recoveryTransazioniProcessingFileAfterMs);
  251.            
  252.             return true;
  253.         }catch(Exception e){
  254.             this.logCore.error("Errore durante il recovery da file system (InitConfigurazione): "+e.getMessage(),e);
  255.             return false;
  256.         }
  257.     }
  258.    
  259.     @Override
  260.     public void process(){
  261.                
  262.         if(TimerState.ENABLED.equals(STATE)) {
  263.        
  264.             DBTransazioniManager dbManager = null;
  265.             Resource r = null;
  266.             try{
  267.                 dbManager = DBTransazioniManager.getInstance();
  268.                 r = dbManager.getResource(this.properties.getIdentitaPortaDefaultWithoutProtocol(), ID_MODULO, null);
  269.                 if(r==null){
  270.                     throw new Exception("Risorsa al database non disponibile");
  271.                 }
  272.                 Connection con = (Connection) r.getResource();
  273.                 if(con == null)
  274.                     throw new TimerException("Connessione non disponibile");    
  275.    
  276.                 org.openspcoop2.core.transazioni.dao.IServiceManager transazioniSM = null;
  277.                 if(this.recoveryTransazioni){
  278.                     transazioniSM = (org.openspcoop2.core.transazioni.dao.IServiceManager)
  279.                             this.daoFactory.getServiceManager(org.openspcoop2.core.transazioni.utils.ProjectInfo.getInstance(), con,
  280.                             this.daoFactoryServiceManagerPropertiesTransazioni, this.daoFactoryLogger);
  281.                 }

  282.                 org.openspcoop2.core.eventi.dao.IServiceManager pluginsSM = null;
  283.                 if(this.recoveryEventi){
  284.                     pluginsSM = (org.openspcoop2.core.eventi.dao.IServiceManager)
  285.                             this.daoFactory.getServiceManager(org.openspcoop2.core.eventi.utils.ProjectInfo.getInstance(), con,
  286.                             this.daoFactoryServiceManagerPropertiesPluginsEventi, this.daoFactoryLogger);
  287.                 }
  288.                                    
  289.                 FSRecoveryLibrary.generate(this.conf,
  290.                         this.daoFactory, this.daoFactoryLogger, this.daoFactoryServiceManagerPropertiesTransazioni,
  291.                         this.properties.getGestioneSerializableDBAttesaAttiva(), this.properties.getGestioneSerializableDBCheckInterval(),
  292.                         transazioniSM,
  293.                         this.loggerTracciamentoOpenSPCoopAppender,
  294.                         this.loggerMsgDiagnosticoOpenSPCoopAppender,
  295.                         this.loggerDumpOpenSPCoopAppender, this.transazioniRegistrazioneDumpHeadersCompactEnabled,
  296.                         pluginsSM, con);
  297.                
  298.             }catch(Exception e){
  299.                 this.logCore.error("Errore durante il recovery da file system: "+e.getMessage(),e);
  300.             }finally{
  301.                 try{
  302.                     if(r!=null)
  303.                         dbManager.releaseResource(this.properties.getIdentitaPortaDefaultWithoutProtocol(), ID_MODULO, r);
  304.                 }catch(Exception eClose){
  305.                     // ignore
  306.                 }
  307.             }
  308.            
  309.         }
  310.         else {
  311.             this.logCore.info("Timer "+ID_MODULO+" disabilitato");
  312.         }
  313.                
  314.     }
  315.    
  316.     @Override
  317.     public void close(){            
  318.            
  319.             this.logCore.info("Thread per il recovery da file system terminato");
  320.            
  321.     }
  322. }