Commit cb6739b4 authored by Piotr Maj's avatar Piotr Maj Committed by Dave Syer

Added testWhileIdle etc.

Fixes gh-463
parent 695b3917
...@@ -25,7 +25,7 @@ import org.springframework.util.StringUtils; ...@@ -25,7 +25,7 @@ import org.springframework.util.StringUtils;
/** /**
* Base class for configuration of a database pool. * Base class for configuration of a database pool.
* *
* @author Dave Syer * @author Dave Syer
*/ */
@ConfigurationProperties(name = DataSourceAutoConfiguration.CONFIGURATION_PREFIX) @ConfigurationProperties(name = DataSourceAutoConfiguration.CONFIGURATION_PREFIX)
...@@ -55,6 +55,12 @@ public abstract class AbstractDataSourceConfiguration implements BeanClassLoader ...@@ -55,6 +55,12 @@ public abstract class AbstractDataSourceConfiguration implements BeanClassLoader
private boolean testOnReturn = false; private boolean testOnReturn = false;
private boolean testWhileIdle = false;
private int timeBetweenEvictionRunsMillis = getDefaultTimeBetweenEvictionRunsMillis();
private int minEvictableIdleTimeMillis = getDefaultMinEvictableIdleTimeMillis();
private ClassLoader classLoader; private ClassLoader classLoader;
private EmbeddedDatabaseConnection embeddedDatabaseConnection = EmbeddedDatabaseConnection.NONE; private EmbeddedDatabaseConnection embeddedDatabaseConnection = EmbeddedDatabaseConnection.NONE;
...@@ -164,6 +170,18 @@ public abstract class AbstractDataSourceConfiguration implements BeanClassLoader ...@@ -164,6 +170,18 @@ public abstract class AbstractDataSourceConfiguration implements BeanClassLoader
this.testOnReturn = testOnReturn; this.testOnReturn = testOnReturn;
} }
public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
public int getInitialSize() { public int getInitialSize() {
return this.initialSize; return this.initialSize;
} }
...@@ -192,4 +210,16 @@ public abstract class AbstractDataSourceConfiguration implements BeanClassLoader ...@@ -192,4 +210,16 @@ public abstract class AbstractDataSourceConfiguration implements BeanClassLoader
return this.testOnReturn; return this.testOnReturn;
} }
protected boolean isTestWhileIdle() {
return this.testWhileIdle;
}
protected int getTimeBetweenEvictionRunsMillis() { return this.timeBetweenEvictionRunsMillis; }
protected int getMinEvictableIdleTimeMillis() { return this.minEvictableIdleTimeMillis; }
protected abstract int getDefaultTimeBetweenEvictionRunsMillis();
protected abstract int getDefaultMinEvictableIdleTimeMillis();
} }
...@@ -24,6 +24,7 @@ import javax.sql.DataSource; ...@@ -24,6 +24,7 @@ import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.DataAccessResourceFailureException;
...@@ -31,7 +32,7 @@ import org.springframework.dao.DataAccessResourceFailureException; ...@@ -31,7 +32,7 @@ import org.springframework.dao.DataAccessResourceFailureException;
/** /**
* Configuration for a Commons DBCP database pool. The DBCP pool is popular but not * Configuration for a Commons DBCP database pool. The DBCP pool is popular but not
* recommended in high volume environments (the Tomcat DataSource is more reliable). * recommended in high volume environments (the Tomcat DataSource is more reliable).
* *
* @author Dave Syer * @author Dave Syer
* @see DataSourceAutoConfiguration * @see DataSourceAutoConfiguration
*/ */
...@@ -66,7 +67,11 @@ public class CommonsDataSourceConfiguration extends AbstractDataSourceConfigurat ...@@ -66,7 +67,11 @@ public class CommonsDataSourceConfiguration extends AbstractDataSourceConfigurat
this.pool.setMinIdle(getMinIdle()); this.pool.setMinIdle(getMinIdle());
this.pool.setTestOnBorrow(isTestOnBorrow()); this.pool.setTestOnBorrow(isTestOnBorrow());
this.pool.setTestOnReturn(isTestOnReturn()); this.pool.setTestOnReturn(isTestOnReturn());
this.pool.setTestWhileIdle(isTestWhileIdle());
this.pool.setTimeBetweenEvictionRunsMillis(getTimeBetweenEvictionRunsMillis());
this.pool.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis());
this.pool.setValidationQuery(getValidationQuery()); this.pool.setValidationQuery(getValidationQuery());
return this.pool; return this.pool;
} }
...@@ -75,12 +80,20 @@ public class CommonsDataSourceConfiguration extends AbstractDataSourceConfigurat ...@@ -75,12 +80,20 @@ public class CommonsDataSourceConfiguration extends AbstractDataSourceConfigurat
if (this.pool != null) { if (this.pool != null) {
try { try {
this.pool.close(); this.pool.close();
} } catch (SQLException ex) {
catch (SQLException ex) {
throw new DataAccessResourceFailureException( throw new DataAccessResourceFailureException(
"Could not close data source", ex); "Could not close data source", ex);
} }
} }
} }
@Override
protected int getDefaultTimeBetweenEvictionRunsMillis() {
return (int) GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
}
@Override
protected int getDefaultMinEvictableIdleTimeMillis() {
return (int) GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
}
} }
...@@ -25,7 +25,7 @@ import org.springframework.context.annotation.Configuration; ...@@ -25,7 +25,7 @@ import org.springframework.context.annotation.Configuration;
/** /**
* Configuration for a Tomcat database pool. The Tomcat pool provides superior performance * Configuration for a Tomcat database pool. The Tomcat pool provides superior performance
* and tends not to deadlock in high volume environments. * and tends not to deadlock in high volume environments.
* *
* @author Dave Syer * @author Dave Syer
* @see DataSourceAutoConfiguration * @see DataSourceAutoConfiguration
*/ */
...@@ -51,6 +51,9 @@ public class TomcatDataSourceConfiguration extends AbstractDataSourceConfigurati ...@@ -51,6 +51,9 @@ public class TomcatDataSourceConfiguration extends AbstractDataSourceConfigurati
this.pool.setMinIdle(getMinIdle()); this.pool.setMinIdle(getMinIdle());
this.pool.setTestOnBorrow(isTestOnBorrow()); this.pool.setTestOnBorrow(isTestOnBorrow());
this.pool.setTestOnReturn(isTestOnReturn()); this.pool.setTestOnReturn(isTestOnReturn());
this.pool.setTestWhileIdle(isTestWhileIdle());
this.pool.setTimeBetweenEvictionRunsMillis(getTimeBetweenEvictionRunsMillis());
this.pool.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis());
this.pool.setValidationQuery(getValidationQuery()); this.pool.setValidationQuery(getValidationQuery());
return this.pool; return this.pool;
} }
...@@ -62,4 +65,13 @@ public class TomcatDataSourceConfiguration extends AbstractDataSourceConfigurati ...@@ -62,4 +65,13 @@ public class TomcatDataSourceConfiguration extends AbstractDataSourceConfigurati
} }
} }
@Override
protected int getDefaultTimeBetweenEvictionRunsMillis() {
return 5000;
}
@Override
protected int getDefaultMinEvictableIdleTimeMillis() {
return 60000;
}
} }
...@@ -18,14 +18,18 @@ package org.springframework.boot.autoconfigure.jdbc; ...@@ -18,14 +18,18 @@ package org.springframework.boot.autoconfigure.jdbc;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.junit.Test; import org.junit.Test;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
/** /**
* Tests for {@link CommonsDataSourceConfiguration}. * Tests for {@link CommonsDataSourceConfiguration}.
* *
* @author Dave Syer * @author Dave Syer
*/ */
public class CommonsDataSourceConfigurationTests { public class CommonsDataSourceConfigurationTests {
...@@ -40,4 +44,32 @@ public class CommonsDataSourceConfigurationTests { ...@@ -40,4 +44,32 @@ public class CommonsDataSourceConfigurationTests {
this.context.close(); this.context.close();
} }
@Test
public void testDataSourcePropertiesOverridden() throws Exception {
this.context.register(CommonsDataSourceConfiguration.class);
EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.url:jdbc:foo//bar/spam");
EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.testWhileIdle:true");
EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.testOnBorrow:true");
EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.testOnReturn:true");
EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.timeBetweenEvictionRunsMillis:10000");
EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.minEvictableIdleTimeMillis:12345");
this.context.refresh();
BasicDataSource ds = this.context.getBean(BasicDataSource.class);
assertEquals("jdbc:foo//bar/spam", ds.getUrl());
assertEquals(true, ds.getTestWhileIdle());
assertEquals(true, ds.getTestOnBorrow());
assertEquals(true, ds.getTestOnReturn());
assertEquals(10000, ds.getTimeBetweenEvictionRunsMillis());
assertEquals(12345, ds.getMinEvictableIdleTimeMillis());
}
@Test
public void testDataSourceDefaultsPreserved() throws Exception {
this.context.register(CommonsDataSourceConfiguration.class);
this.context.refresh();
BasicDataSource ds = this.context.getBean(BasicDataSource.class);
assertEquals(GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, ds.getTimeBetweenEvictionRunsMillis());
assertEquals(GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, ds.getMinEvictableIdleTimeMillis());
}
} }
...@@ -33,7 +33,7 @@ import static org.junit.Assert.assertNotNull; ...@@ -33,7 +33,7 @@ import static org.junit.Assert.assertNotNull;
/** /**
* Tests for {@link TomcatDataSourceConfiguration}. * Tests for {@link TomcatDataSourceConfiguration}.
* *
* @author Dave Syer * @author Dave Syer
*/ */
public class TomcatDataSourceConfigurationTests { public class TomcatDataSourceConfigurationTests {
...@@ -56,12 +56,29 @@ public class TomcatDataSourceConfigurationTests { ...@@ -56,12 +56,29 @@ public class TomcatDataSourceConfigurationTests {
@Test @Test
public void testDataSourcePropertiesOverridden() throws Exception { public void testDataSourcePropertiesOverridden() throws Exception {
this.context.register(TomcatDataSourceConfiguration.class); this.context.register(TomcatDataSourceConfiguration.class);
EnvironmentTestUtils.addEnvironment(this.context, EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.url:jdbc:foo//bar/spam");
"spring.datasource.url:jdbc:foo//bar/spam"); EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.testWhileIdle:true");
EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.testOnBorrow:true");
EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.testOnReturn:true");
EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.timeBetweenEvictionRunsMillis:10000");
EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.minEvictableIdleTimeMillis:12345");
this.context.refresh();
org.apache.tomcat.jdbc.pool.DataSource ds = this.context.getBean(org.apache.tomcat.jdbc.pool.DataSource.class);
assertEquals("jdbc:foo//bar/spam", ds.getUrl());
assertEquals(true, ds.isTestWhileIdle());
assertEquals(true, ds.isTestOnBorrow());
assertEquals(true, ds.isTestOnReturn());
assertEquals(10000, ds.getTimeBetweenEvictionRunsMillis());
assertEquals(12345, ds.getMinEvictableIdleTimeMillis());
}
@Test
public void testDataSourceDefaultsPreserved() throws Exception {
this.context.register(TomcatDataSourceConfiguration.class);
this.context.refresh(); this.context.refresh();
assertEquals("jdbc:foo//bar/spam", org.apache.tomcat.jdbc.pool.DataSource ds = this.context.getBean(org.apache.tomcat.jdbc.pool.DataSource.class);
this.context.getBean(org.apache.tomcat.jdbc.pool.DataSource.class) assertEquals(5000, ds.getTimeBetweenEvictionRunsMillis());
.getUrl()); assertEquals(60000, ds.getMinEvictableIdleTimeMillis());
} }
@Test(expected = BeanCreationException.class) @Test(expected = BeanCreationException.class)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment