TimerGestorePuliziaMessaggiAnomaliImpl.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 TimerGestorePuliziaMessaggiAnomali} 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 TimerGestorePuliziaMessaggiAnomaliImpl 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.     /** Properties Reader */
  65.     private OpenSPCoop2Properties propertiesReader;
  66.     /** MsgDiagnostico */
  67.     private MsgDiagnostico msgDiag;
  68.    
  69.     /** Logger utilizzato per debug. */
  70.     private Logger logTimer = null;

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





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

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

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

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

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

  119.         this.timeout = this.propertiesReader.getRepositoryIntervalloEliminazioneMessaggi();
  120.         String s = "secondi";
  121.         if(this.timeout == 1)
  122.             s = "secondo";
  123.         this.msgDiag.addKeyword(CostantiPdD.KEY_TIMEOUT, this.timeout+" "+s);
  124.        
  125.         this.logQuery = this.propertiesReader.isTimerGestorePuliziaMessaggiAnomaliAbilitatoLog();
  126.         this.orderByQuery = this.propertiesReader.isTimerGestorePuliziaMessaggiAnomaliAbilitatoOrderBy();
  127.        
  128.         this.limit = this.propertiesReader.getTimerGestorePuliziaMessaggiAnomaliLimit();
  129.         if(this.limit<=0){
  130.             this.limit = CostantiPdD.LIMIT_MESSAGGI_GESTORI;
  131.         }
  132.         this.msgDiag.addKeyword(CostantiPdD.KEY_LIMIT, this.limit+"");
  133.     }

  134.     /**
  135.      * Metodo necessario per l'implementazione dell'interfaccia
  136.      * <code>SessionBean</code>.
  137.      *
  138.      *
  139.      */
  140.     @Override
  141.     public void ejbRemove() throws EJBException {
  142.     }

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

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

  161.     private static Semaphore SEMAPHORE = new Semaphore(TimerGestorePuliziaMessaggiAnomali.ID_MODULO);
  162.     private static Boolean LOCK = false;
  163.    
  164.     /**
  165.      * Metodo necessario per l'implementazione dell'interfaccia
  166.      * <code>TimedObject</code>.
  167.      *
  168.      *
  169.      */
  170.     @Override
  171.     public void ejbTimeout(Timer timer) throws EJBException {

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

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

  272.     /**
  273.      * Imposta il Contesto del Session Bean. Metodo necessario per
  274.      * l'implementazione dell'interfaccia <code>SessionBean</code>.
  275.      *
  276.      * @param aContext
  277.      *            Contesto del Session Bean.
  278.      *
  279.      */
  280.     @Override
  281.     public void setSessionContext(SessionContext aContext) throws EJBException {
  282.         this.sessionContext = aContext;
  283.     }

  284.     /**
  285.      * Inizializza il Timer di gestione
  286.      *
  287.      *
  288.      */
  289.     public boolean start() throws EJBException {
  290.         if( this.timer != null ){

  291.             this.msgDiag.logPersonalizzato("timerGiaAvviato");
  292.             this.logTimer.info(this.msgDiag.getMessaggio_replaceKeywords("timerGiaAvviato"));
  293.             return false;

  294.         } else {

  295.             if(this.propertiesReader.isTimerGestorePuliziaMessaggiAnomaliAbilitato()){
  296.                
  297.                 this.deployFromOpenSPCoop = true;      
  298.                 this.msgDiag.logPersonalizzato("avvioInCorso");
  299.                 this.logTimer.info(this.msgDiag.getMessaggio_replaceKeywords("avvioInCorso"));
  300.                 Utilities.sleep(1000); // tempo necessario per un corretto avvio in JBoss 4.0.3...
  301.                 Date now = DateManager.getDate();
  302.                 long timeout = 1000 * this.timeout;
  303.                 try {
  304.                     // creo il timer
  305.                     TimerService ts = this.sessionContext.getTimerService();
  306.                     this.timer = ts.createTimer(now, timeout, TimerGestorePuliziaMessaggiAnomali.ID_MODULO);
  307.                     this.msgDiag.logPersonalizzato("avvioEffettuato");
  308.                     this.logTimer.info(this.msgDiag.getMessaggio_replaceKeywords("avvioEffettuato"));
  309.                 } catch (Exception e) {
  310.                     stop();
  311.                     this.msgDiag.logFatalError(e, "Creazione timer EJB gestore della pulizia dei messaggi non consistenti");
  312.                     this.logTimer.error("Errore durante la creazione del timer: "+e.getMessage(),e);
  313.                 }
  314.                 return this.timer != null;
  315.        
  316.             }else{
  317.                 this.msgDiag.logPersonalizzato("disabilitato");
  318.                 this.logTimer.warn(this.msgDiag.getMessaggio_replaceKeywords("disabilitato"));
  319.                 return false;
  320.             }
  321.         }
  322.     }

  323.     /**
  324.      * Restituisce lo stato del timer di gestione
  325.      *
  326.      *
  327.      */
  328.     public boolean isStarted() throws EJBException {
  329.         return this.timer != null;
  330.     }

  331.     /**
  332.      * Annulla il timer di gestione
  333.      *
  334.      *
  335.      */
  336.     public void stop(Timer atimer) throws EJBException {
  337.         if (atimer != null) {
  338.             atimer.cancel();
  339.         }
  340.     }

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

  352. }