This is an automated email from the ASF dual-hosted git repository.

rohit pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/main by this push:
     new 7e085d5e1df framework/db: use HikariCP as default and improvements 
(#9518)
7e085d5e1df is described below

commit 7e085d5e1df9fd58305f0a9504c27b35e077e4f0
Author: Abhishek Kumar <[email protected]>
AuthorDate: Thu Sep 5 09:36:58 2024 +0530

    framework/db: use HikariCP as default and improvements (#9518)
    
    Per docs, if the mysql connector is JDBC2 compliant then it should use
    the Connection.isValid API to test a connection.
    
(https://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#isValid-int-)
    
    This would significantly reduce query lags and API throughput, as for
    every SQL query one or two SELECT 1 are performed everytime a Connection
    is given to application logic.
    
    This should only be accepted when the driver is JDBC4 complaint.
    
    As per the docs, the connector-j can use /* ping */ before calling
    SELECT 1 to have light weight application pings to the server:
    
https://dev.mysql.com/doc/connector-j/en/connector-j-usagenotes-j2ee-concepts-connection-pooling.html
    
    Replaces dbcp2 connection pool library with more performant HikariCP.
    With this unit tests are failing but build is passing.
    
    Signed-off-by: Rohit Yadav <[email protected]>
    Signed-off-by: Abhishek Kumar <[email protected]>
    Co-authored-by: Rohit Yadav <[email protected]>
---
 client/conf/db.properties.in                       |  20 ++-
 developer/pom.xml                                  |   4 +
 .../java/com/cloud/upgrade/DatabaseCreator.java    |  10 +-
 engine/storage/snapshot/pom.xml                    |   5 +
 framework/db/pom.xml                               |   8 +
 .../com/cloud/utils/db/ConnectionConcierge.java    |   2 +-
 .../java/com/cloud/utils/db/TransactionLegacy.java | 191 +++++++++++++++++----
 plugins/network-elements/globodns/pom.xml          |   5 +
 plugins/network-elements/tungsten/pom.xml          |   5 +
 pom.xml                                            |  13 ++
 server/pom.xml                                     |   5 +
 usage/conf/db.properties.in                        |   4 +
 12 files changed, 229 insertions(+), 43 deletions(-)

diff --git a/client/conf/db.properties.in b/client/conf/db.properties.in
index 8f31aff17e6..0f7d2706a42 100644
--- a/client/conf/db.properties.in
+++ b/client/conf/db.properties.in
@@ -34,10 +34,14 @@ db.cloud.uri=
 
 
 # CloudStack database tuning parameters
+db.cloud.connectionPoolLib=hikaricp
 db.cloud.maxActive=250
 db.cloud.maxIdle=30
-db.cloud.maxWait=10000
-db.cloud.validationQuery=SELECT 1
+db.cloud.maxWait=600000
+db.cloud.minIdleConnections=5
+db.cloud.connectionTimeout=30000
+db.cloud.keepAliveTime=600000
+db.cloud.validationQuery=/* ping */ SELECT 1
 db.cloud.testOnBorrow=true
 db.cloud.testWhileIdle=true
 db.cloud.timeBetweenEvictionRunsMillis=40000
@@ -70,9 +74,13 @@ db.usage.uri=
 
 
 # usage database tuning parameters
+db.usage.connectionPoolLib=hikaricp
 db.usage.maxActive=100
 db.usage.maxIdle=30
-db.usage.maxWait=10000
+db.usage.maxWait=600000
+db.usage.minIdleConnections=5
+db.usage.connectionTimeout=30000
+db.usage.keepAliveTime=600000
 db.usage.url.params=serverTimezone=UTC
 
 # Simulator database settings
@@ -82,9 +90,13 @@ db.simulator.host=@DBHOST@
 db.simulator.driver=@DBDRIVER@
 db.simulator.port=3306
 db.simulator.name=simulator
+db.simulator.connectionPoolLib=hikaricp
 db.simulator.maxActive=250
 db.simulator.maxIdle=30
-db.simulator.maxWait=10000
+db.simulator.maxWait=600000
+db.simulator.minIdleConnections=5
+db.simulator.connectionTimeout=30000
+db.simulator.keepAliveTime=600000
 db.simulator.autoReconnect=true
 
 # Connection URI to the database "simulator". When this property is set, only 
the following properties will be used along with it: db.simulator.host, 
db.simulator.port, db.simulator.name, db.simulator.autoReconnect. Other 
properties will be ignored.
diff --git a/developer/pom.xml b/developer/pom.xml
index 6cbf483faac..b44446ec0a5 100644
--- a/developer/pom.xml
+++ b/developer/pom.xml
@@ -42,6 +42,10 @@
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-pool2</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.zaxxer</groupId>
+            <artifactId>HikariCP</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.jasypt</groupId>
             <artifactId>jasypt</artifactId>
diff --git a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseCreator.java 
b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseCreator.java
index 154a8d11887..384826227af 100644
--- a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseCreator.java
+++ b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseCreator.java
@@ -116,10 +116,6 @@ public class DatabaseCreator {
     }
 
     public static void main(String[] args) {
-
-        ClassPathXmlApplicationContext appContext = new 
ClassPathXmlApplicationContext(new String[] 
{"/com/cloud/upgrade/databaseCreatorContext.xml"});
-        appContext.getBean(ComponentContext.class);
-
         String dbPropsFile = "";
         List<String> sqlFiles = new ArrayList<String>();
         List<String> upgradeClasses = new ArrayList<String>();
@@ -166,13 +162,17 @@ public class DatabaseCreator {
             System.exit(1);
         }
 
+        initDB(dbPropsFile, rootPassword, databases, dryRun);
+
+        ClassPathXmlApplicationContext appContext = new 
ClassPathXmlApplicationContext(new String[] 
{"/com/cloud/upgrade/databaseCreatorContext.xml"});
+        appContext.getBean(ComponentContext.class);
+
         try {
             TransactionLegacy.initDataSource(dbPropsFile);
         } catch (IOException e) {
             e.printStackTrace();
             System.exit(1);
         }
-        initDB(dbPropsFile, rootPassword, databases, dryRun);
 
         // Process sql files
         for (String sqlFile : sqlFiles) {
diff --git a/engine/storage/snapshot/pom.xml b/engine/storage/snapshot/pom.xml
index ac0daeabf76..f29b43d8de0 100644
--- a/engine/storage/snapshot/pom.xml
+++ b/engine/storage/snapshot/pom.xml
@@ -56,6 +56,11 @@
             <version>${project.version}</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
     <build>
         <plugins>
diff --git a/framework/db/pom.xml b/framework/db/pom.xml
index d4d3b6b8772..586d72f34f3 100644
--- a/framework/db/pom.xml
+++ b/framework/db/pom.xml
@@ -40,6 +40,10 @@
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-dbcp2</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.zaxxer</groupId>
+            <artifactId>HikariCP</artifactId>
+        </dependency>
         <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
@@ -48,6 +52,10 @@
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-pool2</artifactId>
         </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.apache.cloudstack</groupId>
             <artifactId>cloud-utils</artifactId>
diff --git 
a/framework/db/src/main/java/com/cloud/utils/db/ConnectionConcierge.java 
b/framework/db/src/main/java/com/cloud/utils/db/ConnectionConcierge.java
index 7cf34e6955c..c7c869ba920 100644
--- a/framework/db/src/main/java/com/cloud/utils/db/ConnectionConcierge.java
+++ b/framework/db/src/main/java/com/cloud/utils/db/ConnectionConcierge.java
@@ -145,7 +145,7 @@ public class ConnectionConcierge {
         protected String testValidity(String name, Connection conn) {
             if (conn != null) {
                 synchronized (conn) {
-                    try (PreparedStatement pstmt = 
conn.prepareStatement("SELECT 1");) {
+                    try (PreparedStatement pstmt = conn.prepareStatement("/* 
ping */ SELECT 1");) {
                         pstmt.executeQuery();
                     } catch (Throwable th) {
                         logger.error("Unable to keep the db connection for " + 
name, th);
diff --git 
a/framework/db/src/main/java/com/cloud/utils/db/TransactionLegacy.java 
b/framework/db/src/main/java/com/cloud/utils/db/TransactionLegacy.java
index 00fa8e4c0d5..88af397c06a 100644
--- a/framework/db/src/main/java/com/cloud/utils/db/TransactionLegacy.java
+++ b/framework/db/src/main/java/com/cloud/utils/db/TransactionLegacy.java
@@ -38,17 +38,20 @@ import 
org.apache.commons.dbcp2.DriverManagerConnectionFactory;
 import org.apache.commons.dbcp2.PoolableConnection;
 import org.apache.commons.dbcp2.PoolableConnectionFactory;
 import org.apache.commons.dbcp2.PoolingDataSource;
+import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.pool2.ObjectPool;
 import org.apache.commons.pool2.impl.GenericObjectPool;
 import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
-import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 
 import com.cloud.utils.Pair;
 import com.cloud.utils.PropertiesUtil;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.mgmt.JmxUtil;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
 
 /**
  * Transaction abstracts away the Connection object in JDBC.  It allows the
@@ -95,6 +98,8 @@ public class TransactionLegacy implements Closeable {
         }
     }
 
+    private static final String CONNECTION_POOL_LIB_DBCP = "dbcp";
+
     private final LinkedList<StackElement> _stack;
     private long _id;
 
@@ -1020,6 +1025,21 @@ public class TransactionLegacy implements Closeable {
         }
     }
 
+    private static <T extends Number> T parseNumber(String value, Class<T> 
type) {
+        if (value == null) {
+            return null;
+        }
+        try {
+            if (type.equals(Long.class)) {
+                return type.cast(Long.parseLong(value));
+            } else {
+                return type.cast(Integer.parseInt(value));
+            }
+        } catch (NumberFormatException ignored) {
+            return null;
+        }
+    }
+
     @SuppressWarnings({"rawtypes", "unchecked"})
     public static void initDataSource(Properties dbProps) {
         try {
@@ -1030,9 +1050,12 @@ public class TransactionLegacy implements Closeable {
             LOGGER.info("Is Data Base High Availiability enabled? Ans : " + 
s_dbHAEnabled);
             String loadBalanceStrategy = 
dbProps.getProperty("db.ha.loadBalanceStrategy");
             // FIXME:  If params are missing...default them????
-            final int cloudMaxActive = 
Integer.parseInt(dbProps.getProperty("db.cloud.maxActive"));
-            final int cloudMaxIdle = 
Integer.parseInt(dbProps.getProperty("db.cloud.maxIdle"));
-            final long cloudMaxWait = 
Long.parseLong(dbProps.getProperty("db.cloud.maxWait"));
+            final Integer cloudMaxActive = 
parseNumber(dbProps.getProperty("db.cloud.maxActive"), Integer.class);
+            final Integer cloudMaxIdle = 
parseNumber(dbProps.getProperty("db.cloud.maxIdle"), Integer.class);
+            final Long cloudMaxWait = 
parseNumber(dbProps.getProperty("db.cloud.maxWait"), Long.class);
+            final Integer cloudMinIdleConnections = 
parseNumber(dbProps.getProperty("db.cloud.minIdleConnections"), Integer.class);
+            final Long cloudConnectionTimeout = 
parseNumber(dbProps.getProperty("db.cloud.connectionTimeout"), Long.class);
+            final Long cloudKeepAliveTimeout = 
parseNumber(dbProps.getProperty("db.cloud.keepAliveTime"), Long.class);
             final String cloudUsername = 
dbProps.getProperty("db.cloud.username");
             final String cloudPassword = 
dbProps.getProperty("db.cloud.password");
             final String cloudValidationQuery = 
dbProps.getProperty("db.cloud.validationQuery");
@@ -1071,14 +1094,19 @@ public class TransactionLegacy implements Closeable {
             DriverLoader.loadDriver(cloudUriAndDriver.second());
 
             // Default Data Source for CloudStack
-            s_ds = createDataSource(cloudUriAndDriver.first(), cloudUsername, 
cloudPassword, cloudMaxActive, cloudMaxIdle, cloudMaxWait,
-                    cloudTimeBtwEvictionRunsMillis, 
cloudMinEvcitableIdleTimeMillis, cloudTestWhileIdle, cloudTestOnBorrow,
-                    cloudValidationQuery, isolationLevel);
+            s_ds = 
createDataSource(dbProps.getProperty("db.cloud.connectionPoolLib"), 
cloudUriAndDriver.first(),
+                    cloudUsername, cloudPassword, cloudMaxActive, 
cloudMaxIdle, cloudMaxWait,
+                    cloudTimeBtwEvictionRunsMillis, 
cloudMinEvcitableIdleTimeMillis, cloudTestWhileIdle,
+                    cloudTestOnBorrow, cloudValidationQuery, 
cloudMinIdleConnections, cloudConnectionTimeout,
+                    cloudKeepAliveTimeout, isolationLevel, "cloud");
 
             // Configure the usage db
-            final int usageMaxActive = 
Integer.parseInt(dbProps.getProperty("db.usage.maxActive"));
-            final int usageMaxIdle = 
Integer.parseInt(dbProps.getProperty("db.usage.maxIdle"));
-            final long usageMaxWait = 
Long.parseLong(dbProps.getProperty("db.usage.maxWait"));
+            final Integer usageMaxActive = 
parseNumber(dbProps.getProperty("db.usage.maxActive"), Integer.class);
+            final Integer usageMaxIdle = 
parseNumber(dbProps.getProperty("db.usage.maxIdle"), Integer.class);
+            final Long usageMaxWait = 
parseNumber(dbProps.getProperty("db.usage.maxWait"), Long.class);
+            final Integer usageMinIdleConnections = 
parseNumber(dbProps.getProperty("db.usage.minIdleConnections"), Integer.class);
+            final Long usageConnectionTimeout = 
parseNumber(dbProps.getProperty("db.usage.connectionTimeout"), Long.class);
+            final Long usageKeepAliveTimeout = 
parseNumber(dbProps.getProperty("db.usage.keepAliveTime"), Long.class);
             final String usageUsername = 
dbProps.getProperty("db.usage.username");
             final String usagePassword = 
dbProps.getProperty("db.usage.password");
 
@@ -1087,15 +1115,19 @@ public class TransactionLegacy implements Closeable {
             DriverLoader.loadDriver(usageUriAndDriver.second());
 
             // Data Source for usage server
-            s_usageDS = createDataSource(usageUriAndDriver.first(), 
usageUsername, usagePassword,
-                    usageMaxActive, usageMaxIdle, usageMaxWait, null, null, 
null, null,
-                    null, isolationLevel);
+            s_usageDS = 
createDataSource(dbProps.getProperty("db.usage.connectionPoolLib"), 
usageUriAndDriver.first(),
+                    usageUsername, usagePassword, usageMaxActive, 
usageMaxIdle, usageMaxWait, null,
+                    null, null, null, null,
+                    usageMinIdleConnections, usageConnectionTimeout, 
usageKeepAliveTimeout, isolationLevel, "usage");
 
             try {
                 // Configure the simulator db
-                final int simulatorMaxActive = 
Integer.parseInt(dbProps.getProperty("db.simulator.maxActive"));
-                final int simulatorMaxIdle = 
Integer.parseInt(dbProps.getProperty("db.simulator.maxIdle"));
-                final long simulatorMaxWait = 
Long.parseLong(dbProps.getProperty("db.simulator.maxWait"));
+                final Integer simulatorMaxActive = 
parseNumber(dbProps.getProperty("db.simulator.maxActive"), Integer.class);
+                final Integer simulatorMaxIdle = 
parseNumber(dbProps.getProperty("db.simulator.maxIdle"), Integer.class);
+                final Long simulatorMaxWait = 
parseNumber(dbProps.getProperty("db.simulator.maxWait"), Long.class);
+                final Integer simulatorMinIdleConnections = 
parseNumber(dbProps.getProperty("db.simulator.minIdleConnections"), 
Integer.class);
+                final Long simulatorConnectionTimeout = 
parseNumber(dbProps.getProperty("db.simulator.connectionTimeout"), Long.class);
+                final Long simulatorKeepAliveTimeout = 
parseNumber(dbProps.getProperty("db.simulator.keepAliveTime"), Long.class);
                 final String simulatorUsername = 
dbProps.getProperty("db.simulator.username");
                 final String simulatorPassword = 
dbProps.getProperty("db.simulator.password");
 
@@ -1122,15 +1154,18 @@ public class TransactionLegacy implements Closeable {
 
                 DriverLoader.loadDriver(simulatorDriver);
 
-                s_simulatorDS = createDataSource(simulatorConnectionUri, 
simulatorUsername, simulatorPassword,
-                        simulatorMaxActive, simulatorMaxIdle, 
simulatorMaxWait, null, null, null, null, cloudValidationQuery, isolationLevel);
+                s_simulatorDS = 
createDataSource(dbProps.getProperty("db.simulator.connectionPoolLib"),
+                        simulatorConnectionUri, simulatorUsername, 
simulatorPassword, simulatorMaxActive,
+                        simulatorMaxIdle, simulatorMaxWait, null, null, null, 
null,
+                        cloudValidationQuery, simulatorMinIdleConnections, 
simulatorConnectionTimeout,
+                        simulatorKeepAliveTimeout, isolationLevel, 
"simulator");
             } catch (Exception e) {
                 LOGGER.debug("Simulator DB properties are not available. Not 
initializing simulator DS");
             }
         } catch (final Exception e) {
-            s_ds = getDefaultDataSource("cloud");
-            s_usageDS = getDefaultDataSource("cloud_usage");
-            s_simulatorDS = getDefaultDataSource("cloud_simulator");
+            s_ds = 
getDefaultDataSource(dbProps.getProperty("db.cloud.connectionPoolLib"), 
"cloud");
+            s_usageDS = 
getDefaultDataSource(dbProps.getProperty("db.usage.connectionPoolLib"), 
"cloud_usage");
+            s_simulatorDS = 
getDefaultDataSource(dbProps.getProperty("db.simulator.connectionPoolLib"), 
"simulator");
             LOGGER.warn(
                     "Unable to load db configuration, using defaults with 5 
connections. Falling back on assumed datasource on localhost:3306 using 
username:password=cloud:cloud. Please check your configuration",
                     e);
@@ -1222,11 +1257,71 @@ public class TransactionLegacy implements Closeable {
     /**
      * Creates a data source
      */
-    private static DataSource createDataSource(String uri, String username, 
String password,
+    private static DataSource createDataSource(String connectionPoolLib, 
String uri, String username, String password,
+               Integer maxActive, Integer maxIdle, Long maxWait, Long 
timeBtwnEvictionRuns, Long minEvictableIdleTime,
+               Boolean testWhileIdle, Boolean testOnBorrow, String 
validationQuery, Integer minIdleConnections,
+               Long connectionTimeout, Long keepAliveTime, Integer 
isolationLevel, String dsName) {
+        LOGGER.debug("Creating datasource for database: {} with connection 
pool lib: {}", dsName,
+                connectionPoolLib);
+        if (CONNECTION_POOL_LIB_DBCP.equals(connectionPoolLib)) {
+            return createDbcpDataSource(uri, username, password, maxActive, 
maxIdle, maxWait, timeBtwnEvictionRuns,
+                    minEvictableIdleTime, testWhileIdle, testOnBorrow, 
validationQuery, isolationLevel);
+        }
+        return createHikaricpDataSource(uri, username, password, maxActive, 
maxIdle, maxWait, minIdleConnections,
+                connectionTimeout, keepAliveTime, isolationLevel, dsName);
+    }
+
+    private static DataSource createHikaricpDataSource(String uri, String 
username, String password,
                                                Integer maxActive, Integer 
maxIdle, Long maxWait,
-                                               Long timeBtwnEvictionRuns, Long 
minEvictableIdleTime,
-                                               Boolean testWhileIdle, Boolean 
testOnBorrow,
-                                               String validationQuery, Integer 
isolationLevel) {
+                                               Integer minIdleConnections, 
Long connectionTimeout, Long keepAliveTime,
+                                               Integer isolationLevel, String 
dsName) {
+        HikariConfig config = new HikariConfig();
+        config.setJdbcUrl(uri);
+        config.setUsername(username);
+        config.setPassword(password);
+
+        config.setPoolName(dsName);
+
+        // Connection pool properties
+        config.setMaximumPoolSize(ObjectUtils.defaultIfNull(maxActive, 250));
+        config.setIdleTimeout(ObjectUtils.defaultIfNull(maxIdle, 30) * 1000);
+        config.setMaxLifetime(ObjectUtils.defaultIfNull(maxWait, 600000L));
+        config.setMinimumIdle(ObjectUtils.defaultIfNull(minIdleConnections, 
5));
+        
config.setConnectionTimeout(ObjectUtils.defaultIfNull(connectionTimeout, 
30000L));
+        config.setKeepaliveTime(ObjectUtils.defaultIfNull(keepAliveTime, 
600000L));
+
+        String isolationLevelString = "TRANSACTION_READ_COMMITTED";
+        if (isolationLevel == Connection.TRANSACTION_SERIALIZABLE) {
+            isolationLevelString = "TRANSACTION_SERIALIZABLE";
+        } else if (isolationLevel == Connection.TRANSACTION_READ_UNCOMMITTED) {
+            isolationLevelString = "TRANSACTION_READ_UNCOMMITTED";
+        } else if (isolationLevel == Connection.TRANSACTION_REPEATABLE_READ) {
+            isolationLevelString = "TRANSACTION_REPEATABLE_READ";
+        }
+        config.setTransactionIsolation(isolationLevelString);
+
+        // Standard datasource config for MySQL
+        config.addDataSourceProperty("cachePrepStmts", "true");
+        config.addDataSourceProperty("prepStmtCacheSize", "250");
+        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
+        // Additional config for MySQL
+        config.addDataSourceProperty("useServerPrepStmts", "true");
+        config.addDataSourceProperty("useLocalSessionState", "true");
+        config.addDataSourceProperty("rewriteBatchedStatements", "true");
+        config.addDataSourceProperty("cacheResultSetMetadata", "true");
+        config.addDataSourceProperty("cacheServerConfiguration", "true");
+        config.addDataSourceProperty("elideSetAutoCommits", "true");
+        config.addDataSourceProperty("maintainTimeStats", "false");
+
+        HikariDataSource dataSource = new HikariDataSource(config);
+        return dataSource;
+    }
+
+    private static DataSource createDbcpDataSource(String uri, String 
username, String password,
+                                                Integer maxActive, Integer 
maxIdle, Long maxWait,
+                                                Long timeBtwnEvictionRuns, 
Long minEvictableIdleTime,
+                                                Boolean testWhileIdle, Boolean 
testOnBorrow,
+                                                String validationQuery, 
Integer isolationLevel) {
         ConnectionFactory connectionFactory = new 
DriverManagerConnectionFactory(uri, username, password);
         PoolableConnectionFactory poolableConnectionFactory = new 
PoolableConnectionFactory(connectionFactory, null);
         GenericObjectPoolConfig config = createPoolConfig(maxActive, maxIdle, 
maxWait, timeBtwnEvictionRuns, minEvictableIdleTime, testWhileIdle, 
testOnBorrow);
@@ -1267,6 +1362,44 @@ public class TransactionLegacy implements Closeable {
         return config;
     }
 
+    private static DataSource getDefaultDataSource(final String 
connectionPoolLib, final String database) {
+        LOGGER.debug("Creating default datasource for database: {} with 
connection pool lib: {}",
+                database, connectionPoolLib);
+        if (CONNECTION_POOL_LIB_DBCP.equalsIgnoreCase(connectionPoolLib)) {
+            return getDefaultDbcpDataSource(database);
+        }
+        return getDefaultHikaricpDataSource(database);
+    }
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    private static DataSource getDefaultHikaricpDataSource(final String 
database) {
+        HikariConfig config = new HikariConfig();
+        config.setJdbcUrl("jdbc:mysql://localhost:3306/" + database + "?" + 
CONNECTION_PARAMS);
+        config.setUsername("cloud");
+        config.setPassword("cloud");
+        config.setPoolName(database);
+        config.setDriverClassName("com.mysql.cj.jdbc.Driver");
+        config.setMaximumPoolSize(250);
+        config.setConnectionTimeout(1000);
+        config.setIdleTimeout(1000);
+        config.setKeepaliveTime(1000);
+        config.setMaxLifetime(1000);
+        config.setTransactionIsolation("TRANSACTION_READ_COMMITTED");
+        config.setInitializationFailTimeout(-1L);
+        config.addDataSourceProperty("cachePrepStmts", "true");
+        config.addDataSourceProperty("prepStmtCacheSize", "250");
+        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
+        return new HikariDataSource(config);
+    }
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    private static DataSource getDefaultDbcpDataSource(final String database) {
+        final ConnectionFactory connectionFactory = new 
DriverManagerConnectionFactory("jdbc:mysql://localhost:3306/" + database  + "?" 
+ CONNECTION_PARAMS, "cloud", "cloud");
+        final PoolableConnectionFactory poolableConnectionFactory = new 
PoolableConnectionFactory(connectionFactory, null);
+        final GenericObjectPool connectionPool = new 
GenericObjectPool(poolableConnectionFactory);
+        return new PoolingDataSource(connectionPool);
+    }
+
     private static String getDBHAParams(String dbName, Properties dbProps) {
         StringBuilder sb = new StringBuilder();
         sb.append("failOverReadOnly=" + dbProps.getProperty("db." + dbName + 
".failOverReadOnly"));
@@ -1278,14 +1411,6 @@ public class TransactionLegacy implements Closeable {
         return sb.toString();
     }
 
-    @SuppressWarnings({"unchecked", "rawtypes"})
-    private static DataSource getDefaultDataSource(final String database) {
-        final ConnectionFactory connectionFactory = new 
DriverManagerConnectionFactory("jdbc:mysql://localhost:3306/" + database  + "?" 
+ CONNECTION_PARAMS, "cloud", "cloud");
-        final PoolableConnectionFactory poolableConnectionFactory = new 
PoolableConnectionFactory(connectionFactory, null);
-        final GenericObjectPool connectionPool = new 
GenericObjectPool(poolableConnectionFactory);
-        return new PoolingDataSource(connectionPool);
-    }
-
     /**
      * Used for unit testing primarily
      *
diff --git a/plugins/network-elements/globodns/pom.xml 
b/plugins/network-elements/globodns/pom.xml
index e27a4a54d16..c0200921f20 100644
--- a/plugins/network-elements/globodns/pom.xml
+++ b/plugins/network-elements/globodns/pom.xml
@@ -32,5 +32,10 @@
             <groupId>com.globo.globodns</groupId>
             <artifactId>globodns-client</artifactId>
         </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/plugins/network-elements/tungsten/pom.xml 
b/plugins/network-elements/tungsten/pom.xml
index b0a46b1331a..1345268d313 100644
--- a/plugins/network-elements/tungsten/pom.xml
+++ b/plugins/network-elements/tungsten/pom.xml
@@ -47,5 +47,10 @@
             <groupId>ch.qos.reload4j</groupId>
             <artifactId>reload4j</artifactId>
         </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/pom.xml b/pom.xml
index 2ed3f8301cc..1acea98096f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -102,6 +102,7 @@
         <cs.configuration.version>1.10</cs.configuration.version>
         <cs.daemon.version>1.3.3</cs.daemon.version>
         <cs.dbcp.version>2.9.0</cs.dbcp.version>
+        <cs.hikaricp.version>5.1.0</cs.hikaricp.version>
         <cs.discovery.version>0.5</cs.discovery.version>
         <cs.lang.version>2.6</cs.lang.version>
         <cs.pool.version>2.9.0</cs.pool.version>
@@ -364,6 +365,7 @@
                 <artifactId>commons-daemon</artifactId>
                 <version>${cs.daemon.version}</version>
             </dependency>
+
             <dependency>
                 <groupId>org.apache.commons</groupId>
                 <artifactId>commons-dbcp2</artifactId>
@@ -375,6 +377,11 @@
                     </exclusion>
                 </exclusions>
             </dependency>
+            <dependency>
+                <groupId>com.zaxxer</groupId>
+                <artifactId>HikariCP</artifactId>
+                <version>${cs.hikaricp.version}</version>
+            </dependency>
             <dependency>
                 <groupId>commons-discovery</groupId>
                 <artifactId>commons-discovery</artifactId>
@@ -455,6 +462,12 @@
                 <artifactId>reload4j</artifactId>
                 <version>${cs.reload4j.version}</version>
             </dependency>
+            <dependency>
+                <groupId>mysql</groupId>
+                <artifactId>mysql-connector-java</artifactId>
+                <version>${cs.mysql.version}</version>
+                <scope>test</scope>
+            </dependency>
             <dependency>
                 <groupId>log4j</groupId>
                 <artifactId>apache-log4j-extras</artifactId>
diff --git a/server/pom.xml b/server/pom.xml
index 269583c381a..ec157b00e30 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -164,6 +164,11 @@
             <artifactId>cloud-framework-agent-lb</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-db</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.cloudstack</groupId>
             <artifactId>cloud-engine-storage-configdrive</artifactId>
diff --git a/usage/conf/db.properties.in b/usage/conf/db.properties.in
index 35a40def7b1..c597bb9fad3 100644
--- a/usage/conf/db.properties.in
+++ b/usage/conf/db.properties.in
@@ -24,7 +24,11 @@ db.usage.port=3306
 db.usage.name=cloud_usage
 
 # usage database tuning parameters
+db.usage.connectionPoolLib=hikaricp
 db.usage.maxActive=100
 db.usage.maxIdle=30
 db.usage.maxWait=10000
+db.usage.minIdleConnections=5
+db.usage.connectionTimeout=30000
+db.usage.keepAliveTime=600000
 db.usage.autoReconnect=true

Reply via email to