diff --git a/spring-cloud-spring-service-connector/build.gradle b/spring-cloud-spring-service-connector/build.gradle index 9b68e47..732cd20 100644 --- a/spring-cloud-spring-service-connector/build.gradle +++ b/spring-cloud-spring-service-connector/build.gradle @@ -23,6 +23,7 @@ dependencies { exclude(group: 'commons-logging', module: 'commons-logging') } optional("commons-dbcp:commons-dbcp:$commonDbcpVersion") + optional("com.zaxxer:HikariCP-java6:2.1.0") optional("org.springframework.amqp:spring-rabbit:$springAmqpVersion") optional("org.springframework.data:spring-data-redis:$springDataRedisVersion") { exclude(group: 'org.springframework', module: 'spring-context-support') diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DataSourceCreator.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DataSourceCreator.java index 654799f..b9b3765 100644 --- a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DataSourceCreator.java +++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DataSourceCreator.java @@ -39,6 +39,7 @@ public abstract class DataSourceCreator extend pooledDataSourceCreators.add(new BasicDbcpPooledDataSourceCreator()); pooledDataSourceCreators.add(new TomcatDbcpPooledDataSourceCreator()); pooledDataSourceCreators.add(new TomcatHighPerformancePooledDataSourceCreator()); + pooledDataSourceCreators.add(new HikariCpPooledDataSourceCreator()); } } diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/HikariCpPooledDataSourceCreator.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/HikariCpPooledDataSourceCreator.java new file mode 100644 index 0000000..da7296d --- /dev/null +++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/HikariCpPooledDataSourceCreator.java @@ -0,0 +1,57 @@ +package org.springframework.cloud.service.relational; + +import static org.springframework.cloud.service.Util.*; + +import java.util.logging.Logger; + +import javax.sql.DataSource; + +import org.springframework.beans.BeanWrapper; +import org.springframework.beans.BeanWrapperImpl; +import org.springframework.cloud.service.ServiceConnectorConfig; +import org.springframework.cloud.service.common.RelationalServiceInfo; + +import com.zaxxer.hikari.HikariDataSource; + +public class HikariCpPooledDataSourceCreator implements PooledDataSourceCreator { + + protected static Logger logger = Logger.getLogger(PooledDataSourceCreator.class.getName()); + + private static final String HIKARI_CLASSNAME = "com.zaxxer.hikari.HikariDataSource"; + + private DataSourceConfigurer configurer = new DataSourceConfigurer(); + + protected void setBasicDataSourceProperties(DataSource basicDataSource, RelationalServiceInfo serviceInfo, + ServiceConnectorConfig serviceConnectorConfig, + String driverClassName, String validationQuery) { + BeanWrapper target = new BeanWrapperImpl(basicDataSource); + target.setPropertyValue("driverClassName", driverClassName); + target.setPropertyValue("jdbcUrl", serviceInfo.getJdbcUrl()); + if (validationQuery != null) { + target.setPropertyValue("connectionTestQuery", validationQuery); + } + + if (serviceConnectorConfig == null) { + // choose sensible values so that we set max connection pool size to what + // free tier services on Cloud Foundry and Heroku allow + target.setPropertyValue("maximumPoolSize", 4); + target.setPropertyValue("connectionTimeout", 30000); + } + configurer.configure(basicDataSource, (DataSourceConfig)serviceConnectorConfig); + } + + + @Override + public DataSource create(RelationalServiceInfo serviceInfo, ServiceConnectorConfig serviceConnectorConfig, + String driverClassName, String validationQuery) { + if (hasClass(HIKARI_CLASSNAME)) { + logger.info("Found HikariCP on the classpath. Using it for DataSource connection pooling."); + HikariDataSource ds = new HikariDataSource(); + setBasicDataSourceProperties(ds, serviceInfo, serviceConnectorConfig, driverClassName, validationQuery); + return ds; + } else { + return null; + } + } + +} diff --git a/spring-cloud-spring-service-connector/src/test/java/org/springframework/cloud/service/relational/PooledDataSourceCreatorsTest.java b/spring-cloud-spring-service-connector/src/test/java/org/springframework/cloud/service/relational/PooledDataSourceCreatorsTest.java index 5791980..c906a79 100644 --- a/spring-cloud-spring-service-connector/src/test/java/org/springframework/cloud/service/relational/PooledDataSourceCreatorsTest.java +++ b/spring-cloud-spring-service-connector/src/test/java/org/springframework/cloud/service/relational/PooledDataSourceCreatorsTest.java @@ -35,6 +35,11 @@ public class PooledDataSourceCreatorsTest { assertPooledDataSource(new TomcatHighPerformancePooledDataSourceCreator()); } + @Test + public void pooledDataSourceCreationHikariCP() { + assertPooledDataSource(new HikariCpPooledDataSourceCreator()); + } + private void assertPooledDataSource(PooledDataSourceCreator testCreator) { DataSource ds = testCreator.create(mockMysqlServiceInfo, null, mysqlDataSourceCreator.getDriverClassName(mockMysqlServiceInfo),