TimerGestoreRepositoryBusteImpl.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 TimerGestoreRepositoryBuste} 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 TimerGestoreRepositoryBusteImpl 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 = 10l; // 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.     /** Properties Reader */
  69.     private OpenSPCoop2Properties propertiesReader;
  70.     /** MsgDiagnostico */
  71.     private MsgDiagnostico msgDiag;
  72.     /** Logger */
  73.     private Logger logTimer;

  74.     /** Indicazione se l'istanza in questione e' autoDeployata da JBoss o creata da OpenSPCoop */
  75.     private boolean deployFromOpenSPCoop = false;
  76.     /** Indicazione se la gestione e' attualmente in esecuzione */
  77.     private boolean gestioneAttiva = false;
  78.     /** Indicazione se deve essere effettuato il log delle query */
  79.     private boolean logQuery = false;
  80.     /** Numero di messaggi prelevati sulla singola query */
  81.     private int limit = CostantiPdD.LIMIT_MESSAGGI_GESTORI;
  82.     /** Indicazione se deve essere effettuato l'order by nelle query */
  83.     private boolean orderByQuery = false;


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

  85.     /**
  86.      * Viene chiamato in causa per istanziare il properties reader al primo
  87.      * utilizzo del thread che implementa l'EJBean definito in questa classe.
  88.      *
  89.      *
  90.      */
  91.     public void ejbCreate() throws CreateException {


  92.         // Aspetto inizializzazione di OpenSPCoop (aspetto mezzo minuto e poi segnalo errore)
  93.         int attesa = 90;
  94.         int secondi = 0;
  95.         while( (OpenSPCoop2Startup.initialize==false) && (secondi<attesa) ){
  96.             Utilities.sleep(1000);
  97.             secondi++;
  98.         }
  99.         if(secondi>= 90){
  100.             throw new CreateException("Riscontrata inizializzazione OpenSPCoop non effettuata");
  101.         }  

  102.         this.logTimer = OpenSPCoop2Logger.getLoggerOpenSPCoopTimers();
  103.        
  104.         try {
  105.             this.msgDiag = MsgDiagnostico.newInstance(TimerGestoreRepositoryBuste.ID_MODULO);
  106.             this.msgDiag.setPrefixMsgPersonalizzati(MsgDiagnosticiProperties.MSG_DIAG_TIMER_GESTORE_REPOSITORY_BUSTE);
  107.             this.msgDiag.addKeyword(CostantiPdD.KEY_TIMER_GESTORE_REPOSITORY_BUSTE, TimerGestoreRepositoryBuste.ID_MODULO);
  108.         } catch (Exception e) {
  109.             String msgErrore = "Riscontrato Errore durante l'inizializzazione del MsgDiagnostico: "+e.getMessage();
  110.             this.logTimer.error(msgErrore,e);
  111.             throw new CreateException(msgErrore);
  112.         }

  113.         try {
  114.             this.propertiesReader = OpenSPCoop2Properties.getInstance();
  115.         } catch (Exception e) {
  116.             this.msgDiag.logErroreGenerico(e,"InizializzazioneProperties");
  117.             String msgErrore = "Riscontrato errore durante l'inizializzazione del Reader delle Properties di OpenSPCoop: "+e.getMessage();
  118.             this.logTimer.error(msgErrore,e);
  119.             throw new CreateException(msgErrore);
  120.         }

  121.         this.timeout = this.propertiesReader.getRepositoryIntervalloEliminazioneMessaggi();
  122.         String sec = "secondi";
  123.         if(this.timeout == 1)
  124.             sec = "secondo";
  125.         this.msgDiag.addKeyword(CostantiPdD.KEY_TIMEOUT, this.timeout+" "+sec);
  126.        
  127.         this.scadenzaMessaggio = this.propertiesReader.getRepositoryIntervalloScadenzaMessaggi();
  128.         String s = "minuti";
  129.         if(this.scadenzaMessaggio == 1)
  130.             s = "minuto";
  131.         this.msgDiag.addKeyword(CostantiPdD.KEY_SCADENZA_MESSAGGIO, this.scadenzaMessaggio+" "+s);
  132.        
  133.         this.logQuery = this.propertiesReader.isTimerGestoreRepositoryBusteAbilitatoLog();
  134.         this.orderByQuery = this.propertiesReader.isTimerGestoreRepositoryBusteAbilitatoOrderBy();
  135.        
  136.         this.limit = this.propertiesReader.getTimerGestoreRepositoryBusteLimit();
  137.         if(this.limit<=0){
  138.             this.limit = CostantiPdD.LIMIT_MESSAGGI_GESTORI;
  139.         }
  140.         this.msgDiag.addKeyword(CostantiPdD.KEY_LIMIT, this.limit+"");
  141.        
  142.     }

  143.     /**
  144.      * Metodo necessario per l'implementazione dell'interfaccia
  145.      * <code>SessionBean</code>.
  146.      *
  147.      *
  148.      */
  149.     @Override
  150.     public void ejbRemove() throws EJBException {
  151.     }

  152.     /**
  153.      * Metodo necessario per l'implementazione dell'interfaccia
  154.      * <code>SessionBean</code>.
  155.      *
  156.      *
  157.      */
  158.     @Override
  159.     public void ejbActivate() throws EJBException {
  160.     }

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

  170.     private static Semaphore SEMAPHORE = new Semaphore(TimerGestoreRepositoryBuste.ID_MODULO);
  171.     private static Boolean LOCK = false;
  172.    
  173.     /**
  174.      * Metodo necessario per l'implementazione dell'interfaccia
  175.      * <code>TimedObject</code>.
  176.      *
  177.      *
  178.      */
  179.     @Override
  180.     public void ejbTimeout(Timer timer) throws EJBException {
  181.        
  182.         // Nelle nuove versioni, jboss avviava automaticamente un EJB Timer registrato. Questo comportamento, insieme
  183.         // al codice che avviava manualmente il timer in versione thread provocava un doppio avvio.
  184.         if(this.propertiesReader.isServerJ2EE()==false){
  185.             //System.out.println("GestoreBuste STOPPED");
  186.             stop(timer);
  187.             return;
  188.         }
  189.        
  190.        
  191.         // Solo il thread avviato da OpenSPCoop deve essere eseguito
  192.         if( (this.deployFromOpenSPCoop == false)){
  193.             if(this.propertiesReader.isTimerAutoStart_StopTimer()){
  194.                 stop(timer);
  195.                 return;
  196.             }else{
  197.                 // Viene sempre richiamato ejbCreate() e quindi la variabile deployFromOpenSPCoop รจ sempre null.
  198.                 // La single instance viene gestiti quindi con un lock
  199.                 SemaphoreLock lock = SEMAPHORE.acquireThrowRuntime("ejbTimeout");
  200.                 try {
  201.                     if(LOCK){
  202.                         this.msgDiag.logPersonalizzato("precedenteEsecuzioneInCorso.stopTimer");
  203.                         this.logTimer.info(this.msgDiag.getMessaggio_replaceKeywords("precedenteEsecuzioneInCorso.stopTimer"));
  204.                         stop(timer);
  205.                         return;
  206.                     }
  207.                     else{
  208.                         LOCK = true;
  209.                        
  210.                         /**
  211.                          * Aggiungo una sleep di 5 secondi per far provocare il LOCK sopra presente, per le altre istanze di timer
  212.                          * in modo da avere solamente una istanza in esecuzione
  213.                          */
  214.                         for (int i = 0; i < 10; i++) {
  215.                             Utilities.sleep(500);
  216.                         }
  217.                     }
  218.                 }finally {
  219.                     SEMAPHORE.release(lock, "ejbTimeout");
  220.                 }
  221.             }
  222.         }

  223.         try{
  224.            
  225.             // Controllo se OpenSPCoop desidera avviare il Timer
  226.             if(this.propertiesReader.isTimerGestoreRepositoryBusteAbilitato()==false){
  227.                 this.msgDiag.logPersonalizzato("disabilitato");
  228.                 this.logTimer.warn(this.msgDiag.getMessaggio_replaceKeywords("disabilitato"));
  229.                 stop(timer);
  230.                 return;
  231.             }
  232.            
  233.             // Controllo che l'inizializzazione corretta delle risorse sia effettuata
  234.             if(timer == null){
  235.                 String msgErrore = "inizializzazione del Timer non effettuata";
  236.                 this.msgDiag.logFatalError(msgErrore, "Check inizializzazione");
  237.                 this.logTimer.error(msgErrore);
  238.                 stop(timer);
  239.                 return;
  240.             }
  241.             if(OpenSPCoop2Startup.initialize==false){
  242.                 String msgErrore = "inizializzazione di OpenSPCoop non effettuata";
  243.                 this.msgDiag.logFatalError(msgErrore, "Check inizializzazione");
  244.                 this.logTimer.error(msgErrore);
  245.                 stop(timer);
  246.                 return;
  247.             }
  248.            
  249.             if(this.gestioneAttiva){
  250.                 this.msgDiag.logPersonalizzato("precedenteEsecuzioneInCorso");
  251.                 this.logTimer.info(this.msgDiag.getMessaggio_replaceKeywords("precedenteEsecuzioneInCorso"));
  252.                 return;
  253.             }
  254.            
  255.             try{
  256.                 // Prendo la gestione
  257.                 this.gestioneAttiva = true;
  258.                 TimerGestoreRepositoryBusteLib gestoreMessaggiLib =
  259.                     new TimerGestoreRepositoryBusteLib(this.msgDiag,this.logTimer,this.propertiesReader,this.logQuery,this.limit,this.orderByQuery);
  260.                
  261.                 gestoreMessaggiLib.check();
  262.                
  263.             }catch(Exception e){
  264.                 this.msgDiag.logErroreGenerico(e,"GestoreRepositoryBusteTimerEJB");
  265.                 this.logTimer.error("Errore generale: "+e.getMessage(),e);
  266.             }finally{
  267.                 // Rilascio la gestione
  268.                 this.gestioneAttiva = false;
  269.             }
  270.                        
  271.         }finally{
  272.             SemaphoreLock lock = SEMAPHORE.acquireThrowRuntime("ejbTimeoutCheck2");
  273.             try {
  274.                 LOCK = false;
  275.             }finally {
  276.                 SEMAPHORE.release(lock, "ejbTimeoutCheck2");
  277.             }  
  278.         }

  279.     }

  280.     /**
  281.      * Imposta il Contesto del Session Bean. Metodo necessario per
  282.      * l'implementazione dell'interfaccia <code>SessionBean</code>.
  283.      *
  284.      * @param aContext
  285.      *            Contesto del Session Bean.
  286.      *
  287.      */
  288.     @Override
  289.     public void setSessionContext(SessionContext aContext) throws EJBException {
  290.         this.sessionContext = aContext;
  291.     }

  292.     /**
  293.      * Inizializza il Timer di gestione
  294.      *
  295.      *
  296.      */
  297.     public boolean start() throws EJBException {
  298.         if( this.timer != null ){

  299.             this.msgDiag.logPersonalizzato("timerGiaAvviato");
  300.             this.logTimer.info(this.msgDiag.getMessaggio_replaceKeywords("timerGiaAvviato"));
  301.             return false;

  302.         } else {

  303.             if(this.propertiesReader.isTimerGestoreRepositoryBusteAbilitato()){
  304.            
  305.                 this.deployFromOpenSPCoop = true;      
  306.                 this.msgDiag.logPersonalizzato("avvioInCorso");
  307.                 this.logTimer.info(this.msgDiag.getMessaggio_replaceKeywords("avvioInCorso"));
  308.                 Utilities.sleep(1000); // tempo necessario per un corretto avvio in JBoss 4.0.3...
  309.                 Date now = DateManager.getDate();
  310.                 long timeout = 1000 * this.timeout;
  311.                 try {
  312.                     // creo il timer
  313.                     TimerService ts = this.sessionContext.getTimerService();
  314.                     this.timer = ts.createTimer(now, timeout, TimerGestoreRepositoryBuste.ID_MODULO);
  315.                     this.msgDiag.logPersonalizzato("avvioEffettuato");
  316.                     this.logTimer.info(this.msgDiag.getMessaggio_replaceKeywords("avvioEffettuato"));
  317.                 } catch (Exception e) {
  318.                     stop();
  319.                     this.msgDiag.logFatalError(e, "Creazione timer EJB gestore del Repository Buste");
  320.                     this.logTimer.error("Errore durante la creazione del timer: "+e.getMessage(),e);
  321.                 }
  322.                 return this.timer != null;
  323.                
  324.             }else{
  325.                
  326.                 this.msgDiag.logPersonalizzato("disabilitato");
  327.                 this.logTimer.warn(this.msgDiag.getMessaggio_replaceKeywords("disabilitato"));
  328.                 return false;
  329.                
  330.             }
  331.         }
  332.     }

  333.     /**
  334.      * Restituisce lo stato del timer di gestione
  335.      *
  336.      *
  337.      */
  338.     public boolean isStarted() throws EJBException {
  339.         return this.timer != null;
  340.     }

  341.     /**
  342.      * Annulla il timer di gestione
  343.      *
  344.      *
  345.      */
  346.     public void stop(Timer atimer) throws EJBException {
  347.         if (atimer != null) {
  348.             atimer.cancel();
  349.         }
  350.     }

  351.     /**
  352.      * Annulla il timer di gestione interno
  353.      *
  354.      *
  355.      */
  356.     public void stop() throws EJBException {
  357.         if (this.timer != null) {
  358.             this.timer.cancel();
  359.             this.timer = null;
  360.         }
  361.     }

  362. }