TimerGestoreMessaggiImpl.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.util.Date;

  22. import javax.ejb.CreateException;
  23. import javax.ejb.EJBException;
  24. import javax.ejb.SessionBean;
  25. import javax.ejb.SessionContext;
  26. import javax.ejb.TimedObject;
  27. import javax.ejb.Timer;
  28. import javax.ejb.TimerService;

  29. import org.slf4j.Logger;
  30. import org.openspcoop2.pdd.config.OpenSPCoop2Properties;
  31. import org.openspcoop2.pdd.core.CostantiPdD;
  32. import org.openspcoop2.pdd.logger.MsgDiagnosticiProperties;
  33. import org.openspcoop2.pdd.logger.MsgDiagnostico;
  34. import org.openspcoop2.pdd.logger.OpenSPCoop2Logger;
  35. import org.openspcoop2.pdd.services.OpenSPCoop2Startup;
  36. import org.openspcoop2.utils.Semaphore;
  37. import org.openspcoop2.utils.SemaphoreLock;
  38. import org.openspcoop2.utils.Utilities;
  39. import org.openspcoop2.utils.date.DateManager;

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

  49. public class TimerGestoreMessaggiImpl implements SessionBean, TimedObject {

  50.      /**
  51.      * serialVersionUID
  52.      */
  53.     private static final long serialVersionUID = 1L;
  54.    
  55.     /* ******** F I E L D S P R I V A T I ******** */

  56.     /** Contesto */
  57.     private SessionContext sessionContext;
  58.     /** Timer associato a questo EJB */
  59.     private Timer timer;
  60.     /**
  61.      * Timeout che definisce la cadenza di avvio di questo timer.
  62.      */
  63.     private long timeout = 10; // ogni 10 secondi avvio il Thread
  64.     /**
  65.      * Timeout che definisce la scadenza di un messaggio
  66.      */
  67.     private long scadenzaMessaggio = 60l * 24l * 5l; // cablato a 5 giorni (60m * 24h * 5giorni).
  68.     /**
  69.      * Timeout che definisce la scadenza di una correlazione applicativa
  70.      */
  71.     private long scadenzaCorrelazioneApplicativa = 60l * 24l * 5l; // cablato a 5 giorni (60m * 24h * 5giorni).
  72.    
  73.     /** Properties Reader */
  74.     private OpenSPCoop2Properties propertiesReader;
  75.     /** MsgDiagnostico */
  76.     private MsgDiagnostico msgDiag;
  77.    
  78.     /** Logger utilizzato per debug. */
  79.     private Logger logTimer = null;

  80.     /** Indicazione se l'istanza in questione e' autoDeployata da JBoss o creata da OpenSPCoop */
  81.     private boolean deployFromOpenSPCoop = false;
  82.     /** Indicazione se la gestione e' attualmente in esecuzione */
  83.     private boolean gestioneAttiva = false;
  84.     /** Indicazione se deve essere effettuato il log delle query */
  85.     private boolean logQuery = false;
  86.     /** Numero di messaggi prelevati sulla singola query */
  87.     private int limit = CostantiPdD.LIMIT_MESSAGGI_GESTORI;
  88.     /** Indicazione se deve essere effettuato l'order by nelle query */
  89.     private boolean orderByQuery = false;
  90.     /** Indicazione se devono essere filtrate le correlazioni applicative scadute rispetto all'ora registrazione */
  91.     private boolean filtraCorrelazioniApplicativeScaduteRispettoOraRegistrazione = true;
  92.     /** Indicazione se devono essere filtrate le correlazioni applicative scadute rispetto all'ora registrazione, escludendo pero' quelle che hanno una scadenza impostata */
  93.     private boolean filtraCorrelazioniApplicativeScaduteRispettoOraRegistrazione_escludiCorrelazioniConScadenzaImpostata = false;


  94.    



  95.     /* ********  M E T O D I   ******** */

  96.     /**
  97.      * Viene chiamato in causa per istanziare il properties reader al primo
  98.      * utilizzo del thread che implementa l'EJBean definito in questa classe.
  99.      *
  100.      *
  101.      */
  102.     public void ejbCreate() throws CreateException {

  103.        
  104.         // Aspetto inizializzazione di OpenSPCoop (aspetto mezzo minuto e poi segnalo errore)
  105.         int attesa = 90;
  106.         int secondi = 0;
  107.         while( (OpenSPCoop2Startup.initialize==false) && (secondi<attesa) ){
  108.             Utilities.sleep(1000);
  109.             secondi++;
  110.         }
  111.         if(secondi>= 90){
  112.             throw new CreateException("Riscontrata inizializzazione OpenSPCoop non effettuata");
  113.         }  

  114.         this.logTimer = OpenSPCoop2Logger.getLoggerOpenSPCoopTimers();
  115.        
  116.         try {
  117.             this.msgDiag = MsgDiagnostico.newInstance(TimerGestoreMessaggi.ID_MODULO);
  118.             this.msgDiag.setPrefixMsgPersonalizzati(MsgDiagnosticiProperties.MSG_DIAG_TIMER_GESTORE_MESSAGGI);
  119.             this.msgDiag.addKeyword(CostantiPdD.KEY_TIMER_GESTORE_MESSAGGI, TimerGestoreMessaggi.ID_MODULO);
  120.         } catch (Exception e) {
  121.             String msgErrore = "Riscontrato Errore durante l'inizializzazione del MsgDiagnostico: "+e.getMessage();
  122.             this.logTimer.error(msgErrore,e);
  123.             throw new CreateException(msgErrore);
  124.         }

  125.         try {
  126.             this.propertiesReader = OpenSPCoop2Properties.getInstance();
  127.         } catch (Exception e) {
  128.             this.msgDiag.logErroreGenerico(e,"InizializzazioneProperties");
  129.             String msgErrore = "Riscontrato errore durante l'inizializzazione del Reader delle Properties di OpenSPCoop: "+e.getMessage();
  130.             this.logTimer.error(msgErrore,e);
  131.             throw new CreateException(msgErrore);
  132.         }

  133.         this.timeout = this.propertiesReader.getRepositoryIntervalloEliminazioneMessaggi();
  134.         String s = "secondi";
  135.         if(this.timeout == 1)
  136.             s = "secondo";
  137.         this.msgDiag.addKeyword(CostantiPdD.KEY_TIMEOUT, this.timeout+" "+s);
  138.        
  139.         this.scadenzaMessaggio = this.propertiesReader.getRepositoryIntervalloScadenzaMessaggi();
  140.         s = "minuti";
  141.         if(this.scadenzaMessaggio == 1)
  142.             s = "minuto";
  143.         this.msgDiag.addKeyword(CostantiPdD.KEY_SCADENZA_MESSAGGIO, this.scadenzaMessaggio+" "+s);
  144.        
  145.         this.logQuery = this.propertiesReader.isTimerGestoreMessaggiAbilitatoLog();
  146.         this.orderByQuery = this.propertiesReader.isTimerGestoreMessaggiAbilitatoOrderBy();
  147.        
  148.         this.limit = this.propertiesReader.getTimerGestoreMessaggiLimit();
  149.         if(this.limit<=0){
  150.             this.limit = CostantiPdD.LIMIT_MESSAGGI_GESTORI;
  151.         }
  152.         this.msgDiag.addKeyword(CostantiPdD.KEY_LIMIT, this.limit+"");
  153.        
  154.         this.scadenzaCorrelazioneApplicativa = this.propertiesReader.getRepositoryIntervalloScadenzaCorrelazioneApplicativa();
  155.         this.filtraCorrelazioniApplicativeScaduteRispettoOraRegistrazione = this.propertiesReader.isRepositoryScadenzaCorrelazioneApplicativaFiltraRispettoOraRegistrazione();
  156.         this.filtraCorrelazioniApplicativeScaduteRispettoOraRegistrazione_escludiCorrelazioniConScadenzaImpostata =
  157.                 this.propertiesReader.isRepositoryScadenzaCorrelazioneApplicativaFiltraRispettoOraRegistrazioneEscludiConScadenzaImpostata();

  158.     }

  159.     /**
  160.      * Metodo necessario per l'implementazione dell'interfaccia
  161.      * <code>SessionBean</code>.
  162.      *
  163.      *
  164.      */
  165.     @Override
  166.     public void ejbRemove() throws EJBException {
  167.     }

  168.     /**
  169.      * Metodo necessario per l'implementazione dell'interfaccia
  170.      * <code>SessionBean</code>.
  171.      *
  172.      *
  173.      */
  174.     @Override
  175.     public void ejbActivate() throws EJBException {
  176.     }

  177.     /**
  178.      * Metodo necessario per l'implementazione dell'interfaccia
  179.      * <code>SessionBean</code>.
  180.      *
  181.      *
  182.      */
  183.     @Override
  184.     public void ejbPassivate() throws EJBException {
  185.     }

  186.     private static Semaphore SEMAPHORE = new Semaphore(TimerGestoreMessaggi.ID_MODULO);
  187.     private static Boolean LOCK = false;
  188.    
  189.     /**
  190.      * Metodo necessario per l'implementazione dell'interfaccia
  191.      * <code>TimedObject</code>.
  192.      *
  193.      *
  194.      */
  195.     @Override
  196.     public void ejbTimeout(Timer timer) throws EJBException {

  197.         // Nelle nuove versioni, jboss avviava automaticamente un EJB Timer registrato. Questo comportamento, insieme
  198.         // al codice che avviava manualmente il timer in versione thread provocava un doppio avvio.
  199.         if(this.propertiesReader.isServerJ2EE()==false){
  200.             //System.out.println("GestoreMessaggi STOPPED");
  201.             stop(timer);
  202.             return;
  203.         }
  204.        
  205.         // Solo il thread avviato da OpenSPCoop deve essere eseguito
  206.         if( (this.deployFromOpenSPCoop == false)){
  207.             if(this.propertiesReader.isTimerAutoStart_StopTimer()){
  208.                 stop(timer);
  209.                 return;
  210.             }else{
  211.                 // Viene sempre richiamato ejbCreate() e quindi la variabile deployFromOpenSPCoop รจ sempre null.
  212.                 // La single instance viene gestiti quindi con un lock
  213.                 SemaphoreLock lock = SEMAPHORE.acquireThrowRuntime("ejbTimeout");
  214.                 try {
  215.                     if(LOCK){
  216.                         this.msgDiag.logPersonalizzato("precedenteEsecuzioneInCorso.stopTimer");
  217.                         this.logTimer.info(this.msgDiag.getMessaggio_replaceKeywords("precedenteEsecuzioneInCorso.stopTimer"));
  218.                         stop(timer);
  219.                         return;
  220.                     }
  221.                     else{
  222.                         LOCK = true;
  223.                        
  224.                         /**
  225.                          * Aggiungo una sleep di 5 secondi per far provocare il LOCK sopra presente, per le altre istanze di timer
  226.                          * in modo da avere solamente una istanza in esecuzione
  227.                          */
  228.                         for (int i = 0; i < 10; i++) {
  229.                             Utilities.sleep(500);
  230.                         }
  231.                     }
  232.                 }finally {
  233.                     SEMAPHORE.release(lock, "ejbTimeout");
  234.                 }
  235.             }
  236.         }
  237.        
  238.         try{
  239.            
  240.             // Controllo se OpenSPCoop desidera avviare il Timer
  241.             if(this.propertiesReader.isTimerGestoreMessaggiAbilitato()==false){
  242.                 this.msgDiag.logPersonalizzato("disabilitato");
  243.                 this.logTimer.warn(this.msgDiag.getMessaggio_replaceKeywords("disabilitato"));
  244.                 stop(timer);
  245.                 return;
  246.             }
  247.    
  248.             // Controllo che l'inizializzazione corretta delle risorse sia effettuata
  249.             if(timer == null){
  250.                 String msgErrore = "inizializzazione del Timer non effettuata";
  251.                 this.msgDiag.logFatalError(msgErrore, "Check inizializzazione");
  252.                 this.logTimer.error(msgErrore);
  253.                 stop(timer);
  254.                 return;
  255.             }
  256.             if(OpenSPCoop2Startup.initialize==false){
  257.                 String msgErrore = "inizializzazione di OpenSPCoop non effettuata";
  258.                 this.msgDiag.logFatalError(msgErrore, "Check inizializzazione");
  259.                 this.logTimer.error(msgErrore);
  260.                 stop(timer);
  261.                 return;
  262.             }
  263.            
  264.             if(this.gestioneAttiva){
  265.                 this.msgDiag.logPersonalizzato("precedenteEsecuzioneInCorso");
  266.                 this.logTimer.info(this.msgDiag.getMessaggio_replaceKeywords("precedenteEsecuzioneInCorso"));
  267.                 return;
  268.             }
  269.            
  270.             try{
  271.                 // Prendo la gestione
  272.                 this.gestioneAttiva = true;
  273.                 TimerGestoreMessaggiLib gestoreMessaggiLib =
  274.                     new TimerGestoreMessaggiLib(this.msgDiag,this.logTimer,this.propertiesReader,
  275.                         this.scadenzaMessaggio,this.logQuery,
  276.                         this.limit,this.orderByQuery,this.scadenzaCorrelazioneApplicativa,
  277.                         this.filtraCorrelazioniApplicativeScaduteRispettoOraRegistrazione,
  278.                         this.filtraCorrelazioniApplicativeScaduteRispettoOraRegistrazione_escludiCorrelazioniConScadenzaImpostata);
  279.                
  280.                 gestoreMessaggiLib.check();
  281.                
  282.             }catch(Exception e){
  283.                 this.msgDiag.logErroreGenerico(e,"GestioneMessaggiTimerEJB");
  284.                 this.logTimer.error("Errore generale: "+e.getMessage(),e);
  285.             }finally{
  286.                 // Rilascio la gestione
  287.                 this.gestioneAttiva = false;
  288.             }
  289.            
  290.         }finally{
  291.             SemaphoreLock lock = SEMAPHORE.acquireThrowRuntime("ejbTimeoutCheck2");
  292.             try {
  293.                 LOCK = false;
  294.             }finally {
  295.                 SEMAPHORE.release(lock, "ejbTimeoutCheck2");
  296.             }
  297.         }
  298.        

  299.     }

  300.     /**
  301.      * Imposta il Contesto del Session Bean. Metodo necessario per
  302.      * l'implementazione dell'interfaccia <code>SessionBean</code>.
  303.      *
  304.      * @param aContext
  305.      *            Contesto del Session Bean.
  306.      *
  307.      */
  308.     @Override
  309.     public void setSessionContext(SessionContext aContext) throws EJBException {
  310.         this.sessionContext = aContext;
  311.     }

  312.     /**
  313.      * Inizializza il Timer di gestione
  314.      *
  315.      *
  316.      */
  317.     public boolean start() throws EJBException {
  318.         if( this.timer != null ){

  319.             this.msgDiag.logPersonalizzato("timerGiaAvviato");
  320.             this.logTimer.info(this.msgDiag.getMessaggio_replaceKeywords("timerGiaAvviato"));
  321.             return false;

  322.         } else {

  323.             if(this.propertiesReader.isTimerGestoreMessaggiAbilitato()){
  324.                
  325.                 this.deployFromOpenSPCoop = true;      
  326.                 this.msgDiag.logPersonalizzato("avvioInCorso");
  327.                 this.logTimer.info(this.msgDiag.getMessaggio_replaceKeywords("avvioInCorso"));
  328.                 Utilities.sleep(1000); // tempo necessario per un corretto avvio in JBoss 4.0.3...
  329.                 Date now = DateManager.getDate();
  330.                 long timeout = 1000 * this.timeout;
  331.                 try {
  332.                     // creo il timer
  333.                     TimerService ts = this.sessionContext.getTimerService();
  334.                     this.timer = ts.createTimer(now, timeout, TimerGestoreMessaggi.ID_MODULO);
  335.                     this.msgDiag.logPersonalizzato("avvioEffettuato");
  336.                     this.logTimer.info(this.msgDiag.getMessaggio_replaceKeywords("avvioEffettuato"));
  337.                 } catch (Exception e) {
  338.                     stop();
  339.                     this.msgDiag.logFatalError(e, "Creazione timer EJB gestore dei messaggi");
  340.                     this.logTimer.error("Errore durante la creazione del timer: "+e.getMessage(),e);
  341.                 }
  342.                 return this.timer != null;
  343.        
  344.             }else{
  345.                
  346.                 this.msgDiag.logPersonalizzato("disabilitato");
  347.                 this.logTimer.warn(this.msgDiag.getMessaggio_replaceKeywords("disabilitato"));
  348.                 return false;
  349.                
  350.             }
  351.         }
  352.     }

  353.     /**
  354.      * Restituisce lo stato del timer di gestione
  355.      *
  356.      *
  357.      */
  358.     public boolean isStarted() throws EJBException {
  359.         return this.timer != null;
  360.     }

  361.     /**
  362.      * Annulla il timer di gestione
  363.      *
  364.      *
  365.      */
  366.     public void stop(Timer atimer) throws EJBException {
  367.         if (atimer != null) {
  368.             atimer.cancel();
  369.         }
  370.     }

  371.     /**
  372.      * Annulla il timer di gestione interno
  373.      *
  374.      *
  375.      */
  376.     public void stop() throws EJBException {
  377.         if (this.timer != null) {
  378.             this.timer.cancel();
  379.             this.timer = null;
  380.         }
  381.     }

  382. }