All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencms.db.CmsDbPoolV11 Maven / Gradle / Ivy

Go to download

OpenCms is an enterprise-ready, easy to use website content management system based on Java and XML technology. Offering a complete set of features, OpenCms helps content managers worldwide to create and maintain beautiful websites fast and efficiently.

There is a newer version: 17.0
Show newest version
/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software GmbH & Co. KG, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.db;

import org.opencms.configuration.CmsParameterConfiguration;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.security.I_CmsCredentialsResolver;
import org.opencms.util.CmsStringUtil;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLTimeoutException;
import java.sql.SQLTransientConnectionException;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.logging.Log;

import com.google.common.collect.Maps;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

/**
 * Database connection pool class using HikariCP.
 */
public final class CmsDbPoolV11 {

    /** Prefix for database keys. */
    public static final String KEY_DATABASE = "db.";

    /** Key for the database name. */
    public static final String KEY_DATABASE_NAME = KEY_DATABASE + "name";

    /** Key for the pool id. */
    public static final String KEY_DATABASE_POOL = KEY_DATABASE + "pool";

    /** Key for number of connection attempts. */
    public static final String KEY_CONNECT_ATTEMTS = "connects";

    /** Key for connection waiting. */
    public static final String KEY_CONNECT_WAITS = "wait";

    /** Key for the entity manager pool size. */
    public static final String KEY_ENTITY_MANAGER_POOL_SIZE = "entityMangerPoolSize";

    /** Key for jdbc driver. */
    public static final String KEY_JDBC_DRIVER = "jdbcDriver";

    /** Key for jdbc url. */
    public static final String KEY_JDBC_URL = "jdbcUrl";

    /** Key for jdbc url params. */
    public static final String KEY_JDBC_URL_PARAMS = KEY_JDBC_URL + ".params";

    /** Key for database password. */
    public static final String KEY_PASSWORD = "password";

    /** Key for default. */
    public static final String KEY_POOL_DEFAULT = "default";

    /** Key for pool url. */
    public static final String KEY_POOL_URL = "poolUrl";

    /** Key for pool user. */
    public static final String KEY_POOL_USER = "user";

    /** Key for vfs pool. */
    public static final String KEY_POOL_VFS = "vfs";

    /** Key for user name. */
    public static final String KEY_USERNAME = "user";

    /** The name of the opencms default pool. */
    public static final String OPENCMS_DEFAULT_POOL_NAME = "default";

    /** The default OpenCms JDBC pool URL. */
    public static final String OPENCMS_DEFAULT_POOL_URL = "opencms:default";

    /** The prefix used for opencms JDBC pools. */
    public static final String OPENCMS_URL_PREFIX = "opencms:";

    /** Logger instance for this class. */
    private static final Log LOG = CmsLog.getLog(CmsDbPoolV11.class);

    /** Map of default test queries. */
    private static Map testQueries = Maps.newHashMap();

    static {
        testQueries.put("com.ibm.db2.jcc.DB2Driver", "SELECT 1 FROM SYSIBM.SYSDUMMY1");
        testQueries.put("net.sourceforge.jtds.jdbc.Driver", "SELECT 1");
        testQueries.put("oracle.jdbc.driver.OracleDriver", "SELECT 1 FROM DUAL");
        testQueries.put("com.ibm.as400.access.AS400JDBCDriver", "SELECT NOW()");
    }

    /** The opencms pool url. */
    private String m_poolUrl;

    /** The HikariCP data source. */
    private HikariDataSource m_dataSource;

