Package org.wso2.carbon.database.connection.service.dbcp

Source Code of org.wso2.carbon.database.connection.service.dbcp.DBCPDatabaseConnectionService

/*
*  Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
*  WSO2 Inc. licenses this file to you under the Apache License,
*  Version 2.0 (the "License"); you may not use this file except
*  in compliance with the License.
*  You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.database.connection.service.dbcp;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.database.connection.service.DatabaseConnectionServiceException;
import org.wso2.carbon.database.connection.service.config.DatabaseConnectionPoolConfig;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
*  Implements ConnectionService  interface to get connection from a Apache commons DBCP connection pool
*/
public class DBCPDatabaseConnectionService {

    private static Log log = LogFactory.getLog(DBCPDatabaseConnectionService.class);

    /**
     * Map of, DBConnectionURL -> BasicDataSource
     */
    private Map<String, BasicDataSource> dataSourceMap = new HashMap<String, BasicDataSource>();

    /**
     * Initialize Basic Data source
     */
    private BasicDataSource dataSource = null;

    /**
     * Default values are defined, if they are not configured in configuration files
     */
    private static final int DEFAULT_MAX_ACTIVE = 40;
    private static final int DEFAULT_MAX_WAIT = 1000 * 60;
    private static final int DEFAULT_MIN_IDLE = 5;
    private static final int DEFAULT_MAX_IDLE = 6;

    /**
     * Hold the values of created and closed  database connections
     */
    private static AtomicInteger connectionsCreated = new AtomicInteger();
    private static AtomicInteger connectionsClosed = new AtomicInteger();



    /**
     * This method returns the database connection for given database configuration
     * @param databaseConnectionPoolConfig  DatabaseConnectionPoolConfig  object which has been
     * encapsulated the DB configuration data
     * @return database connection is return from connection pool
     * @throws DatabaseConnectionServiceException  DatabaseConnectionServiceException throws when
     * db url is null and if database connection can not be created from connection pool
     */
    public Connection getDBConnection(DatabaseConnectionPoolConfig databaseConnectionPoolConfig)
            throws DatabaseConnectionServiceException {

        Connection connection = null;
        String databaseUrl = databaseConnectionPoolConfig.getDatabaseUrl();

        if(databaseUrl != null && databaseUrl.equals("")) {

            if (dataSourceMap.containsKey(databaseConnectionPoolConfig.getDatabaseUrl())) {
                dataSource = dataSourceMap.get(databaseConnectionPoolConfig.getDatabaseUrl());
            } else {
                createDataSource(databaseConnectionPoolConfig);
            }

            try {
                connection = dataSource.getConnection();
            } catch (SQLException e) {
                log.error("Unable to create database connection ", e);
                throw new DatabaseConnectionServiceException("Unable to create database connection ", e);
            }
            connectionsCreated.incrementAndGet();

        } else {
            throw new DatabaseConnectionServiceException("Database Url can not be null value");
        }
        return connection;
    }

    /**
     * This method returns the database connection for given database Url
     * @param databaseUrl  database url which is
     * @return database connection is return from connection pool
     * @throws DatabaseConnectionServiceException  DatabaseConnectionServiceException throws when
     * db url is null and if database connection can not be created from connection pool
     */
    public Connection getDBConnection(String databaseUrl)
            throws DatabaseConnectionServiceException {     // TODO we should decide whether to use this method

        Connection connection;

        if(databaseUrl != null && databaseUrl.equals("")) {

            if (dataSourceMap.containsKey(databaseUrl)) {
                dataSource = dataSourceMap.get(databaseUrl);
            }

            try {
                connection = dataSource.getConnection();
            } catch (SQLException e) {
                log.error("Unable to create database connection ", e);
                throw new DatabaseConnectionServiceException("Unable to create database connection ", e);
            }
            connectionsCreated.incrementAndGet();

        } else {
            throw new DatabaseConnectionServiceException("Database Url can not be null value");
        }

        return connection;
    }

    /**
     * This method  creates the database connection pool and puts it in to the Map and returns
     * @param databaseConnectionPoolConfig DatabaseConnectionPoolConfig  object which has been
     * encapsulated the DB configuration data
     * @return DBCP connection pool is return
     */
    private BasicDataSource createDataSource(DatabaseConnectionPoolConfig databaseConnectionPoolConfig) {

        String maxActive = databaseConnectionPoolConfig.getMaxActive();
        String minIdle = databaseConnectionPoolConfig.getMinIdle();
        String maxIdle = databaseConnectionPoolConfig.getMaxIdle();
        String maxWait = databaseConnectionPoolConfig.getMaxWait();
        dataSource = new BasicDataSource();

        dataSource.setDriverClassName(databaseConnectionPoolConfig.getDriverClassName());
        dataSource.setUrl(databaseConnectionPoolConfig.getDatabaseUrl());
        dataSource.setUsername(databaseConnectionPoolConfig.getUserName());
        dataSource.setPassword(databaseConnectionPoolConfig.getPassword());

        if(maxActive != null && !maxActive.equals("")){
            dataSource.setMaxActive(Integer.parseInt(maxActive));
        } else {
            dataSource.setMaxActive(DEFAULT_MAX_ACTIVE);
        }

        if(minIdle != null && !minIdle.equals("")){
            dataSource.setMaxActive(Integer.parseInt(minIdle));
        } else {
            dataSource.setMaxActive(DEFAULT_MIN_IDLE);
        }

        if(maxIdle != null && !maxIdle.equals("")){
            dataSource.setMaxActive(Integer.parseInt(maxIdle));
        } else {
            dataSource.setMaxActive(DEFAULT_MAX_IDLE);
        }

        if(maxWait != null && !maxWait.equals("")){
            dataSource.setMaxActive(Integer.parseInt(maxWait));
        } else {
            dataSource.setMaxActive(DEFAULT_MAX_WAIT);
        }

        dataSourceMap.put(databaseConnectionPoolConfig.getDatabaseUrl(), dataSource);
        return dataSource;
    }

    /**
     * This method closes the given database connection
     * @param connection database connection
     */
    public void closeDBConnection(Connection connection) {

        try {
            connection.close();
            connectionsClosed.incrementAndGet();
        } catch (SQLException e) {
            log.error("Unable to close data base connection", e);
        }
    }

    /**
     * This method closes and releases all idle connections that are
     * currently stored in the connection pool associated with this data source
     */
    public void closeDatabasePoolConnection() {

        if (dataSource != null) {
            try {
                dataSource.close();
                dataSource = null;
            } catch (SQLException e) {
                log.error("Unable to close data source connection pool ", e);
            }
        }
    }

    /**
     *  Timer task to log the created and closed database connections, used only for debug purposes
     */
    public static void logDatabaseConnections() {

        final ScheduledExecutorService scheduler =
                Executors.newScheduledThreadPool(10);
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                scheduler.shutdownNow();
            }
        });
        Runnable runnable = new Runnable() {
            public void run() {
                if (log.isDebugEnabled()) {
                    log.debug("Total Number of Connections Created      : " +
                            connectionsCreated.get());
                    log.debug("Total Number of Connections Closed       : " +
                           connectionsClosed.get());
                }
            }
        };
        scheduler.scheduleAtFixedRate(runnable, 60, 60, TimeUnit.SECONDS);
    }
}
TOP

Related Classes of org.wso2.carbon.database.connection.service.dbcp.DBCPDatabaseConnectionService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.