This is an automated email from the ASF dual-hosted git repository.
wlo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/gobblin.git
The following commit(s) were added to refs/heads/master by this push:
new 72bf8d5d1 [GOBBLIN-1753] Migrate DB connection pool from
o.a.commons.dbcp/dbcp2 to HikariCP (#3613)
72bf8d5d1 is described below
commit 72bf8d5d10ad77d3c54cc88202e05890231f9da4
Author: Kip Kohn <[email protected]>
AuthorDate: Tue Dec 6 09:14:34 2022 -0800
[GOBBLIN-1753] Migrate DB connection pool from o.a.commons.dbcp/dbcp2 to
HikariCP (#3613)
* [GOBBLIN-1753] Migrate DB connection pool from o.a.commons.dbcp/dbcp2 to
HikariCP
* minor change to use `Duration`
---
.../gobblin/configuration/ConfigurationKeys.java | 4 ---
gobblin-core/build.gradle | 2 +-
.../CleanableMysqlDatasetStoreDatasetTest.java | 16 ++++-----
.../retention/sql/SqlBasedRetentionPoc.java | 15 ++++----
gobblin-metastore/build.gradle | 2 +-
.../metastore/JobHistoryDataSourceProvider.java | 22 ++++++++----
.../metastore/MysqlDagStateStoreFactory.java | 6 ++--
.../gobblin/metastore/MysqlDataSourceFactory.java | 19 +++++-----
.../gobblin/metastore/MysqlDataSourceKey.java | 4 +--
.../metastore/MysqlJobStatusStateStoreFactory.java | 6 ++--
.../apache/gobblin/metastore/MysqlStateStore.java | 40 ++++++++++++----------
.../gobblin/metastore/MysqlStateStoreFactory.java | 6 ++--
.../metastore/MysqlDataSourceFactoryTest.java | 20 +++++------
.../AvroToJdbcEntryConverterInitializer.java | 2 +-
.../apache/gobblin/publisher/JdbcPublisher.java | 2 +-
.../apache/gobblin/source/jdbc/JdbcProvider.java | 22 +++++++-----
.../java/org/apache/gobblin/writer/JdbcWriter.java | 2 +-
.../writer/initializer/JdbcWriterInitializer.java | 2 +-
.../runtime/MysqlDatasetStateStoreFactory.java | 6 ++--
.../runtime/spec_store/MysqlBaseSpecStore.java | 12 ++++---
.../runtime/MysqlDatasetStateStoreTest.java | 16 ++++-----
.../gobblin/runtime/cli/JobStateStoreCliTest.java | 18 +++++-----
gobblin-service/build.gradle | 2 +-
.../modules/db/ServiceDatabaseProviderImpl.java | 30 ++++++++--------
.../orchestration/MysqlUserQuotaManager.java | 24 ++++++++-----
.../orchestration/MysqlDagStateStoreTest.java | 16 ++++-----
gobblin-utility/build.gradle | 2 +-
.../gobblin/util/jdbc/DataSourceBuilder.java | 12 -------
.../gobblin/util/jdbc/DataSourceProvider.java | 39 +++++++++++----------
gradle/scripts/dependencyDefinitions.gradle | 3 +-
30 files changed, 195 insertions(+), 177 deletions(-)
diff --git
a/gobblin-api/src/main/java/org/apache/gobblin/configuration/ConfigurationKeys.java
b/gobblin-api/src/main/java/org/apache/gobblin/configuration/ConfigurationKeys.java
index cb5f664e8..4344f3575 100644
---
a/gobblin-api/src/main/java/org/apache/gobblin/configuration/ConfigurationKeys.java
+++
b/gobblin-api/src/main/java/org/apache/gobblin/configuration/ConfigurationKeys.java
@@ -75,10 +75,6 @@ public class ConfigurationKeys {
// DB state store configuration
public static final String STATE_STORE_DB_JDBC_DRIVER_KEY =
"state.store.db.jdbc.driver";
public static final String DEFAULT_STATE_STORE_DB_JDBC_DRIVER =
"com.mysql.jdbc.Driver";
- // min idle time for eviction
- public static final String STATE_STORE_DB_CONN_MIN_EVICTABLE_IDLE_TIME_KEY =
- "state.store.db.conn.min.evictable.idle.time";
- public static final long DEFAULT_STATE_STORE_DB_CONN_MIN_EVICTABLE_IDLE_TIME
= 5 * 60 * 1000;
public static final String STATE_STORE_DB_URL_KEY = "state.store.db.url";
public static final String STATE_STORE_DB_USER_KEY = "state.store.db.user";
public static final String STATE_STORE_DB_PASSWORD_KEY =
"state.store.db.password";
diff --git a/gobblin-core/build.gradle b/gobblin-core/build.gradle
index 9ca24678d..7daa1a9b3 100644
--- a/gobblin-core/build.gradle
+++ b/gobblin-core/build.gradle
@@ -32,7 +32,6 @@ dependencies {
compile externalDependency.avroMapredH2
compile externalDependency.commonsCodec
- compile externalDependency.commonsDbcp
compile externalDependency.commonsMath
compile externalDependency.commonsHttpClient
compile externalDependency.avro
@@ -46,6 +45,7 @@ dependencies {
compile externalDependency.jsch
compile externalDependency.commonsLang3
compile externalDependency.commonsIo
+ compile externalDependency.hikariCP
compile externalDependency.hiveExec
compile externalDependency.hiveSerDe
compile externalDependency.httpclient
diff --git
a/gobblin-data-management/src/test/java/org/apache/gobblin/data/management/retention/CleanableMysqlDatasetStoreDatasetTest.java
b/gobblin-data-management/src/test/java/org/apache/gobblin/data/management/retention/CleanableMysqlDatasetStoreDatasetTest.java
index fad2df795..c0d0719cb 100644
---
a/gobblin-data-management/src/test/java/org/apache/gobblin/data/management/retention/CleanableMysqlDatasetStoreDatasetTest.java
+++
b/gobblin-data-management/src/test/java/org/apache/gobblin/data/management/retention/CleanableMysqlDatasetStoreDatasetTest.java
@@ -20,7 +20,6 @@ package org.apache.gobblin.data.management.retention;
import java.io.IOException;
import java.util.List;
-import org.apache.commons.dbcp.BasicDataSource;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.testng.Assert;
@@ -29,6 +28,7 @@ import org.testng.annotations.Test;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigValueFactory;
+import com.zaxxer.hikari.HikariDataSource;
import org.apache.gobblin.config.ConfigBuilder;
import org.apache.gobblin.configuration.ConfigurationKeys;
@@ -78,15 +78,15 @@ public class CleanableMysqlDatasetStoreDatasetTest {
this.testMetastoreDatabase = TestMetastoreDatabaseFactory.get();
String jdbcUrl = this.testMetastoreDatabase.getJdbcUrl();
ConfigBuilder configBuilder = ConfigBuilder.create();
- BasicDataSource mySqlDs = new BasicDataSource();
+ HikariDataSource dataSource = new HikariDataSource();
-
mySqlDs.setDriverClassName(ConfigurationKeys.DEFAULT_STATE_STORE_DB_JDBC_DRIVER);
- mySqlDs.setDefaultAutoCommit(false);
- mySqlDs.setUrl(jdbcUrl);
- mySqlDs.setUsername(TEST_USER);
- mySqlDs.setPassword(TEST_PASSWORD);
+
dataSource.setDriverClassName(ConfigurationKeys.DEFAULT_STATE_STORE_DB_JDBC_DRIVER);
+ dataSource.setAutoCommit(false);
+ dataSource.setJdbcUrl(jdbcUrl);
+ dataSource.setUsername(TEST_USER);
+ dataSource.setPassword(TEST_PASSWORD);
- this.dbJobStateStore = new MysqlStateStore<>(mySqlDs, TEST_STATE_STORE,
false, JobState.class);
+ this.dbJobStateStore = new MysqlStateStore<>(dataSource, TEST_STATE_STORE,
false, JobState.class);
configBuilder.addPrimitive("selection.timeBased.lookbackTime", "10m");
configBuilder.addPrimitive(ConfigurationKeys.STATE_STORE_TYPE_KEY,
"mysql");
diff --git
a/gobblin-data-management/src/test/java/org/apache/gobblin/data/management/retention/sql/SqlBasedRetentionPoc.java
b/gobblin-data-management/src/test/java/org/apache/gobblin/data/management/retention/sql/SqlBasedRetentionPoc.java
index ab62d5bcd..e7899f800 100644
---
a/gobblin-data-management/src/test/java/org/apache/gobblin/data/management/retention/sql/SqlBasedRetentionPoc.java
+++
b/gobblin-data-management/src/test/java/org/apache/gobblin/data/management/retention/sql/SqlBasedRetentionPoc.java
@@ -22,7 +22,8 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
-import org.apache.commons.dbcp.BasicDataSource;
+import com.zaxxer.hikari.HikariDataSource;
+
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.fs.Path;
import org.joda.time.DateTime;
@@ -42,7 +43,7 @@ public class SqlBasedRetentionPoc {
private static final int TWO_YEARS_IN_DAYS = 365 * 2;
private static final String DAILY_PARTITION_PATTERN = "yyyy/MM/dd";
- private BasicDataSource basicDataSource;
+ private HikariDataSource dataSource;
private Connection connection;
/**
@@ -55,11 +56,11 @@ public class SqlBasedRetentionPoc {
*/
@BeforeClass
public void setup() throws SQLException {
- basicDataSource = new BasicDataSource();
- basicDataSource.setDriverClassName("org.apache.derby.jdbc.EmbeddedDriver");
- basicDataSource.setUrl("jdbc:derby:memory:derbypoc;create=true");
+ dataSource = new HikariDataSource();
+ dataSource.setDriverClassName("org.apache.derby.jdbc.EmbeddedDriver");
+ dataSource.setJdbcUrl("jdbc:derby:memory:derbypoc;create=true");
- Connection connection = basicDataSource.getConnection();
+ Connection connection = dataSource.getConnection();
connection.setAutoCommit(false);
this.connection = connection;
@@ -72,7 +73,7 @@ public class SqlBasedRetentionPoc {
@AfterClass
public void cleanUp() throws Exception {
- basicDataSource.close();
+ dataSource.close();
}
/**
diff --git a/gobblin-metastore/build.gradle b/gobblin-metastore/build.gradle
index 2a0e85e26..7a0d83b2e 100644
--- a/gobblin-metastore/build.gradle
+++ b/gobblin-metastore/build.gradle
@@ -25,12 +25,12 @@ dependencies {
compile externalDependency.guava
compile externalDependency.slf4j
compile externalDependency.pegasus.data
- compile externalDependency.commonsDbcp
compile externalDependency.commonsLang
compile externalDependency.commonsLang3
compile externalDependency.guice
compile externalDependency.javaxInject
compile externalDependency.jodaTime
+ compile externalDependency.hikariCP
compile externalDependency.httpclient
compile externalDependency.flyway
compile externalDependency.commonsConfiguration
diff --git
a/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/JobHistoryDataSourceProvider.java
b/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/JobHistoryDataSourceProvider.java
index 73d0b0339..edf35d637 100644
---
a/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/JobHistoryDataSourceProvider.java
+++
b/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/JobHistoryDataSourceProvider.java
@@ -39,7 +39,7 @@ public class JobHistoryDataSourceProvider extends
org.apache.gobblin.util.jdbc.D
@Inject
public JobHistoryDataSourceProvider(@Named("dataSourceProperties")
Properties properties) {
-
this.basicDataSource.setDriverClassName(properties.getProperty(ConfigurationKeys.JOB_HISTORY_STORE_JDBC_DRIVER_KEY,
+
this.dataSource.setDriverClassName(properties.getProperty(ConfigurationKeys.JOB_HISTORY_STORE_JDBC_DRIVER_KEY,
ConfigurationKeys.DEFAULT_JOB_HISTORY_STORE_JDBC_DRIVER));
// Set validation query to verify connection
@@ -47,16 +47,24 @@ public class JobHistoryDataSourceProvider extends
org.apache.gobblin.util.jdbc.D
// MySQL server can timeout a connection so need to validate connections
before use
final String validationQuery =
MysqlDataSourceUtils.QUERY_CONNECTION_IS_VALID_AND_NOT_READONLY;
LOG.info("setting `DataSource` validation query: '" + validationQuery +
"'");
- this.basicDataSource.setValidationQuery(validationQuery);
- this.basicDataSource.setTestOnBorrow(true);
-
this.basicDataSource.setTimeBetweenEvictionRunsMillis(Duration.ofSeconds(60).toMillis());
+ // TODO: revisit following verification of successful connection pool
migration:
+ // If your driver supports JDBC4 we strongly recommend not setting
this property. This is for "legacy" drivers
+ // that do not support the JDBC4 Connection.isValid() API; see:
+ //
https://github.com/brettwooldridge/HikariCP#gear-configuration-knobs-baby
+ this.dataSource.setConnectionTestQuery(validationQuery);
+ this.dataSource.setIdleTimeout(Duration.ofSeconds(60).toMillis());
}
-
this.basicDataSource.setUrl(properties.getProperty(ConfigurationKeys.JOB_HISTORY_STORE_URL_KEY));
+
this.dataSource.setJdbcUrl(properties.getProperty(ConfigurationKeys.JOB_HISTORY_STORE_URL_KEY));
+ // TODO: revisit following verification of successful connection pool
migration:
+ // whereas `o.a.commons.dbcp.BasicDataSource` defaults min idle conns to
0, hikari defaults to 10.
+ // perhaps non-zero would have desirable runtime perf, but anything >0
currently fails unit tests (even 1!);
+ // (so experimenting with a higher number would first require adjusting
tests)
+ this.dataSource.setMinimumIdle(0);
if (properties.containsKey(ConfigurationKeys.JOB_HISTORY_STORE_USER_KEY)
&&
properties.containsKey(ConfigurationKeys.JOB_HISTORY_STORE_PASSWORD_KEY)) {
-
this.basicDataSource.setUsername(properties.getProperty(ConfigurationKeys.JOB_HISTORY_STORE_USER_KEY));
- this.basicDataSource.setPassword(PasswordManager.getInstance(properties)
+
this.dataSource.setUsername(properties.getProperty(ConfigurationKeys.JOB_HISTORY_STORE_USER_KEY));
+ this.dataSource.setPassword(PasswordManager.getInstance(properties)
.readPassword(properties.getProperty(ConfigurationKeys.JOB_HISTORY_STORE_PASSWORD_KEY)));
}
}
diff --git
a/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlDagStateStoreFactory.java
b/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlDagStateStoreFactory.java
index 5327c4b11..9282d51e1 100644
---
a/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlDagStateStoreFactory.java
+++
b/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlDagStateStoreFactory.java
@@ -17,7 +17,7 @@
package org.apache.gobblin.metastore;
-import org.apache.commons.dbcp.BasicDataSource;
+import javax.sql.DataSource;
import com.typesafe.config.Config;
@@ -37,10 +37,10 @@ public class MysqlDagStateStoreFactory extends
MysqlStateStoreFactory {
ConfigurationKeys.DEFAULT_STATE_STORE_COMPRESSED_VALUES);
try {
- BasicDataSource basicDataSource = MysqlDataSourceFactory.get(config,
+ DataSource dataSource = MysqlDataSourceFactory.get(config,
SharedResourcesBrokerFactory.getImplicitBroker());
- return new MysqlDagStore<>(basicDataSource, stateStoreTableName,
compressedValues, stateClass);
+ return new MysqlDagStore<>(dataSource, stateStoreTableName,
compressedValues, stateClass);
} catch (Exception e) {
throw new RuntimeException("Failed to create MysqlDagStore with
factory", e);
}
diff --git
a/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlDataSourceFactory.java
b/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlDataSourceFactory.java
index 45bd045ef..c00e011df 100644
---
a/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlDataSourceFactory.java
+++
b/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlDataSourceFactory.java
@@ -19,7 +19,7 @@ package org.apache.gobblin.metastore;
import java.io.IOException;
-import org.apache.commons.dbcp.BasicDataSource;
+import javax.sql.DataSource;
import com.typesafe.config.Config;
@@ -35,24 +35,25 @@ import
org.apache.gobblin.broker.iface.SharedResourcesBroker;
import lombok.extern.slf4j.Slf4j;
/**
- * A {@link SharedResourceFactory} for creating {@link BasicDataSource}s.
+ * A {@link SharedResourceFactory} for creating {@link DataSource}s.
*
- * The factory creates a {@link BasicDataSource} with the config.
+ * The factory creates a {@link DataSource} with the config.
*/
@Slf4j
public class MysqlDataSourceFactory<S extends ScopeType<S>>
- implements SharedResourceFactory<BasicDataSource, MysqlDataSourceKey, S> {
+ implements SharedResourceFactory<DataSource, MysqlDataSourceKey, S> {
+ // WARNING: now a misnomer, but retained for legacy compatibility, despite
move from `o.a.commons.dbcp.BasicDataSource` to `HikariCP`
public static final String FACTORY_NAME = "basicDataSource";
/**
- * Get a {@link BasicDataSource} based on the config
+ * Get a {@link DataSource} based on the config
* @param config configuration
* @param broker broker
- * @return a {@link BasicDataSource}
+ * @return a {@link DataSource}
* @throws IOException
*/
- public static <S extends ScopeType<S>> BasicDataSource get(Config config,
+ public static <S extends ScopeType<S>> DataSource get(Config config,
SharedResourcesBroker<S> broker) throws IOException {
try {
return broker.getSharedResource(new MysqlDataSourceFactory<S>(),
@@ -68,12 +69,12 @@ public class MysqlDataSourceFactory<S extends ScopeType<S>>
}
@Override
- public SharedResourceFactoryResponse<BasicDataSource>
createResource(SharedResourcesBroker<S> broker,
+ public SharedResourceFactoryResponse<DataSource>
createResource(SharedResourcesBroker<S> broker,
ScopedConfigView<S, MysqlDataSourceKey> config) throws
NotConfiguredException {
MysqlDataSourceKey key = config.getKey();
Config configuration = key.getConfig();
- BasicDataSource dataSource = MysqlStateStore.newDataSource(configuration);
+ DataSource dataSource = MysqlStateStore.newDataSource(configuration);
return new ResourceInstance<>(dataSource);
}
diff --git
a/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlDataSourceKey.java
b/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlDataSourceKey.java
index bccab28f5..5e8b20927 100644
---
a/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlDataSourceKey.java
+++
b/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlDataSourceKey.java
@@ -17,7 +17,7 @@
package org.apache.gobblin.metastore;
-import org.apache.commons.dbcp.BasicDataSource;
+import javax.sql.DataSource;
import com.typesafe.config.Config;
@@ -26,7 +26,7 @@ import org.apache.gobblin.broker.iface.SharedResourceKey;
import lombok.Getter;
/**
- * {@link SharedResourceKey} for requesting {@link BasicDataSource}s from a
+ * {@link SharedResourceKey} for requesting {@link DataSource}s from a
* {@link org.apache.gobblin.broker.iface.SharedResourceFactory}
*/
@Getter
diff --git
a/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlJobStatusStateStoreFactory.java
b/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlJobStatusStateStoreFactory.java
index 5a2c68473..34d34d478 100644
---
a/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlJobStatusStateStoreFactory.java
+++
b/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlJobStatusStateStoreFactory.java
@@ -17,7 +17,7 @@
package org.apache.gobblin.metastore;
-import org.apache.commons.dbcp.BasicDataSource;
+import javax.sql.DataSource;
import com.typesafe.config.Config;
@@ -36,10 +36,10 @@ public class MysqlJobStatusStateStoreFactory extends
MysqlStateStoreFactory impl
ConfigurationKeys.DEFAULT_STATE_STORE_COMPRESSED_VALUES);
try {
- BasicDataSource basicDataSource = MysqlDataSourceFactory.get(config,
+ DataSource dataSource = MysqlDataSourceFactory.get(config,
SharedResourcesBrokerFactory.getImplicitBroker());
- return new MysqlJobStatusStateStore<>(basicDataSource,
stateStoreTableName, compressedValues, stateClass);
+ return new MysqlJobStatusStateStore<>(dataSource, stateStoreTableName,
compressedValues, stateClass);
} catch (Exception e) {
throw new RuntimeException("Failed to create MysqlStateStore with
factory", e);
}
diff --git
a/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlStateStore.java
b/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlStateStore.java
index f75cddc5a..3bbf8747b 100644
---
a/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlStateStore.java
+++
b/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlStateStore.java
@@ -38,11 +38,11 @@ import java.util.Collections;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
+import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.commons.dbcp.BasicDataSource;
import org.apache.hadoop.io.Text;
import com.google.common.annotations.VisibleForTesting;
@@ -50,8 +50,7 @@ import com.google.common.base.Predicate;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.typesafe.config.Config;
-
-import javax.sql.DataSource;
+import com.zaxxer.hikari.HikariDataSource;
import org.apache.gobblin.configuration.ConfigurationKeys;
import org.apache.gobblin.configuration.State;
@@ -194,33 +193,38 @@ public class MysqlStateStore<T extends State> implements
StateStore<T> {
}
/**
- * creates a new {@link BasicDataSource}
+ * creates a new {@link DataSource}
* @param config the properties used for datasource instantiation
* @return
*/
- public static BasicDataSource newDataSource(Config config) {
- BasicDataSource basicDataSource = new BasicDataSource();
+ public static DataSource newDataSource(Config config) {
+ HikariDataSource dataSource = new HikariDataSource();
PasswordManager passwordManager =
PasswordManager.getInstance(ConfigUtils.configToProperties(config));
- basicDataSource.setDriverClassName(ConfigUtils.getString(config,
ConfigurationKeys.STATE_STORE_DB_JDBC_DRIVER_KEY,
+ dataSource.setDriverClassName(ConfigUtils.getString(config,
ConfigurationKeys.STATE_STORE_DB_JDBC_DRIVER_KEY,
ConfigurationKeys.DEFAULT_STATE_STORE_DB_JDBC_DRIVER));
// MySQL server can timeout a connection so need to validate connections
before use
final String validationQuery =
MysqlDataSourceUtils.QUERY_CONNECTION_IS_VALID_AND_NOT_READONLY;
LOG.info("setting `DataSource` validation query: '" + validationQuery +
"'");
- basicDataSource.setValidationQuery(validationQuery);
- basicDataSource.setTestOnBorrow(true);
- basicDataSource.setDefaultAutoCommit(false);
-
basicDataSource.setTimeBetweenEvictionRunsMillis(Duration.ofSeconds(60).toMillis());
-
basicDataSource.setUrl(config.getString(ConfigurationKeys.STATE_STORE_DB_URL_KEY));
- basicDataSource.setUsername(passwordManager.readPassword(
+ // TODO: revisit following verification of successful connection pool
migration:
+ // If your driver supports JDBC4 we strongly recommend not setting this
property. This is for "legacy" drivers
+ // that do not support the JDBC4 Connection.isValid() API; see:
+ //
https://github.com/brettwooldridge/HikariCP#gear-configuration-knobs-baby
+ dataSource.setConnectionTestQuery(validationQuery);
+ dataSource.setAutoCommit(false);
+ dataSource.setIdleTimeout(Duration.ofSeconds(60).toMillis());
+
dataSource.setJdbcUrl(config.getString(ConfigurationKeys.STATE_STORE_DB_URL_KEY));
+ // TODO: revisit following verification of successful connection pool
migration:
+ // whereas `o.a.commons.dbcp.BasicDataSource` defaults min idle conns to
0, hikari defaults to 10.
+ // perhaps non-zero would have desirable runtime perf, but anything >0
currently fails unit tests (even 1!);
+ // (so experimenting with a higher number would first require adjusting
tests)
+ dataSource.setMinimumIdle(0);
+ dataSource.setUsername(passwordManager.readPassword(
config.getString(ConfigurationKeys.STATE_STORE_DB_USER_KEY)));
- basicDataSource.setPassword(passwordManager.readPassword(
+ dataSource.setPassword(passwordManager.readPassword(
config.getString(ConfigurationKeys.STATE_STORE_DB_PASSWORD_KEY)));
- basicDataSource.setMinEvictableIdleTimeMillis(
- ConfigUtils.getLong(config,
ConfigurationKeys.STATE_STORE_DB_CONN_MIN_EVICTABLE_IDLE_TIME_KEY,
-
ConfigurationKeys.DEFAULT_STATE_STORE_DB_CONN_MIN_EVICTABLE_IDLE_TIME));
- return basicDataSource;
+ return dataSource;
}
/**
diff --git
a/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlStateStoreFactory.java
b/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlStateStoreFactory.java
index fc9e362d7..eccb0cd59 100644
---
a/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlStateStoreFactory.java
+++
b/gobblin-metastore/src/main/java/org/apache/gobblin/metastore/MysqlStateStoreFactory.java
@@ -16,7 +16,7 @@
*/
package org.apache.gobblin.metastore;
-import org.apache.commons.dbcp.BasicDataSource;
+import javax.sql.DataSource;
import com.typesafe.config.Config;
@@ -36,10 +36,10 @@ public class MysqlStateStoreFactory implements
StateStore.Factory {
ConfigurationKeys.DEFAULT_STATE_STORE_COMPRESSED_VALUES);
try {
- BasicDataSource basicDataSource = MysqlDataSourceFactory.get(config,
+ DataSource dataSource = MysqlDataSourceFactory.get(config,
SharedResourcesBrokerFactory.getImplicitBroker());
- return new MysqlStateStore<>(basicDataSource, stateStoreTableName,
compressedValues, stateClass);
+ return new MysqlStateStore<>(dataSource, stateStoreTableName,
compressedValues, stateClass);
} catch (Exception e) {
throw new RuntimeException("Failed to create MysqlStateStore with
factory", e);
}
diff --git
a/gobblin-metastore/src/test/java/org/apache/gobblin/metastore/MysqlDataSourceFactoryTest.java
b/gobblin-metastore/src/test/java/org/apache/gobblin/metastore/MysqlDataSourceFactoryTest.java
index a11a4aff4..40e0aaa31 100644
---
a/gobblin-metastore/src/test/java/org/apache/gobblin/metastore/MysqlDataSourceFactoryTest.java
+++
b/gobblin-metastore/src/test/java/org/apache/gobblin/metastore/MysqlDataSourceFactoryTest.java
@@ -17,8 +17,8 @@
package org.apache.gobblin.metastore;
import java.io.IOException;
+import javax.sql.DataSource;
-import org.apache.commons.dbcp.BasicDataSource;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -42,13 +42,13 @@ public class MysqlDataSourceFactoryTest {
ConfigurationKeys.STATE_STORE_DB_USER_KEY, "user",
ConfigurationKeys.STATE_STORE_DB_PASSWORD_KEY, "dummypwd"));
- BasicDataSource basicDataSource1 = MysqlDataSourceFactory.get(config,
+ DataSource dataSource1 = MysqlDataSourceFactory.get(config,
SharedResourcesBrokerFactory.getImplicitBroker());
- BasicDataSource basicDataSource2 = MysqlDataSourceFactory.get(config,
+ DataSource dataSource2 = MysqlDataSourceFactory.get(config,
SharedResourcesBrokerFactory.getImplicitBroker());
- Assert.assertEquals(basicDataSource1, basicDataSource2);
+ Assert.assertEquals(dataSource1, dataSource2);
}
@Test
@@ -62,13 +62,13 @@ public class MysqlDataSourceFactoryTest {
ConfigurationKeys.STATE_STORE_DB_USER_KEY, "user",
ConfigurationKeys.STATE_STORE_DB_PASSWORD_KEY, "dummypwd"));
- BasicDataSource basicDataSource1 = MysqlDataSourceFactory.get(config1,
+ DataSource dataSource1 = MysqlDataSourceFactory.get(config1,
SharedResourcesBrokerFactory.getImplicitBroker());
- BasicDataSource basicDataSource2 = MysqlDataSourceFactory.get(config2,
+ DataSource dataSource2 = MysqlDataSourceFactory.get(config2,
SharedResourcesBrokerFactory.getImplicitBroker());
- Assert.assertNotEquals(basicDataSource1, basicDataSource2);
+ Assert.assertNotEquals(dataSource1, dataSource2);
}
@Test
@@ -82,12 +82,12 @@ public class MysqlDataSourceFactoryTest {
ConfigurationKeys.STATE_STORE_DB_USER_KEY, "user2",
ConfigurationKeys.STATE_STORE_DB_PASSWORD_KEY, "dummypwd"));
- BasicDataSource basicDataSource1 = MysqlDataSourceFactory.get(config1,
+ DataSource dataSource1 = MysqlDataSourceFactory.get(config1,
SharedResourcesBrokerFactory.getImplicitBroker());
- BasicDataSource basicDataSource2 = MysqlDataSourceFactory.get(config2,
+ DataSource dataSource2 = MysqlDataSourceFactory.get(config2,
SharedResourcesBrokerFactory.getImplicitBroker());
- Assert.assertNotEquals(basicDataSource1, basicDataSource2);
+ Assert.assertNotEquals(dataSource1, dataSource2);
}
}
diff --git
a/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/converter/initializer/AvroToJdbcEntryConverterInitializer.java
b/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/converter/initializer/AvroToJdbcEntryConverterInitializer.java
index d3ca9f9c7..1802da98f 100644
---
a/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/converter/initializer/AvroToJdbcEntryConverterInitializer.java
+++
b/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/converter/initializer/AvroToJdbcEntryConverterInitializer.java
@@ -108,7 +108,7 @@ public class AvroToJdbcEntryConverterInitializer implements
ConverterInitializer
.userName(this.state.getProp(JdbcPublisher.JDBC_PUBLISHER_USERNAME))
.passWord(this.state.getProp(JdbcPublisher.JDBC_PUBLISHER_PASSWORD))
.cryptoKeyLocation(this.state.getProp(JdbcPublisher.JDBC_PUBLISHER_ENCRYPTION_KEY_LOC)).maxActiveConnections(1)
- .maxIdleConnections(1).state(this.state).build();
+ .state(this.state).build();
return dataSource.getConnection();
}
diff --git
a/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/publisher/JdbcPublisher.java
b/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/publisher/JdbcPublisher.java
index 4561bb651..cf4909bcf 100644
---
a/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/publisher/JdbcPublisher.java
+++
b/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/publisher/JdbcPublisher.java
@@ -106,7 +106,7 @@ public class JdbcPublisher extends DataPublisher {
.driver(this.state.getProp(JDBC_PUBLISHER_DRIVER)).userName(this.state.getProp(JDBC_PUBLISHER_USERNAME))
.passWord(this.state.getProp(JDBC_PUBLISHER_PASSWORD))
.cryptoKeyLocation(this.state.getProp(JDBC_PUBLISHER_ENCRYPTION_KEY_LOC)).maxActiveConnections(1)
- .maxIdleConnections(1).state(this.state).build();
+ .state(this.state).build();
try {
return dataSource.getConnection();
} catch (SQLException e) {
diff --git
a/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/source/jdbc/JdbcProvider.java
b/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/source/jdbc/JdbcProvider.java
index 6775f224e..db6494088 100644
---
a/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/source/jdbc/JdbcProvider.java
+++
b/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/source/jdbc/JdbcProvider.java
@@ -17,11 +17,11 @@
package org.apache.gobblin.source.jdbc;
+import java.io.IOException;
+
import org.apache.gobblin.tunnel.Tunnel;
-import org.apache.commons.dbcp.BasicDataSource;
-import java.io.IOException;
-import java.sql.SQLException;
+import com.zaxxer.hikari.HikariDataSource;
/**
@@ -29,7 +29,7 @@ import java.sql.SQLException;
*
* @author nveeramr
*/
-public class JdbcProvider extends BasicDataSource {
+public class JdbcProvider extends HikariDataSource {
private Tunnel tunnel;
// If extract type is not provided then consider it as a default type
@@ -76,14 +76,18 @@ public class JdbcProvider extends BasicDataSource {
this.setDriverClassName(driver);
this.setUsername(user);
this.setPassword(password);
- this.setUrl(connectionUrl);
- this.setInitialSize(0);
- this.setMaxIdle(numconn);
- this.setMaxWait(timeout);
+ this.setJdbcUrl(connectionUrl);
+ // TODO: revisit following verification of successful connection pool
migration:
+ // whereas `o.a.commons.dbcp.BasicDataSource` defaults min idle conns to
0, hikari defaults to 10.
+ // perhaps non-zero would have desirable runtime perf, but anything >0
currently fails unit tests (even 1!);
+ // (so experimenting with a higher number would first require adjusting
tests)
+ this.setMinimumIdle(0);
+ this.setMaximumPoolSize(numconn);
+ this.setConnectionTimeout(timeout);
}
@Override
- public synchronized void close() throws SQLException {
+ public synchronized void close() {
super.close();
if (this.tunnel != null) {
this.tunnel.close();
diff --git
a/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/writer/JdbcWriter.java
b/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/writer/JdbcWriter.java
index 7404f30db..c30a453e9 100644
---
a/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/writer/JdbcWriter.java
+++
b/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/writer/JdbcWriter.java
@@ -116,7 +116,7 @@ public class JdbcWriter implements
DataWriter<JdbcEntryData> {
.userName(this.state.getProp(JdbcPublisher.JDBC_PUBLISHER_USERNAME))
.passWord(this.state.getProp(JdbcPublisher.JDBC_PUBLISHER_PASSWORD))
.cryptoKeyLocation(this.state.getProp(JdbcPublisher.JDBC_PUBLISHER_ENCRYPTION_KEY_LOC)).maxActiveConnections(1)
- .maxIdleConnections(1).state(this.state).build();
+ .state(this.state).build();
return dataSource.getConnection();
}
diff --git
a/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/writer/initializer/JdbcWriterInitializer.java
b/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/writer/initializer/JdbcWriterInitializer.java
index bdaf1e1cc..8226de769 100644
---
a/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/writer/initializer/JdbcWriterInitializer.java
+++
b/gobblin-modules/gobblin-sql/src/main/java/org/apache/gobblin/writer/initializer/JdbcWriterInitializer.java
@@ -132,7 +132,7 @@ public class JdbcWriterInitializer implements
WriterInitializer {
.userName(this.state.getProp(JdbcPublisher.JDBC_PUBLISHER_USERNAME))
.passWord(this.state.getProp(JdbcPublisher.JDBC_PUBLISHER_PASSWORD))
.cryptoKeyLocation(this.state.getProp(JdbcPublisher.JDBC_PUBLISHER_ENCRYPTION_KEY_LOC)).maxActiveConnections(1)
- .maxIdleConnections(1).state(this.state).build();
+ .state(this.state).build();
return dataSource.getConnection();
}
diff --git
a/gobblin-runtime/src/main/java/org/apache/gobblin/runtime/MysqlDatasetStateStoreFactory.java
b/gobblin-runtime/src/main/java/org/apache/gobblin/runtime/MysqlDatasetStateStoreFactory.java
index 8d5b29185..ce621bbbb 100644
---
a/gobblin-runtime/src/main/java/org/apache/gobblin/runtime/MysqlDatasetStateStoreFactory.java
+++
b/gobblin-runtime/src/main/java/org/apache/gobblin/runtime/MysqlDatasetStateStoreFactory.java
@@ -16,7 +16,7 @@
*/
package org.apache.gobblin.runtime;
-import org.apache.commons.dbcp.BasicDataSource;
+import javax.sql.DataSource;
import com.typesafe.config.Config;
@@ -38,10 +38,10 @@ public class MysqlDatasetStateStoreFactory implements
DatasetStateStore.Factory
ConfigurationKeys.DEFAULT_STATE_STORE_COMPRESSED_VALUES;
try {
- BasicDataSource basicDataSource = MysqlDataSourceFactory.get(config,
+ DataSource dataSource = MysqlDataSourceFactory.get(config,
SharedResourcesBrokerFactory.getImplicitBroker());
- return new MysqlDatasetStateStore(basicDataSource, stateStoreTableName,
compressedValues);
+ return new MysqlDatasetStateStore(dataSource, stateStoreTableName,
compressedValues);
} catch (Exception e) {
throw new RuntimeException("Failed to create MysqlDatasetStateStore with
factory", e);
}
diff --git
a/gobblin-runtime/src/main/java/org/apache/gobblin/runtime/spec_store/MysqlBaseSpecStore.java
b/gobblin-runtime/src/main/java/org/apache/gobblin/runtime/spec_store/MysqlBaseSpecStore.java
index 3e3a78201..b12360466 100644
---
a/gobblin-runtime/src/main/java/org/apache/gobblin/runtime/spec_store/MysqlBaseSpecStore.java
+++
b/gobblin-runtime/src/main/java/org/apache/gobblin/runtime/spec_store/MysqlBaseSpecStore.java
@@ -28,13 +28,13 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
-
-import org.apache.commons.dbcp.BasicDataSource;
+import javax.sql.DataSource;
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import com.google.common.io.ByteStreams;
import com.typesafe.config.Config;
+import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
@@ -132,7 +132,7 @@ public class MysqlBaseSpecStore extends
InstrumentedSpecStore {
}
- protected final BasicDataSource dataSource;
+ protected final DataSource dataSource;
protected final String tableName;
private final URI specStoreURI;
protected final SpecSerDe specSerDe;
@@ -331,7 +331,11 @@ public class MysqlBaseSpecStore extends
InstrumentedSpecStore {
}
return result;
} catch (SQLException e) {
- log.warn("Received SQL exception that can result from invalid
connection. Checking if validation query is set {} Exception is {}",
((BasicDataSource) this.dataSource).getValidationQuery(), e);
+ // TODO: revisit use of connection test query following verification of
successful connection pool migration:
+ // If your driver supports JDBC4 we strongly recommend not setting
this property. This is for "legacy" drivers
+ // that do not support the JDBC4 Connection.isValid() API; see:
+ //
https://github.com/brettwooldridge/HikariCP#gear-configuration-knobs-baby
+ log.warn("Received SQL exception that can result from invalid
connection. Checking if validation query is set {} Exception is {}",
((HikariDataSource) this.dataSource).getConnectionTestQuery(), e);
throw new IOException(e);
}
}
diff --git
a/gobblin-runtime/src/test/java/org/apache/gobblin/runtime/MysqlDatasetStateStoreTest.java
b/gobblin-runtime/src/test/java/org/apache/gobblin/runtime/MysqlDatasetStateStoreTest.java
index 956a87576..14c5a9166 100644
---
a/gobblin-runtime/src/test/java/org/apache/gobblin/runtime/MysqlDatasetStateStoreTest.java
+++
b/gobblin-runtime/src/test/java/org/apache/gobblin/runtime/MysqlDatasetStateStoreTest.java
@@ -22,13 +22,13 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
-import org.apache.commons.dbcp.BasicDataSource;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.base.Predicates;
+import com.zaxxer.hikari.HikariDataSource;
import org.apache.gobblin.config.ConfigBuilder;
import org.apache.gobblin.configuration.ConfigurationKeys;
@@ -70,15 +70,15 @@ public class MysqlDatasetStateStoreTest {
testMetastoreDatabase = TestMetastoreDatabaseFactory.get();
String jdbcUrl = testMetastoreDatabase.getJdbcUrl();
ConfigBuilder configBuilder = ConfigBuilder.create();
- BasicDataSource mySqlDs = new BasicDataSource();
+ HikariDataSource dataSource = new HikariDataSource();
-
mySqlDs.setDriverClassName(ConfigurationKeys.DEFAULT_STATE_STORE_DB_JDBC_DRIVER);
- mySqlDs.setDefaultAutoCommit(false);
- mySqlDs.setUrl(jdbcUrl);
- mySqlDs.setUsername(TEST_USER);
- mySqlDs.setPassword(TEST_PASSWORD);
+
dataSource.setDriverClassName(ConfigurationKeys.DEFAULT_STATE_STORE_DB_JDBC_DRIVER);
+ dataSource.setAutoCommit(false);
+ dataSource.setJdbcUrl(jdbcUrl);
+ dataSource.setUsername(TEST_USER);
+ dataSource.setPassword(TEST_PASSWORD);
- dbJobStateStore = new MysqlStateStore<>(mySqlDs, TEST_STATE_STORE, false,
JobState.class);
+ dbJobStateStore = new MysqlStateStore<>(dataSource, TEST_STATE_STORE,
false, JobState.class);
configBuilder.addPrimitive(ConfigurationKeys.STATE_STORE_DB_URL_KEY,
jdbcUrl);
configBuilder.addPrimitive(ConfigurationKeys.STATE_STORE_DB_USER_KEY,
TEST_USER);
diff --git
a/gobblin-runtime/src/test/java/org/apache/gobblin/runtime/cli/JobStateStoreCliTest.java
b/gobblin-runtime/src/test/java/org/apache/gobblin/runtime/cli/JobStateStoreCliTest.java
index 075d056e5..6b5213284 100644
---
a/gobblin-runtime/src/test/java/org/apache/gobblin/runtime/cli/JobStateStoreCliTest.java
+++
b/gobblin-runtime/src/test/java/org/apache/gobblin/runtime/cli/JobStateStoreCliTest.java
@@ -20,7 +20,9 @@ package org.apache.gobblin.runtime.cli;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
-import org.apache.commons.dbcp.BasicDataSource;
+
+import com.zaxxer.hikari.HikariDataSource;
+
import org.apache.gobblin.config.ConfigBuilder;
import org.apache.gobblin.configuration.ConfigurationKeys;
import org.apache.gobblin.configuration.WorkUnitState;
@@ -64,15 +66,15 @@ public class JobStateStoreCliTest {
testMetastoreDatabase = TestMetastoreDatabaseFactory.get();
String jdbcUrl = testMetastoreDatabase.getJdbcUrl();
ConfigBuilder configBuilder = ConfigBuilder.create();
- BasicDataSource mySqlDs = new BasicDataSource();
+ HikariDataSource dataSource = new HikariDataSource();
-
mySqlDs.setDriverClassName(ConfigurationKeys.DEFAULT_STATE_STORE_DB_JDBC_DRIVER);
- mySqlDs.setDefaultAutoCommit(false);
- mySqlDs.setUrl(jdbcUrl);
- mySqlDs.setUsername(TEST_USER);
- mySqlDs.setPassword(TEST_PASSWORD);
+
dataSource.setDriverClassName(ConfigurationKeys.DEFAULT_STATE_STORE_DB_JDBC_DRIVER);
+ dataSource.setAutoCommit(false);
+ dataSource.setJdbcUrl(jdbcUrl);
+ dataSource.setUsername(TEST_USER);
+ dataSource.setPassword(TEST_PASSWORD);
- dbJobStateStore = new MysqlStateStore<>(mySqlDs, TEST_STATE_STORE, false,
JobState.class);
+ dbJobStateStore = new MysqlStateStore<>(dataSource, TEST_STATE_STORE,
false, JobState.class);
configBuilder.addPrimitive(ConfigurationKeys.STATE_STORE_DB_URL_KEY,
jdbcUrl);
configBuilder.addPrimitive(ConfigurationKeys.STATE_STORE_DB_USER_KEY,
TEST_USER);
diff --git a/gobblin-service/build.gradle b/gobblin-service/build.gradle
index 6fb986e93..af029ad5c 100644
--- a/gobblin-service/build.gradle
+++ b/gobblin-service/build.gradle
@@ -43,7 +43,6 @@ dependencies {
compile externalDependency.curatorFramework
compile externalDependency.curatorClient
compile externalDependency.curatorRecipes
- compile externalDependency.commonsDbcp2
compile externalDependency.findBugsAnnotations
compile externalDependency.flyway
compile externalDependency.gson
@@ -56,6 +55,7 @@ dependencies {
compile (externalDependency.helix) {
exclude group: 'io.dropwizard.metrics', module: 'metrics-core'
}
+ compile externalDependency.hikariCP
compile externalDependency.hiveCommon
compile externalDependency.httpclient
compile externalDependency.httpcore
diff --git
a/gobblin-service/src/main/java/org/apache/gobblin/service/modules/db/ServiceDatabaseProviderImpl.java
b/gobblin-service/src/main/java/org/apache/gobblin/service/modules/db/ServiceDatabaseProviderImpl.java
index b9c2d32e4..7d2d719da 100644
---
a/gobblin-service/src/main/java/org/apache/gobblin/service/modules/db/ServiceDatabaseProviderImpl.java
+++
b/gobblin-service/src/main/java/org/apache/gobblin/service/modules/db/ServiceDatabaseProviderImpl.java
@@ -23,9 +23,8 @@ import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.commons.dbcp2.BasicDataSource;
-
import com.typesafe.config.Config;
+import com.zaxxer.hikari.HikariDataSource;
import javax.inject.Inject;
import javax.sql.DataSource;
@@ -44,7 +43,7 @@ public class ServiceDatabaseProviderImpl implements
ServiceDatabaseProvider {
private static final Logger LOG =
LoggerFactory.getLogger(ServiceDatabaseProviderImpl.class);
private final Configuration configuration;
- private BasicDataSource dataSource;
+ private HikariDataSource dataSource;
@Inject
public ServiceDatabaseProviderImpl(Configuration configuration) {
@@ -61,25 +60,28 @@ public class ServiceDatabaseProviderImpl implements
ServiceDatabaseProvider {
return;
}
- dataSource = new BasicDataSource();
+ dataSource = new HikariDataSource();
- dataSource.setUrl(configuration.getUrl());
+ dataSource.setJdbcUrl(configuration.getUrl());
dataSource.setUsername(configuration.getUserName());
dataSource.setPassword(configuration.getPassword());
// MySQL server can timeout a connection so need to validate connections
before use
final String validationQuery =
MysqlDataSourceUtils.QUERY_CONNECTION_IS_VALID_AND_NOT_READONLY;
LOG.info("setting `DataSource` validation query: '" + validationQuery +
"'");
- dataSource.setValidationQuery(validationQuery);
- dataSource.setValidationQueryTimeout(5);
-
- // To improve performance, we only check connections on creation, and set
a maximum connection lifetime
+ // TODO: revisit following verification of successful connection pool
migration:
+ // If your driver supports JDBC4 we strongly recommend not setting this
property. This is for "legacy" drivers
+ // that do not support the JDBC4 Connection.isValid() API; see:
+ //
https://github.com/brettwooldridge/HikariCP#gear-configuration-knobs-baby
+ dataSource.setConnectionTestQuery(validationQuery);
+ dataSource.setValidationTimeout(Duration.ofSeconds(5).toMillis());
+
+ // To improve performance, we set a maximum connection lifetime
// If database goes to read-only mode, then connection would not work
correctly for up to configured lifetime
- dataSource.setTestOnCreate(true);
-
dataSource.setMaxConnLifetimeMillis(configuration.getMaxConnectionLifetime().toMillis());
-
dataSource.setTimeBetweenEvictionRunsMillis(Duration.ofSeconds(10).toMillis());
- dataSource.setMinIdle(2);
- dataSource.setMaxTotal(configuration.getMaxConnections());
+
dataSource.setMaxLifetime(configuration.getMaxConnectionLifetime().toMillis());
+ dataSource.setIdleTimeout(Duration.ofSeconds(10).toMillis());
+ dataSource.setMinimumIdle(2);
+ dataSource.setMaximumPoolSize(configuration.getMaxConnections());
}
@Builder
diff --git
a/gobblin-service/src/main/java/org/apache/gobblin/service/modules/orchestration/MysqlUserQuotaManager.java
b/gobblin-service/src/main/java/org/apache/gobblin/service/modules/orchestration/MysqlUserQuotaManager.java
index 41a9a03a8..8f5c57e49 100644
---
a/gobblin-service/src/main/java/org/apache/gobblin/service/modules/orchestration/MysqlUserQuotaManager.java
+++
b/gobblin-service/src/main/java/org/apache/gobblin/service/modules/orchestration/MysqlUserQuotaManager.java
@@ -27,11 +27,11 @@ import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
-import org.apache.commons.dbcp.BasicDataSource;
import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Inject;
import com.typesafe.config.Config;
+import com.zaxxer.hikari.HikariDataSource;
import javax.inject.Singleton;
import javax.sql.DataSource;
@@ -265,22 +265,22 @@ public class MysqlUserQuotaManager extends
AbstractUserQuotaManager {
String quotaStoreTableName = ConfigUtils.getString(config,
ServiceConfigKeys.QUOTA_STORE_DB_TABLE_KEY,
ServiceConfigKeys.DEFAULT_QUOTA_STORE_DB_TABLE);
- BasicDataSource basicDataSource = MysqlStateStore.newDataSource(config);
+ DataSource dataSource = MysqlStateStore.newDataSource(config);
- return new MysqlQuotaStore(basicDataSource, quotaStoreTableName);
+ return new MysqlQuotaStore(dataSource, quotaStoreTableName);
}
protected RunningDagIdsStore createRunningDagStore(Config config) throws
IOException {
String quotaStoreTableName = ConfigUtils.getString(config,
ServiceConfigKeys.RUNNING_DAG_IDS_DB_TABLE_KEY,
ServiceConfigKeys.DEFAULT_RUNNING_DAG_IDS_DB_TABLE);
- BasicDataSource basicDataSource = MysqlStateStore.newDataSource(config);
+ DataSource dataSource = MysqlStateStore.newDataSource(config);
- return new RunningDagIdsStore(basicDataSource, quotaStoreTableName);
+ return new RunningDagIdsStore(dataSource, quotaStoreTableName);
}
static class MysqlQuotaStore {
- protected final BasicDataSource dataSource;
+ protected final DataSource dataSource;
final String tableName;
private final String GET_USER_COUNT;
private final String GET_REQUESTER_COUNT;
@@ -293,7 +293,8 @@ public class MysqlUserQuotaManager extends
AbstractUserQuotaManager {
private final String DECREASE_FLOWGROUP_COUNT_SQL;
private final String DELETE_USER_SQL;
- public MysqlQuotaStore(BasicDataSource dataSource, String tableName)
+
@edu.umd.cs.findbugs.annotations.SuppressFBWarnings("SQL_PREPARED_STATEMENT_GENERATED_FROM_NONCONSTANT_STRING")
+ public MysqlQuotaStore(DataSource dataSource, String tableName)
throws IOException {
this.dataSource = dataSource;
this.tableName = tableName;
@@ -319,8 +320,12 @@ public class MysqlUserQuotaManager extends
AbstractUserQuotaManager {
try (Connection connection = dataSource.getConnection();
PreparedStatement createStatement =
connection.prepareStatement(createQuotaTable)) {
createStatement.executeUpdate();
} catch (SQLException e) {
+ // TODO: revisit use of connection test query following verification
of successful connection pool migration:
+ // If your driver supports JDBC4 we strongly recommend not setting
this property. This is for "legacy" drivers
+ // that do not support the JDBC4 Connection.isValid() API; see:
+ //
https://github.com/brettwooldridge/HikariCP#gear-configuration-knobs-baby
log.warn("Failure in creating table {}. Validation query is set to {}
Exception is {}",
- tableName, this.dataSource.getValidationQuery(), e);
+ tableName, ((HikariDataSource)
this.dataSource).getConnectionTestQuery(), e);
throw new IOException(e);
}
}
@@ -437,7 +442,8 @@ public class MysqlUserQuotaManager extends
AbstractUserQuotaManager {
private final String ADD_DAG_ID;
private final String REMOVE_DAG_ID;
- public RunningDagIdsStore(BasicDataSource dataSource, String tableName)
+
@edu.umd.cs.findbugs.annotations.SuppressFBWarnings("SQL_PREPARED_STATEMENT_GENERATED_FROM_NONCONSTANT_STRING")
+ public RunningDagIdsStore(DataSource dataSource, String tableName)
throws IOException {
this.dataSource = dataSource;
this.tableName = tableName;
diff --git
a/gobblin-service/src/test/java/org/apache/gobblin/service/modules/orchestration/MysqlDagStateStoreTest.java
b/gobblin-service/src/test/java/org/apache/gobblin/service/modules/orchestration/MysqlDagStateStoreTest.java
index dfbbd6a92..97d2ae698 100644
---
a/gobblin-service/src/test/java/org/apache/gobblin/service/modules/orchestration/MysqlDagStateStoreTest.java
+++
b/gobblin-service/src/test/java/org/apache/gobblin/service/modules/orchestration/MysqlDagStateStoreTest.java
@@ -23,12 +23,12 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.apache.commons.dbcp.BasicDataSource;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.typesafe.config.Config;
+import com.zaxxer.hikari.HikariDataSource;
import org.apache.gobblin.config.ConfigBuilder;
import org.apache.gobblin.configuration.ConfigurationKeys;
@@ -166,15 +166,15 @@ public class MysqlDagStateStoreTest {
// Setting up mock DB
ITestMetastoreDatabase testMetastoreDatabase =
TestMetastoreDatabaseFactory.get();
String jdbcUrl = testMetastoreDatabase.getJdbcUrl();
- BasicDataSource mySqlDs = new BasicDataSource();
+ HikariDataSource dataSource = new HikariDataSource();
-
mySqlDs.setDriverClassName(ConfigurationKeys.DEFAULT_STATE_STORE_DB_JDBC_DRIVER);
- mySqlDs.setDefaultAutoCommit(false);
- mySqlDs.setUrl(jdbcUrl);
- mySqlDs.setUsername(TEST_USER);
- mySqlDs.setPassword(TEST_PASSWORD);
+
dataSource.setDriverClassName(ConfigurationKeys.DEFAULT_STATE_STORE_DB_JDBC_DRIVER);
+ dataSource.setAutoCommit(false);
+ dataSource.setJdbcUrl(jdbcUrl);
+ dataSource.setUsername(TEST_USER);
+ dataSource.setPassword(TEST_PASSWORD);
- return new MysqlStateStore<>(mySqlDs, TEST_DAG_STATE_STORE, false,
State.class);
+ return new MysqlStateStore<>(dataSource, TEST_DAG_STATE_STORE, false,
State.class);
} catch (Exception e) {
throw new RuntimeException(e);
}
diff --git a/gobblin-utility/build.gradle b/gobblin-utility/build.gradle
index c80ea8346..7bba0ec2b 100644
--- a/gobblin-utility/build.gradle
+++ b/gobblin-utility/build.gradle
@@ -23,7 +23,6 @@ dependencies {
compile externalDependency.commonsCli
compile externalDependency.commonsConfiguration
compile externalDependency.commonsCompress
- compile externalDependency.commonsDbcp
compile externalDependency.commonsEmail
compile externalDependency.commonsIo
compile externalDependency.commonsLang
@@ -33,6 +32,7 @@ dependencies {
compile externalDependency.avroCompiler
compile externalDependency.avroCompatHelper
compile externalDependency.orcCore
+ compile externalDependency.hikariCP
compile externalDependency.hiveMetastore
compile externalDependency.jodaTime
compile externalDependency.jacksonCore
diff --git
a/gobblin-utility/src/main/java/org/apache/gobblin/util/jdbc/DataSourceBuilder.java
b/gobblin-utility/src/main/java/org/apache/gobblin/util/jdbc/DataSourceBuilder.java
index 83cafffbb..528950fed 100644
---
a/gobblin-utility/src/main/java/org/apache/gobblin/util/jdbc/DataSourceBuilder.java
+++
b/gobblin-utility/src/main/java/org/apache/gobblin/util/jdbc/DataSourceBuilder.java
@@ -41,7 +41,6 @@ public class DataSourceBuilder {
private String driver;
private String userName;
private String passWord;
- private Integer maxIdleConnections;
private Integer maxActiveConnections;
private String cryptoKeyLocation;
private Boolean useStrongEncryption;
@@ -71,11 +70,6 @@ public class DataSourceBuilder {
return this;
}
- public DataSourceBuilder maxIdleConnections(int maxIdleConnections) {
- this.maxIdleConnections = maxIdleConnections;
- return this;
- }
-
public DataSourceBuilder maxActiveConnections(int maxActiveConnections) {
this.maxActiveConnections = maxActiveConnections;
return this;
@@ -110,10 +104,6 @@ public class DataSourceBuilder {
properties.setProperty(ConfigurationKeys.ENCRYPT_KEY_LOC,
this.cryptoKeyLocation);
}
- if (this.maxIdleConnections != null) {
- properties.setProperty(DataSourceProvider.MAX_IDLE_CONNS,
this.maxIdleConnections.toString());
- }
-
if (this.maxActiveConnections != null) {
properties.setProperty(DataSourceProvider.MAX_ACTIVE_CONNS,
this.maxActiveConnections.toString());
}
@@ -133,8 +123,6 @@ public class DataSourceBuilder {
validateNotEmpty(this.url, "url");
validateNotEmpty(this.driver, "driver");
validateNotEmpty(this.passWord, "passWord");
- Preconditions.checkArgument(this.maxIdleConnections == null ||
this.maxIdleConnections > 0,
- "maxIdleConnections should be a positive integer.");
Preconditions.checkArgument(this.maxActiveConnections == null ||
this.maxActiveConnections > 0,
"maxActiveConnections should be a positive integer.");
}
diff --git
a/gobblin-utility/src/main/java/org/apache/gobblin/util/jdbc/DataSourceProvider.java
b/gobblin-utility/src/main/java/org/apache/gobblin/util/jdbc/DataSourceProvider.java
index 86afeea60..dbd4222bc 100644
---
a/gobblin-utility/src/main/java/org/apache/gobblin/util/jdbc/DataSourceProvider.java
+++
b/gobblin-utility/src/main/java/org/apache/gobblin/util/jdbc/DataSourceProvider.java
@@ -26,11 +26,10 @@ import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.commons.dbcp.BasicDataSource;
-
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.name.Named;
+import com.zaxxer.hikari.HikariDataSource;
import org.apache.gobblin.password.PasswordManager;
@@ -48,36 +47,40 @@ public class DataSourceProvider implements
Provider<DataSource> {
public static final String USERNAME = GOBBLIN_UTIL_JDBC_PREFIX + "username";
public static final String PASSWORD = GOBBLIN_UTIL_JDBC_PREFIX + "password";
public static final String SKIP_VALIDATION_QUERY = GOBBLIN_UTIL_JDBC_PREFIX
+ "skip.validation.query";
- public static final String MAX_IDLE_CONNS = GOBBLIN_UTIL_JDBC_PREFIX +
"max.idle.connections";
public static final String MAX_ACTIVE_CONNS = GOBBLIN_UTIL_JDBC_PREFIX +
"max.active.connections";
public static final String DEFAULT_CONN_DRIVER = "com.mysql.jdbc.Driver";
- protected final BasicDataSource basicDataSource;
+ protected final HikariDataSource dataSource;
@Inject
public DataSourceProvider(@Named("dataSourceProperties") Properties
properties) {
- this.basicDataSource = new BasicDataSource();
-
this.basicDataSource.setDriverClassName(properties.getProperty(CONN_DRIVER,
DEFAULT_CONN_DRIVER));
+ this.dataSource = new HikariDataSource();
+ this.dataSource.setDriverClassName(properties.getProperty(CONN_DRIVER,
DEFAULT_CONN_DRIVER));
// the validation query should work beyond mysql; still, to bypass for any
reason, heed directive
if (!Boolean.parseBoolean(properties.getProperty(SKIP_VALIDATION_QUERY,
"false"))) {
// MySQL server can timeout a connection so need to validate connections
before use
final String validationQuery =
MysqlDataSourceUtils.QUERY_CONNECTION_IS_VALID_AND_NOT_READONLY;
LOG.info("setting `DataSource` validation query: '" + validationQuery +
"'");
- this.basicDataSource.setValidationQuery(validationQuery);
- this.basicDataSource.setTestOnBorrow(true);
-
this.basicDataSource.setTimeBetweenEvictionRunsMillis(Duration.ofSeconds(60).toMillis());
+ // TODO: revisit following verification of successful connection pool
migration:
+ // If your driver supports JDBC4 we strongly recommend not setting
this property. This is for "legacy" drivers
+ // that do not support the JDBC4 Connection.isValid() API; see:
+ //
https://github.com/brettwooldridge/HikariCP#gear-configuration-knobs-baby
+ this.dataSource.setConnectionTestQuery(validationQuery);
+ this.dataSource.setIdleTimeout(Duration.ofSeconds(60).toMillis());
}
- this.basicDataSource.setUrl(properties.getProperty(CONN_URL));
+ this.dataSource.setJdbcUrl(properties.getProperty(CONN_URL));
+ // TODO: revisit following verification of successful connection pool
migration:
+ // whereas `o.a.commons.dbcp.BasicDataSource` defaults min idle conns to
0, hikari defaults to 10.
+ // perhaps non-zero would have desirable runtime perf, but anything >0
currently fails unit tests (even 1!);
+ // (so experimenting with a higher number would first require adjusting
tests)
+ this.dataSource.setMinimumIdle(0);
if (properties.containsKey(USERNAME) && properties.containsKey(PASSWORD)) {
- this.basicDataSource.setUsername(properties.getProperty(USERNAME));
- this.basicDataSource
+ this.dataSource.setUsername(properties.getProperty(USERNAME));
+ this.dataSource
.setPassword(PasswordManager.getInstance(properties).readPassword(properties.getProperty(PASSWORD)));
}
- if (properties.containsKey(MAX_IDLE_CONNS)) {
-
this.basicDataSource.setMaxIdle(Integer.parseInt(properties.getProperty(MAX_IDLE_CONNS)));
- }
if (properties.containsKey(MAX_ACTIVE_CONNS)) {
-
this.basicDataSource.setMaxActive(Integer.parseInt(properties.getProperty(MAX_ACTIVE_CONNS)));
+
this.dataSource.setMaximumPoolSize(Integer.parseInt(properties.getProperty(MAX_ACTIVE_CONNS)));
}
}
@@ -85,11 +88,11 @@ public class DataSourceProvider implements
Provider<DataSource> {
LOG.warn("Creating {} without setting validation query.\n Stacktrace of
current thread {}",
this.getClass().getSimpleName(),
Arrays.toString(Thread.currentThread().getStackTrace()).replace(", ",
"\n at "));
- this.basicDataSource = new BasicDataSource();
+ this.dataSource = new HikariDataSource();
}
@Override
public DataSource get() {
- return this.basicDataSource;
+ return this.dataSource;
}
}
diff --git a/gradle/scripts/dependencyDefinitions.gradle
b/gradle/scripts/dependencyDefinitions.gradle
index 1ffbae691..b15f76e0c 100644
--- a/gradle/scripts/dependencyDefinitions.gradle
+++ b/gradle/scripts/dependencyDefinitions.gradle
@@ -37,8 +37,6 @@ ext.externalDependency = [
"awsSts": "com.amazonaws:aws-java-sdk-sts:" + awsVersion,
"commonsCli": "commons-cli:commons-cli:1.3.1",
"commonsCodec": "commons-codec:commons-codec:1.10",
- "commonsDbcp": "commons-dbcp:commons-dbcp:1.4",
- "commonsDbcp2": "org.apache.commons:commons-dbcp2:2.9.0",
"commonsEmail": "org.apache.commons:commons-email:1.4",
"commonsLang": "commons-lang:commons-lang:2.6",
"commonsLang3": "org.apache.commons:commons-lang3:3.4",
@@ -70,6 +68,7 @@ ext.externalDependency = [
"hadoopAws": "org.apache.hadoop:hadoop-aws:2.6.0",
"hdrHistogram": "org.hdrhistogram:HdrHistogram:2.1.11",
"helix": "org.apache.helix:helix-core:1.0.2",
+ "hikariCP": "com.zaxxer:HikariCP:3.2.0",
"hiveCommon": "com.linkedin.hive:hive-common:" + hiveVersion,
"hiveService": "com.linkedin.hive:hive-service:" + hiveVersion,
"hiveJdbc": "com.linkedin.hive:hive-jdbc:" + hiveVersion,