    /**
     * Default constructor.

* * @param config the OpenCms configuration (opencms.properties) * @param key the name of the pool (without the opencms: prefix) * * @throws Exception if something goes wrong */ public CmsDbPoolV11(CmsParameterConfiguration config, String key) throws Exception { HikariConfig hikariConf = createHikariConfig(config, key); m_poolUrl = OPENCMS_URL_PREFIX + key; m_dataSource = new HikariDataSource(hikariConf); Connection con = null; boolean connect = false; int connectionTests = 0; int connectionAttempts = config.getInteger(KEY_DATABASE_POOL + '.' + key + '.' + KEY_CONNECT_ATTEMTS, 10); int connectionsWait = config.getInteger(KEY_DATABASE_POOL + '.' + key + '.' + KEY_CONNECT_WAITS, 5000); // try to connect once to the database to ensure it can be connected to at all // if the conection cannot be established, multiple attempts will be done to connect // just in cast the database was not fast enough to start before OpenCms was started do { try { // try to connect con = m_dataSource.getConnection(); connect = true; } catch (Exception e) { // connection failed, increase attempts, sleept for some seconds and log a message connectionTests++; if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info( Messages.get().getBundle().key( Messages.INIT_WAIT_FOR_DB_4, new Object[] { getPoolUrl(), m_dataSource.getJdbcUrl(), new Integer(connectionTests), new Integer(connectionsWait)})); } Thread.sleep(connectionsWait); } finally { if (con != null) { con.close(); } } } while (!connect && (connectionTests < connectionAttempts)); if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info( Messages.get().getBundle().key(Messages.INIT_JDBC_POOL_2, getPoolUrl(), m_dataSource.getJdbcUrl())); } } /** * Creates the HikariCP configuration based on the configuration of a pool defined in opencms.properties. * * @param config the configuration object with the properties * @param key the pool name (without the opencms prefix) * * @return the HikariCP configuration for the pool */ public static HikariConfig createHikariConfig(CmsParameterConfiguration config, String key) { Map poolMap = Maps.newHashMap(); for (Map.Entry entry : config.entrySet()) { String suffix = getPropertyRelativeSuffix(KEY_DATABASE_POOL + "." + key, entry.getKey()); if ((suffix != null) && !CmsStringUtil.isEmptyOrWhitespaceOnly(entry.getValue())) { String value = entry.getValue().trim(); poolMap.put(suffix, value); } } // these are for backwards compatibility , all other properties not of the form db.pool.poolname.v11..... are ignored String jdbcUrl = poolMap.get(KEY_JDBC_URL); String params = poolMap.get(KEY_JDBC_URL_PARAMS); String driver = poolMap.get(KEY_JDBC_DRIVER); String user = poolMap.get(KEY_USERNAME); String password = poolMap.get(KEY_PASSWORD); String poolName = OPENCMS_URL_PREFIX + key; if ((params != null) && (jdbcUrl != null)) { jdbcUrl += params; } Properties hikariProps = new Properties(); if (jdbcUrl != null) { hikariProps.put("jdbcUrl", jdbcUrl); } if (driver != null) { hikariProps.put("driverClassName", driver); } if (user != null) { user = OpenCms.getCredentialsResolver().resolveCredential(I_CmsCredentialsResolver.DB_USER, user); hikariProps.put("username", user); } if (password != null) { password = OpenCms.getCredentialsResolver().resolveCredential( I_CmsCredentialsResolver.DB_PASSWORD, password); hikariProps.put("password", password); } hikariProps.put("maximumPoolSize", "30"); // Properties of the form db.pool.poolname.v11. are directly passed to HikariCP as for (Map.Entry entry : poolMap.entrySet()) { String suffix = getPropertyRelativeSuffix("v11", entry.getKey()); if (suffix != null) { hikariProps.put(suffix, entry.getValue()); } } String configuredTestQuery = (String)(hikariProps.get("connectionTestQuery")); String testQueryForDriver = testQueries.get(driver); if ((testQueryForDriver != null) && CmsStringUtil.isEmptyOrWhitespaceOnly(configuredTestQuery)) { hikariProps.put("connectionTestQuery", testQueryForDriver); } hikariProps.put("registerMbeans", "true"); HikariConfig result = new HikariConfig(hikariProps); result.setPoolName(poolName.replace(":", "_")); return result; } /** * Returns the name of the default database connection pool.

* * @return the name of the default database connection pool */ public static String getDefaultDbPoolName() { return OPENCMS_DEFAULT_POOL_NAME; } /** * If str starts with prefix + '.', return the remaining part, otherwise return null.

* * @param prefix the prefix * @param str the string to remove the prefix from * @return str with the prefix removed, or null if it didn't start with prefix + '.' */ public static String getPropertyRelativeSuffix(String prefix, String str) { String realPrefix = prefix + "."; if (str.startsWith(realPrefix)) { return str.substring(realPrefix.length()); } return null; } /** * Closes the pool.

* * @throws Exception if something goes wrong */ public void close() throws Exception { m_dataSource.close(); } /** * Returns the number of active connections.

* * @return the number of active connections */ public int getActiveConnections() { return m_dataSource.getHikariPoolMXBean().getActiveConnections(); } /** * Gets a database connection from the pool.

* * @return the database connection * @throws SQLException if something goes wrong */ public Connection getConnection() throws SQLException { try { return m_dataSource.getConnection(); } catch (SQLTransientConnectionException | SQLTimeoutException e) { LOG.error(e.getLocalizedMessage(), e); throw e; } } /** * Gets the number of idle connections.

* * @return the number of idle connections */ public int getIdleConnections() { return m_dataSource.getHikariPoolMXBean().getIdleConnections(); } /** * Gets the pool url.

* * @return the pool url */ public String getPoolUrl() { return m_poolUrl; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy