DBTransazioniManager.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.  * DBTransazioniManager
  41.  *
  42.  * @author Poli Andrea (poli@link.it)
  43.  * @author $Author$
  44.  * @version $Rev$, $Date$
  45.  */
  46. public class DBTransazioniManager implements IMonitoraggioRisorsa {

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

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