diff --git a/spring-service-connector/pom.xml b/spring-service-connector/pom.xml
index 82ac25c..178b843 100644
--- a/spring-service-connector/pom.xml
+++ b/spring-service-connector/pom.xml
@@ -84,6 +84,12 @@
${tomcat.version}
provided
+
+ org.apache.tomcat
+ tomcat-dbcp
+ ${tomcat.version}
+ provided
+
commons-dbcp
diff --git a/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/BasicDbcpPooledDataSourceCreator.java b/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/BasicDbcpPooledDataSourceCreator.java
new file mode 100644
index 0000000..0b07963
--- /dev/null
+++ b/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/BasicDbcpPooledDataSourceCreator.java
@@ -0,0 +1,31 @@
+package org.springframework.cloud.service.relational;
+
+import static org.springframework.cloud.service.Util.hasClass;
+
+import javax.sql.DataSource;
+
+import org.springframework.cloud.service.ServiceConnectorConfig;
+import org.springframework.cloud.service.common.RelationalServiceInfo;
+
+/**
+ *
+ * @author Ramnivas Laddad
+ *
+ * @param
+ */
+public class BasicDbcpPooledDataSourceCreator extends DbcpLikePooledDataSourceCreator {
+
+ @Override
+ public DataSource create(RelationalServiceInfo serviceInfo, ServiceConnectorConfig serviceConnectorConfig,
+ String driverClassName, String validationQuery) {
+ if (hasClass("org.apache.commons.dbcp.BasicDataSource")) {
+ logger.info("Found DBCP on the classpath. Using it for DataSource connection pooling.");
+ org.apache.commons.dbcp.BasicDataSource ds = new org.apache.commons.dbcp.BasicDataSource();
+ setBasicDataSourceProperties(ds, serviceInfo, serviceConnectorConfig, driverClassName, validationQuery);
+ return ds;
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DataSourceCreator.java b/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DataSourceCreator.java
index 888eadb..2c9c1e3 100644
--- a/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DataSourceCreator.java
+++ b/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DataSourceCreator.java
@@ -1,15 +1,12 @@
package org.springframework.cloud.service.relational;
-import static org.springframework.cloud.service.Util.hasClass;
-
import java.sql.DriverManager;
+import java.util.ArrayList;
+import java.util.List;
import java.util.logging.Logger;
import javax.sql.DataSource;
-import org.springframework.beans.BeanWrapper;
-import org.springframework.beans.BeanWrapperImpl;
-import org.springframework.cloud.Cloud;
import org.springframework.cloud.service.AbstractServiceConnectorCreator;
import org.springframework.cloud.service.ServiceConnectorConfig;
import org.springframework.cloud.service.ServiceConnectorCreationException;
@@ -24,52 +21,41 @@ import org.springframework.jdbc.datasource.SimpleDriverDataSource;
*/
public abstract class DataSourceCreator extends AbstractServiceConnectorCreator {
- private static Logger logger = Logger.getLogger(DataSourceCreator.class.getName());
-
- private DataSourceConfigurer configurer = new DataSourceConfigurer();
+ protected static Logger logger = Logger.getLogger(DataSourceCreator.class.getName());
public abstract String getDriverClassName();
public abstract String getValidationQuery();
+ private List> pooledDataSourceCreators = new ArrayList>();
+
+ public DataSourceCreator() {
+ if (pooledDataSourceCreators.size() == 0) {
+ pooledDataSourceCreators.add(new BasicDbcpPooledDataSourceCreator());
+ pooledDataSourceCreators.add(new TomcatDbcpPooledDataSourceCreator());
+ pooledDataSourceCreators.add(new TomcatHighPerformancePooledDataSourceCreator());
+ }
+ }
+
@Override
public DataSource create(SI serviceInfo, ServiceConnectorConfig serviceConnectorConfig) {
try {
Class.forName(getDriverClassName());
- // Give first preference to user's DBCP datasource
- if (hasClass("org.apache.commons.dbcp.BasicDataSource")) {
- logger.info("Found DBCP on the classpath. Using it for DataSource connection pooling.");
- org.apache.commons.dbcp.BasicDataSource ds = new org.apache.commons.dbcp.BasicDataSource();
- setBasicDataSourceProperties(ds, serviceInfo, serviceConnectorConfig);
- return ds;
- // else, we have one from Tomcat
- } else if (hasClass("org.apache.tomcat.jdbc.pool.DataSource")) {
- logger.info("Found Tomcat connection pool on the classpath. Using it for DataSource connection pooling.");
- org.apache.tomcat.jdbc.pool.DataSource ds = new org.apache.tomcat.jdbc.pool.DataSource();
- setBasicDataSourceProperties(ds, serviceInfo, serviceConnectorConfig);
- return ds;
- } else {
- // Only for testing outside Tomcat/CloudFoundry
- logger.warning("Found neither DBCP nor Tomcat connection pool on the classpath (no pooling in effect)");
- return new SimpleDriverDataSource(DriverManager.getDriver(serviceInfo.getJdbcUrl()),
- serviceInfo.getJdbcUrl());
+
+ for (PooledDataSourceCreator delegate: pooledDataSourceCreators) {
+ DataSource ds = delegate.create(serviceInfo, serviceConnectorConfig, getDriverClassName(), getValidationQuery());
+
+ if (ds != null) {
+ return ds;
+ }
}
+ // Only for testing outside Tomcat/CloudFoundry
+ logger.warning("Found neither DBCP nor Tomcat connection pool on the classpath (no pooling is in effect).");
+ return new SimpleDriverDataSource(DriverManager.getDriver(serviceInfo.getJdbcUrl()), serviceInfo.getJdbcUrl());
} catch (Exception e) {
throw new ServiceConnectorCreationException(
"Failed to created cloud datasource for "
+ serviceInfo.getId() + " service", e);
}
}
-
- private void setBasicDataSourceProperties(DataSource basicDataSource, RelationalServiceInfo serviceInfo,
- ServiceConnectorConfig serviceConnectorConfig) {
- BeanWrapper target = new BeanWrapperImpl(basicDataSource);
- target.setPropertyValue("driverClassName", getDriverClassName());
- target.setPropertyValue("url", serviceInfo.getJdbcUrl());
- if (getValidationQuery() != null) {
- target.setPropertyValue("validationQuery", getValidationQuery());
- target.setPropertyValue("testOnBorrow", true);
- }
- configurer.configure(basicDataSource, (DataSourceConfig)serviceConnectorConfig);
- }
}
diff --git a/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DbcpLikePooledDataSourceCreator.java b/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DbcpLikePooledDataSourceCreator.java
new file mode 100644
index 0000000..e467bc6
--- /dev/null
+++ b/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DbcpLikePooledDataSourceCreator.java
@@ -0,0 +1,38 @@
+package org.springframework.cloud.service.relational;
+
+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;
+
+/**
+ * Common implementation that assumes DBCP connection pool properties.
+ *
+ * @author Ramnivas Laddad
+ *
+ * @param
+ */
+public abstract class DbcpLikePooledDataSourceCreator implements PooledDataSourceCreator {
+
+ protected static Logger logger = Logger.getLogger(PooledDataSourceCreator.class.getName());
+
+ 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("url", serviceInfo.getJdbcUrl());
+ if (validationQuery != null) {
+ target.setPropertyValue("validationQuery", validationQuery);
+ target.setPropertyValue("testOnBorrow", true);
+ }
+ configurer.configure(basicDataSource, (DataSourceConfig)serviceConnectorConfig);
+ }
+
+}
diff --git a/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/PooledDataSourceCreator.java b/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/PooledDataSourceCreator.java
new file mode 100644
index 0000000..3f8ec83
--- /dev/null
+++ b/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/PooledDataSourceCreator.java
@@ -0,0 +1,19 @@
+package org.springframework.cloud.service.relational;
+
+import javax.sql.DataSource;
+
+import org.springframework.cloud.service.ServiceConnectorConfig;
+import org.springframework.cloud.service.common.RelationalServiceInfo;
+
+/**
+ * DataSource creator that produces a pooled connection
+ *
+ * @author Ramnivas Laddad
+ *
+ * @param
+ */
+public interface PooledDataSourceCreator {
+ public abstract DataSource create(RelationalServiceInfo serviceInfo, ServiceConnectorConfig serviceConnectorConfig,
+ String driverClassName, String validationQuery);
+}
+
diff --git a/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/TomcatDbcpPooledDataSourceCreator.java b/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/TomcatDbcpPooledDataSourceCreator.java
new file mode 100644
index 0000000..74709e1
--- /dev/null
+++ b/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/TomcatDbcpPooledDataSourceCreator.java
@@ -0,0 +1,31 @@
+package org.springframework.cloud.service.relational;
+
+import static org.springframework.cloud.service.Util.hasClass;
+
+import javax.sql.DataSource;
+
+import org.springframework.cloud.service.ServiceConnectorConfig;
+import org.springframework.cloud.service.common.RelationalServiceInfo;
+
+/**
+ *
+ * @author Ramnivas Laddad
+ *
+ * @param
+ */
+public class TomcatDbcpPooledDataSourceCreator extends DbcpLikePooledDataSourceCreator {
+
+ @Override
+ public DataSource create(RelationalServiceInfo serviceInfo, ServiceConnectorConfig serviceConnectorConfig,
+ String driverClassName, String validationQuery) {
+ if (hasClass("org.apache.tomcat.dbcp.dbcp.BasicDataSource")) {
+ logger.info("Found Tomcat dbcp connection pool on the classpath. Using it for DataSource connection pooling.");
+ org.apache.tomcat.dbcp.dbcp.BasicDataSource ds = new org.apache.tomcat.dbcp.dbcp.BasicDataSource();
+ setBasicDataSourceProperties(ds, serviceInfo, serviceConnectorConfig, driverClassName, validationQuery);
+ return ds;
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/TomcatHighPerformancePooledDataSourceCreator.java b/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/TomcatHighPerformancePooledDataSourceCreator.java
new file mode 100644
index 0000000..7522417
--- /dev/null
+++ b/spring-service-connector/src/main/java/org/springframework/cloud/service/relational/TomcatHighPerformancePooledDataSourceCreator.java
@@ -0,0 +1,32 @@
+package org.springframework.cloud.service.relational;
+
+import static org.springframework.cloud.service.Util.hasClass;
+
+import javax.sql.DataSource;
+
+import org.springframework.cloud.service.ServiceConnectorConfig;
+import org.springframework.cloud.service.common.RelationalServiceInfo;
+
+/**
+ *
+ * @author Ramnivas Laddad
+ *
+ * @param
+ */
+public class TomcatHighPerformancePooledDataSourceCreator
+ extends DbcpLikePooledDataSourceCreator {
+
+ @Override
+ public DataSource create(RelationalServiceInfo serviceInfo, ServiceConnectorConfig serviceConnectorConfig,
+ String driverClassName, String validationQuery) {
+ if (hasClass("org.apache.tomcat.jdbc.pool.DataSource")) {
+ logger.info("Found Tomcat connection pool on the classpath. Using it for DataSource connection pooling.");
+ org.apache.tomcat.jdbc.pool.DataSource ds = new org.apache.tomcat.jdbc.pool.DataSource();
+ setBasicDataSourceProperties(ds, serviceInfo, serviceConnectorConfig, driverClassName, validationQuery);
+ return ds;
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/spring-service-connector/src/test/java/org/springframework/cloud/service/relational/PooledDataSourceCreatorsTest.java b/spring-service-connector/src/test/java/org/springframework/cloud/service/relational/PooledDataSourceCreatorsTest.java
new file mode 100644
index 0000000..f8fd726
--- /dev/null
+++ b/spring-service-connector/src/test/java/org/springframework/cloud/service/relational/PooledDataSourceCreatorsTest.java
@@ -0,0 +1,42 @@
+package org.springframework.cloud.service.relational;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.sql.DataSource;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.cloud.service.common.MysqlServiceInfo;
+
+public class PooledDataSourceCreatorsTest {
+ @Mock private MysqlServiceInfo mockMysqlServiceInfo;
+
+ // Just to grab driver class name and validation query string
+ private MysqlDataSourceCreator mysqlDataSourceCreator = new MysqlDataSourceCreator();
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void pooledDataSourceCreation() {
+ List> pooledDataSourceCreators = new ArrayList>();
+
+ pooledDataSourceCreators.add(new BasicDbcpPooledDataSourceCreator());
+ pooledDataSourceCreators.add(new TomcatDbcpPooledDataSourceCreator());
+ pooledDataSourceCreators.add(new TomcatHighPerformancePooledDataSourceCreator());
+
+ for (PooledDataSourceCreator testCreator : pooledDataSourceCreators) {
+ DataSource ds = testCreator.create(mockMysqlServiceInfo, null,
+ mysqlDataSourceCreator.getDriverClassName(),
+ mysqlDataSourceCreator.getValidationQuery());
+
+ Assert.assertNotNull(ds);
+ }
+ }
+}