JDBCServiceManagerBase.java
/*
* GovWay - A customizable API Gateway
* https://govway.org
*
* Copyright (c) 2005-2024 Link.it srl (https://link.it).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openspcoop2.generic_project.dao.jdbc;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Date;
import java.util.Properties;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.openspcoop2.generic_project.beans.IProjectInfo;
import org.openspcoop2.generic_project.exception.ServiceException;
import org.openspcoop2.generic_project.utils.ServiceManagerProperties;
import org.openspcoop2.utils.LoggerWrapperFactory;
import org.openspcoop2.utils.date.DateManager;
import org.openspcoop2.utils.resources.ClassLoaderUtilities;
import org.openspcoop2.utils.resources.GestoreJNDI;
/**
* JDBCServiceManager
*
* @author Poli Andrea (apoli@link.it)
* @author $Author$
* @version $Rev$, $Date$
*/
public class JDBCServiceManagerBase {
/** DataSource. */
protected DataSource datasource;
/** Connection */
protected Connection connection = null;
/** Logger */
protected Logger log = null;
/** JDBC Properties */
protected JDBCServiceManagerProperties jdbcProperties = null;
/** Parametri per rinegoziare la connessione */
private String connectionUrl;
private String username;
private String password;
private int secondsToRefreshConnection = -1;
private Date connectionDate;
/** Tipo di costruttore */
private JDBCServiceManagerTipoCostruttore tipoCostruttore = null;
protected JDBCServiceManagerBase(){}
public JDBCServiceManagerBase(String jndiName, Properties contextJNDI,ServiceManagerProperties serviceManagerProperties) throws ServiceException{
this(jndiName, contextJNDI, new JDBCServiceManagerProperties(serviceManagerProperties), null);
}
public JDBCServiceManagerBase(String jndiName, Properties contextJNDI,JDBCServiceManagerProperties jdbcProperties) throws ServiceException{
this(jndiName, contextJNDI, jdbcProperties, null);
}
public JDBCServiceManagerBase(String jndiName, Properties contextJNDI,ServiceManagerProperties serviceManagerProperties,Logger alog) throws ServiceException{
this(jndiName, contextJNDI, new JDBCServiceManagerProperties(serviceManagerProperties), alog);
}
public JDBCServiceManagerBase(String jndiName, Properties contextJNDI,JDBCServiceManagerProperties jdbcProperties,Logger alog) throws ServiceException{
this.tipoCostruttore = JDBCServiceManagerTipoCostruttore.DATASOURCE_CFG;
if(alog==null){
this.log = LoggerWrapperFactory.getLogger(JDBCServiceManagerBase.class);
}else
this.log = alog;
try{
GestoreJNDI gestoreJNDI = new GestoreJNDI(contextJNDI);
this.datasource = (DataSource) gestoreJNDI.lookup(jndiName);
if(this.datasource == null){
throw new Exception("Datasource is null");
}
this.jdbcProperties = jdbcProperties;
jdbcProperties.getDatabase(); // check tipoDatabase fornito
} catch(Exception e) {
this.log.error("Creating failure: "+e.getMessage(),e);
throw new ServiceException("Creating failure: "+e.getMessage(),e);
}
}
public JDBCServiceManagerBase(DataSource ds,ServiceManagerProperties serviceManagerProperties) throws ServiceException{
this(ds, new JDBCServiceManagerProperties(serviceManagerProperties), null);
}
public JDBCServiceManagerBase(DataSource ds,JDBCServiceManagerProperties jdbcProperties) throws ServiceException{
this(ds, jdbcProperties, null);
}
public JDBCServiceManagerBase(DataSource ds,ServiceManagerProperties serviceManagerProperties,Logger alog) throws ServiceException{
this(ds, new JDBCServiceManagerProperties(serviceManagerProperties), alog);
}
public JDBCServiceManagerBase(DataSource ds,JDBCServiceManagerProperties jdbcProperties,Logger alog) throws ServiceException{
this.tipoCostruttore = JDBCServiceManagerTipoCostruttore.DATASOURCE_OBJECT;
if(alog==null){
this.log = LoggerWrapperFactory.getLogger(JDBCServiceManagerBase.class);
}else
this.log = alog;
try{
this.datasource = ds;
if(this.datasource == null){
throw new Exception("Datasource is null");
}
this.jdbcProperties = jdbcProperties;
jdbcProperties.getDatabase(); // check tipoDatabase fornito
} catch(Exception e) {
this.log.error("Creating failure: "+e.getMessage(),e);
throw new ServiceException("Creating failure: "+e.getMessage(),e);
}
}
public JDBCServiceManagerBase(String connectionUrl,String driverJDBC,String username,String password,ServiceManagerProperties serviceManagerProperties) throws ServiceException{
this(connectionUrl,driverJDBC,username,password,new JDBCServiceManagerProperties(serviceManagerProperties),null);
}
public JDBCServiceManagerBase(String connectionUrl,String driverJDBC,String username,String password,JDBCServiceManagerProperties jdbcProperties) throws ServiceException{
this(connectionUrl,driverJDBC,username,password,jdbcProperties,null);
}
public JDBCServiceManagerBase(String connectionUrl,String driverJDBC,String username,String password,ServiceManagerProperties serviceManagerProperties,Logger alog) throws ServiceException{
this(connectionUrl,driverJDBC,username,password,new JDBCServiceManagerProperties(serviceManagerProperties),alog);
}
public JDBCServiceManagerBase(String connectionUrl,String driverJDBC,String username,String password,JDBCServiceManagerProperties jdbcProperties,Logger alog) throws ServiceException{
this.tipoCostruttore = JDBCServiceManagerTipoCostruttore.CONNECTION_CFG;
if(alog==null){
this.log = LoggerWrapperFactory.getLogger(JDBCServiceManagerBase.class);
}else
this.log = alog;
try{
this.connectionUrl = connectionUrl;
this.username = username;
this.password = password;
this.secondsToRefreshConnection = jdbcProperties.getSecondsToRefreshConnection();
ClassLoaderUtilities.newInstance(driverJDBC);
setConnection();
this.jdbcProperties = jdbcProperties;
jdbcProperties.getDatabase(); // check tipoDatabase fornito
} catch(Exception e) {
this.log.error("Creating failure: "+e.getMessage(),e);
throw new ServiceException("Creating failure: "+e.getMessage(),e);
}
}
private void setConnection() throws Exception {
if(this.username!=null){
this.connection = DriverManager.getConnection(this.connectionUrl,this.username,this.password);
}else{
this.connection = DriverManager.getConnection(this.connectionUrl);
}
/*if(this.connection == null){
throw new Exception("Connection is null");
}*/
this.connectionDate = DateManager.getDate();
}
private boolean isConnectionExpired() {
if(this.secondsToRefreshConnection>0) {
Date now = DateManager.getDate();
Date expireDate = new Date(this.connectionDate.getTime()+(this.secondsToRefreshConnection*1000));
if(expireDate.before(now)) {
return true;
}
}
return false;
}
private void refreshConnection() throws Exception {
if(this.isConnectionExpired()) {
this._refreshConnection();
}
}
private synchronized void _refreshConnection() throws Exception {
if(this.isConnectionExpired()) {
//System.out.println("REFRESH (user:"+this.username+" connection-url: "+this.connectionUrl+")");
try {
if(this.connection!=null) {
this.connection.close();
}
}catch(Throwable t) {}
setConnection();
}
}
public JDBCServiceManagerBase(Connection connection,ServiceManagerProperties serviceManagerProperties) throws ServiceException{
this(connection, new JDBCServiceManagerProperties(serviceManagerProperties), null);
}
public JDBCServiceManagerBase(Connection connection,JDBCServiceManagerProperties jdbcProperties) throws ServiceException{
this(connection, jdbcProperties, null);
}
public JDBCServiceManagerBase(Connection connection,ServiceManagerProperties serviceManagerProperties,Logger alog) throws ServiceException{
this(connection, new JDBCServiceManagerProperties(serviceManagerProperties), alog);
}
public JDBCServiceManagerBase(Connection connection,JDBCServiceManagerProperties jdbcProperties,Logger alog) throws ServiceException{
this.tipoCostruttore = JDBCServiceManagerTipoCostruttore.CONNECTION_OBJECT;
if(alog==null){
this.log = LoggerWrapperFactory.getLogger(JDBCServiceManagerBase.class);
}else
this.log = alog;
try{
this.connection = connection;
if(this.connection == null){
throw new Exception("Connection is null");
}
this.jdbcProperties = jdbcProperties;
jdbcProperties.getDatabase(); // check tipoDatabase fornito
} catch(Exception e) {
this.log.error("Creating failure: "+e.getMessage(),e);
throw new ServiceException("Creating failure: "+e.getMessage(),e);
}
}
/* ** Destrory Service Manager */
public void close() throws ServiceException{
try{
if(this.tipoCostruttore!=null){
switch (this.tipoCostruttore) {
case CONNECTION_CFG:
if(this.connection!=null){
//System.out.println("CLOSE (user:"+this.username+" connection-url: "+this.connectionUrl+")");
this.connection.close();
}
break;
default:
break;
}
}
}catch(Exception e){
throw new ServiceException("Close failure: "+e.getMessage(),e);
}
}
/* ** Utilities */
// Metodi che non devono essere utilizzati dagli sviluppatori jdbc che implementano i metodi veri e propri
protected Connection getConnection() throws ServiceException {
try{
if(this.datasource!=null){
return this.datasource.getConnection();
}
else if(this.connection!=null){
if(JDBCServiceManagerTipoCostruttore.CONNECTION_CFG.equals(this.tipoCostruttore)) {
this.refreshConnection();
}
return this.connection;
}else{
throw new Exception("ServiceManager not initialized");
}
}catch(Exception e){
throw new ServiceException("Get Connection failure: "+e.getMessage(),e);
}
}
protected void closeConnection(Connection connection) throws ServiceException {
try{
if(connection==null){
throw new ServiceException("Connection is null");
}
if(this.datasource!=null){
// DATASOURCE_*
connection.close();
}
else if(this.connection!=null){
// CONNECTION_*
// se la connessione e' stata fornita come parametro del costruttore del service manager (quindi salvata in this.connection instance variable)
// non deve essere mai chiusa. La gestione e' a carico di chi ha inizializzato il service manager fornendo la connessione:
// - se ha usato il costruttore fornendo l'oggetto connection, deve fare lui la close sulla clonnection
// - se ha usato il costruttore fornendo i dati per creare una connessione (url,username,password) deve chiamare il metodo close del service manager.
if(connection.isClosed()){
throw new Exception("The connection provided shall not be closed");
}
}else{
throw new Exception("ServiceManager not initialized");
}
}catch(Exception e){
throw new ServiceException("Get Connection failure: "+e.getMessage(),e);
}
}
public Logger getLog() {
return this.log;
}
public JDBCServiceManagerProperties getJdbcProperties() {
return this.jdbcProperties;
}
/* Logger */
public static void configureDefaultLog4jProperties(IProjectInfo project) throws ServiceException{
JDBCLoggerProperties loggerProperties = new JDBCLoggerProperties(project);
loggerProperties.configureLog4j();
}
public static void configureLog4jProperties(File log4jProperties) throws ServiceException{
JDBCLoggerProperties loggerProperties = new JDBCLoggerProperties(null,log4jProperties);
loggerProperties.configureLog4j();
}
}