DBStatisticheManager.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.config;

  21. import java.sql.Connection;
  22. import java.sql.SQLException;
  23. import java.sql.Statement;

  24. import javax.sql.DataSource;

  25. import org.openspcoop2.core.commons.CoreException;
  26. import org.openspcoop2.core.commons.IMonitoraggioRisorsa;
  27. import org.openspcoop2.core.constants.Costanti;
  28. import org.openspcoop2.core.constants.CostantiDB;
  29. import org.openspcoop2.core.id.IDSoggetto;
  30. import org.openspcoop2.pdd.logger.OpenSPCoop2Logger;
  31. import org.openspcoop2.utils.LoggerWrapperFactory;
  32. import org.openspcoop2.utils.UtilsAlreadyExistsException;
  33. import org.openspcoop2.utils.UtilsException;
  34. import org.openspcoop2.utils.datasource.DataSourceFactory;
  35. import org.openspcoop2.utils.datasource.DataSourceParams;
  36. import org.openspcoop2.utils.jdbc.JDBCUtilities;
  37. import org.openspcoop2.utils.resources.GestoreJNDI;
  38. import org.slf4j.Logger;

  39. /**    
  40.  * DBStatisticheManager
  41.  *
  42.  * @author Poli Andrea (poli@link.it)
  43.  * @author $Author$
  44.  * @version $Rev$, $Date$
  45.  */
  46. public class DBStatisticheManager implements IMonitoraggioRisorsa {

  47.     private static final String ID_MODULO = "DBStatisticheManager";
  48.    
  49.     private static DBStatisticheManager staticInstanceDBStatisticheManager;
  50.     public static synchronized void init(DBManager dbManagerRuntimePdD,Logger alog,String tipoDatabase) {
  51.         if(staticInstanceDBStatisticheManager==null) {
  52.             staticInstanceDBStatisticheManager = new DBStatisticheManager(dbManagerRuntimePdD, alog, tipoDatabase);
  53.         }
  54.     }
  55.     public static synchronized void init(DBTransazioniManager dbManagerTransazioni,Logger alog,String tipoDatabase) {
  56.         if(staticInstanceDBStatisticheManager==null) {
  57.             staticInstanceDBStatisticheManager = new DBStatisticheManager(dbManagerTransazioni, alog, tipoDatabase);
  58.         }
  59.     }
  60.     public static synchronized void init(String nomeDataSource, java.util.Properties context,Logger alog,String tipoDatabase,
  61.             boolean useOp2UtilsDatasource, boolean bindJMX) throws UtilsException {
  62.         if(staticInstanceDBStatisticheManager==null) {
  63.             staticInstanceDBStatisticheManager = new DBStatisticheManager(nomeDataSource, context, alog, tipoDatabase, useOp2UtilsDatasource, bindJMX);
  64.         }
  65.     }
  66.     public static DBStatisticheManager getInstance() {
  67.         // spotbugs warning 'SING_SINGLETON_GETTER_NOT_SYNCHRONIZED': l'istanza viene creata allo startup
  68.         if (staticInstanceDBStatisticheManager == null) {
  69.             synchronized (DBStatisticheManager.class) {
  70.                 if (staticInstanceDBStatisticheManager == null) {
  71.                     return null;
  72.                 }
  73.             }
  74.         }
  75.         return staticInstanceDBStatisticheManager;
  76.     }
  77.    
  78.    
  79.     /** Informazione sui proprietari che hanno richiesto una connessione */
  80.     private static java.util.concurrent.ConcurrentHashMap<String,Resource> risorseInGestione = new java.util.concurrent.ConcurrentHashMap<>();
  81.    
  82.     public static String[] getStatoRisorse() {  
  83.         return DBManager.getStatoRisorse(DBStatisticheManager.risorseInGestione);
  84.     }
  85.    
  86.    
  87.     private String tipoDatabase;
  88.     public String getTipoDatabase() {
  89.         return this.tipoDatabase;
  90.     }

  91.     private Logger log;
  92.    
  93.     private DBManager dbManagerRuntimePdD;
  94.     public boolean useRuntimePdD() {
  95.         return this.dbManagerRuntimePdD!=null;
  96.     }
  97.     private DBTransazioniManager dbManagerTransazioni;
  98.     public boolean useTransazioni() {
  99.         return this.dbManagerTransazioni!=null;
  100.     }
  101.     private DataSource datasourceStatistiche;
  102.    
  103.     private DBStatisticheManager(DBManager dbManagerRuntimePdD,Logger alog,String tipoDatabase) {
  104.         this.dbManagerRuntimePdD = dbManagerRuntimePdD;
  105.         this.log = alog;
  106.         this.tipoDatabase = tipoDatabase;
  107.     }
  108.     private DBStatisticheManager(DBTransazioniManager dbManagerTransazioni,Logger alog,String tipoDatabase) {
  109.         this.dbManagerTransazioni = dbManagerTransazioni;
  110.         this.log = alog;
  111.         this.tipoDatabase = tipoDatabase;
  112.     }
  113.     private DBStatisticheManager(String nomeDataSource, java.util.Properties context,Logger alog,String tipoDatabase,
  114.             boolean useOp2UtilsDatasource, boolean bindJMX) throws UtilsException {
  115.         try {
  116.             this.log = alog;
  117.             this.tipoDatabase = tipoDatabase;
  118.            
  119.             if(useOp2UtilsDatasource){
  120.                 DataSourceParams dsParams = Costanti.getDataSourceParamsPdD(bindJMX, tipoDatabase);
  121.                 initDatasource(nomeDataSource, context, dsParams);
  122.             }
  123.             else{
  124.                 GestoreJNDI gestoreJNDI = new GestoreJNDI(context);
  125.                 this.datasourceStatistiche = (DataSource) gestoreJNDI.lookup(nomeDataSource);
  126.             }
  127.         } catch (Exception ne) {
  128.             String msg = "Impossibile instanziare il manager: " + ne.getMessage();
  129.             doError(msg, ne);
  130.         }
  131.     }
  132.     private void initDatasource(String nomeDataSource, java.util.Properties context, DataSourceParams dsParams) throws UtilsException {
  133.         try{
  134.             this.datasourceStatistiche = DataSourceFactory.newInstance(nomeDataSource, context, dsParams);
  135.         }catch(UtilsAlreadyExistsException exists){
  136.             this.datasourceStatistiche = DataSourceFactory.getInstance(nomeDataSource);
  137.             if(this.datasourceStatistiche==null){
  138.                 throw new UtilsException("Lookup datasource non riuscita ("+exists.getMessage()+")",exists);
  139.             }
  140.         }
  141.     }
  142.    
  143.     private void doError(String msg, Exception e) throws UtilsException {
  144.         this.log.error(msg,e);
  145.         throw new UtilsException(msg,e);
  146.     }
  147.    
  148.    
  149.     public Resource getResource(IDSoggetto idPDD,String modulo,String idTransazione) throws UtilsException {
  150.         return this.getResource(idPDD, modulo, idTransazione, true);
  151.     }
  152.     public Resource getResource(IDSoggetto idPDD,String modulo,String idTransazione, boolean logError) throws UtilsException {
  153.         if(this.dbManagerRuntimePdD!=null) {
  154.             return this.dbManagerRuntimePdD.getResource(idPDD, modulo, idTransazione, logError);
  155.         }
  156.         else if(this.dbManagerTransazioni!=null) {
  157.             return this.dbManagerTransazioni.getResource(idPDD, modulo, idTransazione, logError);
  158.         }
  159.         else {
  160.             try {
  161.                 StringBuilder bf = new StringBuilder();
  162.                 if(idPDD!=null) {
  163.                     bf.append(idPDD.toString());
  164.                     if(modulo!=null) {
  165.                         bf.append(".");
  166.                     }
  167.                 }
  168.                 if(modulo!=null) {
  169.                     bf.append(modulo);
  170.                 }
  171.                 if(bf.length()<=0) {
  172.                     bf.append(ID_MODULO);
  173.                 }
  174.                 Resource risorsa = DBManager.buildResource("DBStatisticsManager", this.getConnectionFromDatasource(bf.toString(), idTransazione),
  175.                         idPDD, modulo, idTransazione);  
  176.                
  177.                 DBStatisticheManager.risorseInGestione.put(risorsa.getId(), risorsa);
  178.                
  179.                 return risorsa;
  180.             }
  181.             catch(Exception e) {
  182.                 String msg = "Errore durante l'ottenimento di una connessione: "+e.getMessage();
  183.                 doError(msg, e);
  184.                 throw new UtilsException(msg,e);
  185.             }
  186.         }
  187.     }
  188.    
  189.     private Connection getConnectionFromDatasource(String methodName, String idTransazione) throws SQLException {
  190.         if(this.datasourceStatistiche instanceof org.openspcoop2.utils.datasource.DataSource){
  191.             return ((org.openspcoop2.utils.datasource.DataSource)this.datasourceStatistiche).getWrappedConnection(idTransazione, "DBStatisticheManager."+methodName);
  192.         }
  193.         else{
  194.             return this.datasourceStatistiche.getConnection();
  195.         }
  196.     }
  197.    
  198.     public void releaseResource(IDSoggetto idPDD,String modulo,Resource resource){
  199.         this.releaseResource(idPDD, modulo, resource, true);
  200.     }
  201.     public void releaseResource(IDSoggetto idPDD,String modulo,Resource resource, boolean logError){
  202.         try {
  203.             if(this.dbManagerRuntimePdD!=null) {
  204.                 this.dbManagerRuntimePdD.releaseResource(idPDD, modulo, resource, logError);
  205.             }
  206.             else if(this.dbManagerTransazioni!=null) {
  207.                 this.dbManagerTransazioni.releaseResource(idPDD, modulo, resource, logError);
  208.             }
  209.             else {
  210.                 releaseConnection(resource);
  211.             }
  212.         }
  213.         catch(Exception e) {
  214.             this.log.error("Errore durante il rilascio di una risorsa: "+e.getMessage(),e);
  215.         }
  216.     }
  217.     private void releaseConnection(Resource resource) throws SQLException {
  218.         if(resource!=null){
  219.            
  220.             if(resource.getResource()!=null){
  221.                 Connection connectionDB = (Connection) resource.getResource();
  222.                 Logger logResource = OpenSPCoop2Logger.getLoggerOpenSPCoopResources()!=null ? OpenSPCoop2Logger.getLoggerOpenSPCoopResources() : LoggerWrapperFactory.getLogger(DBStatisticheManager.class);
  223.                 boolean checkAutocommit = (OpenSPCoop2Properties.getInstance()==null) || OpenSPCoop2Properties.getInstance().isJdbcCloseConnectionCheckAutocommit();
  224.                 boolean checkIsClosed = (OpenSPCoop2Properties.getInstance()==null) || OpenSPCoop2Properties.getInstance().isJdbcCloseConnectionCheckIsClosed();
  225.                 JDBCUtilities.closeConnection(logResource, connectionDB, checkAutocommit, checkIsClosed);
  226.             }  
  227.            
  228.             if(DBStatisticheManager.risorseInGestione.containsKey(resource.getId()))
  229.                 DBStatisticheManager.risorseInGestione.remove(resource.getId());
  230.         }
  231.     }
  232.    
  233.    
  234.    
  235.     /**
  236.      * Metodo che verica la connessione ad una risorsa.
  237.      * Se la connessione non e' presente, viene lanciata una eccezione che contiene il motivo della mancata connessione
  238.      *
  239.      * @throws DriverException eccezione che contiene il motivo della mancata connessione
  240.      */
  241.     @Override
  242.     public void isAlive() throws CoreException{
  243.         if(this.dbManagerRuntimePdD!=null) {
  244.             this.dbManagerRuntimePdD.isAlive();
  245.         }
  246.         else if(this.dbManagerTransazioni!=null) {
  247.             this.dbManagerTransazioni.isAlive();
  248.         }
  249.         else {
  250.             // Verifico la connessione
  251.             Resource resource = null;
  252.             Statement stmtTest = null;
  253.             IDSoggetto idSoggettAlive = new IDSoggetto();
  254.             idSoggettAlive.setCodicePorta(ID_MODULO);
  255.             idSoggettAlive.setTipo(ID_MODULO);
  256.             idSoggettAlive.setNome(ID_MODULO);
  257.             try {
  258.                 resource = getResource(idSoggettAlive);
  259.                 Connection con = (Connection) resource.getResource();
  260.                 // test:
  261.                 stmtTest = con.createStatement();
  262.                 stmtTest.execute("SELECT * from "+CostantiDB.DB_INFO);
  263.                        
  264.             } catch (Exception e) {
  265.                 throw new CoreException("Connessione al database 'GovWay - Statistiche' non disponibile: "+e.getMessage(),e);
  266.    
  267.             }finally{
  268.                 try{
  269.                     if(stmtTest!=null)
  270.                         stmtTest.close();
  271.                 }catch(Exception e){
  272.                     // close
  273.                 }
  274.                 try{
  275.                     this.releaseResource(idSoggettAlive, "CheckIsAlive", resource);
  276.                 }catch(Exception e){
  277.                     // close
  278.                 }
  279.             }
  280.         }
  281.     }
  282.     private Resource getResource(IDSoggetto idSoggettAlive) throws UtilsException {
  283.         Resource resource = null;
  284.         try{
  285.             resource = this.getResource(idSoggettAlive, "CheckIsAlive", null);
  286.         }catch(Exception e){
  287.             throw new UtilsException(e.getMessage(),e);
  288.         }
  289.         if(resource == null)
  290.             throw new UtilsException("Resource is null");
  291.         if(resource.getResource() == null)
  292.             throw new UtilsException("Connessione is null");
  293.         return resource;
  294.     }
  295. }