Do not default username/password for DataSource unless embedded
To use a DataSource pool (Tomcat or DBCP) the user must supply a valid driver class name *and* database URL. If both are supplied and the driver class is not one of the embedded ones, then no default username or password is provided. Fixes gh-94
This commit is contained in:
@@ -174,6 +174,11 @@
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.jdbc;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -29,15 +30,16 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
@ConfigurationProperties(name = DataSourceAutoConfiguration.CONFIGURATION_PREFIX)
|
||||
@EnableConfigurationProperties
|
||||
public abstract class AbstractDataSourceConfiguration implements BeanClassLoaderAware {
|
||||
public abstract class AbstractDataSourceConfiguration implements BeanClassLoaderAware,
|
||||
InitializingBean {
|
||||
|
||||
private String driverClassName;
|
||||
|
||||
private String url;
|
||||
|
||||
private String username = "sa";
|
||||
private String username;
|
||||
|
||||
private String password = "";
|
||||
private String password;
|
||||
|
||||
private int maxActive = 100;
|
||||
|
||||
@@ -53,41 +55,67 @@ public abstract class AbstractDataSourceConfiguration implements BeanClassLoader
|
||||
|
||||
private ClassLoader classLoader;
|
||||
|
||||
private EmbeddedDatabaseConnection embeddedDatabaseConnection = EmbeddedDatabaseConnection.NONE;
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.embeddedDatabaseConnection = EmbeddedDatabaseConnection
|
||||
.get(this.classLoader);
|
||||
}
|
||||
|
||||
protected String getDriverClassName() {
|
||||
if (StringUtils.hasText(this.driverClassName)) {
|
||||
return this.driverClassName;
|
||||
}
|
||||
EmbeddedDatabaseConnection embeddedDatabaseConnection = EmbeddedDatabaseConnection
|
||||
.get(this.classLoader);
|
||||
this.driverClassName = embeddedDatabaseConnection.getDriverClassName();
|
||||
if (!StringUtils.hasText(this.driverClassName)) {
|
||||
String driverClassName = this.embeddedDatabaseConnection.getDriverClassName();
|
||||
if (!StringUtils.hasText(driverClassName)) {
|
||||
throw new BeanCreationException(
|
||||
"Cannot determine embedded database driver class for database type "
|
||||
+ embeddedDatabaseConnection + ". If you want an embedded "
|
||||
+ "database please put a supoprted one on the classpath.");
|
||||
+ this.embeddedDatabaseConnection
|
||||
+ ". If you want an embedded "
|
||||
+ "database please put a supported one on the classpath.");
|
||||
}
|
||||
return this.driverClassName;
|
||||
return driverClassName;
|
||||
}
|
||||
|
||||
protected String getUrl() {
|
||||
if (StringUtils.hasText(this.url)) {
|
||||
return this.url;
|
||||
}
|
||||
EmbeddedDatabaseConnection embeddedDatabaseConnection = EmbeddedDatabaseConnection
|
||||
.get(this.classLoader);
|
||||
this.url = embeddedDatabaseConnection.getUrl();
|
||||
if (!StringUtils.hasText(this.url)) {
|
||||
String url = this.embeddedDatabaseConnection.getUrl();
|
||||
if (!StringUtils.hasText(url)) {
|
||||
throw new BeanCreationException(
|
||||
"Cannot determine embedded database url for database type "
|
||||
+ embeddedDatabaseConnection + ". If you want an embedded "
|
||||
+ this.embeddedDatabaseConnection
|
||||
+ ". If you want an embedded "
|
||||
+ "database please put a supported on on the classpath.");
|
||||
}
|
||||
return this.url;
|
||||
return url;
|
||||
}
|
||||
|
||||
protected String getUsername() {
|
||||
if (StringUtils.hasText(this.username)) {
|
||||
return this.username;
|
||||
}
|
||||
if (EmbeddedDatabaseConnection.isEmbedded(this.driverClassName)) {
|
||||
return "sa";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String getPassword() {
|
||||
if (StringUtils.hasText(this.password)) {
|
||||
return this.password;
|
||||
}
|
||||
if (EmbeddedDatabaseConnection.isEmbedded(this.driverClassName)) {
|
||||
return "";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setDriverClassName(String driverClassName) {
|
||||
@@ -130,14 +158,6 @@ public abstract class AbstractDataSourceConfiguration implements BeanClassLoader
|
||||
this.testOnReturn = testOnReturn;
|
||||
}
|
||||
|
||||
protected String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
protected String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
protected int getMaxActive() {
|
||||
return this.maxActive;
|
||||
}
|
||||
|
||||
@@ -49,8 +49,12 @@ public class CommonsDataSourceConfiguration extends AbstractDataSourceConfigurat
|
||||
this.pool = new BasicDataSource();
|
||||
this.pool.setDriverClassName(getDriverClassName());
|
||||
this.pool.setUrl(getUrl());
|
||||
this.pool.setUsername(getUsername());
|
||||
this.pool.setPassword(getPassword());
|
||||
if (getUsername() != null) {
|
||||
this.pool.setUsername(getUsername());
|
||||
}
|
||||
if (getPassword() != null) {
|
||||
this.pool.setPassword(getPassword());
|
||||
}
|
||||
this.pool.setMaxActive(getMaxActive());
|
||||
this.pool.setMaxIdle(getMaxIdle());
|
||||
this.pool.setMinIdle(getMinIdle());
|
||||
|
||||
@@ -88,6 +88,20 @@ public enum EmbeddedDatabaseConnection {
|
||||
*/
|
||||
static EmbeddedDatabaseConnection override;
|
||||
|
||||
/**
|
||||
* Convenience method to determine if a given driver class name represents an embedded
|
||||
* database type.
|
||||
*
|
||||
* @param driverClass the driver class
|
||||
* @return true if the driver class is one of the embedded types
|
||||
*/
|
||||
public static boolean isEmbedded(String driverClass) {
|
||||
return driverClass != null
|
||||
&& (driverClass.equals(HSQL.driverClass)
|
||||
|| driverClass.equals(H2.driverClass) || driverClass
|
||||
.equals(DERBY.driverClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the most suitable {@link EmbeddedDatabaseConnection} for the given class
|
||||
* loader.
|
||||
|
||||
@@ -39,8 +39,12 @@ public class TomcatDataSourceConfiguration extends AbstractDataSourceConfigurati
|
||||
this.pool = new org.apache.tomcat.jdbc.pool.DataSource();
|
||||
this.pool.setDriverClassName(getDriverClassName());
|
||||
this.pool.setUrl(getUrl());
|
||||
this.pool.setUsername(getUsername());
|
||||
this.pool.setPassword(getPassword());
|
||||
if (getUsername() != null) {
|
||||
this.pool.setUsername(getUsername());
|
||||
}
|
||||
if (getPassword() != null) {
|
||||
this.pool.setPassword(getPassword());
|
||||
}
|
||||
this.pool.setMaxActive(getMaxActive());
|
||||
this.pool.setMaxIdle(getMaxIdle());
|
||||
this.pool.setMinIdle(getMinIdle());
|
||||
|
||||
@@ -23,6 +23,7 @@ import javax.sql.DataSource;
|
||||
|
||||
import org.apache.commons.dbcp.BasicDataSource;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.TestUtils;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -35,6 +36,7 @@ import org.springframework.util.ClassUtils;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
@@ -54,6 +56,36 @@ public class DataSourceAutoConfigurationTests {
|
||||
assertNotNull(this.context.getBean(DataSource.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmbeddedTypeDefaultsUsername() throws Exception {
|
||||
TestUtils.addEnviroment(this.context,
|
||||
"spring.datasource.driverClassName:org.hsqldb.jdbcDriver",
|
||||
"spring.datasource.url:jdbc:hsqldb:mem:testdb");
|
||||
this.context.register(DataSourceAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
DataSource bean = this.context.getBean(DataSource.class);
|
||||
assertNotNull(bean);
|
||||
org.apache.tomcat.jdbc.pool.DataSource pool = (org.apache.tomcat.jdbc.pool.DataSource) bean;
|
||||
assertEquals("org.hsqldb.jdbcDriver", pool.getDriverClassName());
|
||||
assertEquals("sa", pool.getUsername());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExplicitDriverClassClearsUserName() throws Exception {
|
||||
TestUtils.addEnviroment(this.context,
|
||||
"spring.datasource.driverClassName:com.mysql.jdbc.Driver",
|
||||
"spring.datasource.url:jdbc:mysql://localhost");
|
||||
this.context.register(DataSourceAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
DataSource bean = this.context.getBean(DataSource.class);
|
||||
assertNotNull(bean);
|
||||
org.apache.tomcat.jdbc.pool.DataSource pool = (org.apache.tomcat.jdbc.pool.DataSource) bean;
|
||||
assertEquals("com.mysql.jdbc.Driver", pool.getDriverClassName());
|
||||
assertNull(pool.getUsername());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultDataSourceCanBeOverridden() throws Exception {
|
||||
this.context.register(TestDataSourceConfiguration.class,
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
<log4j.version>1.2.17</log4j.version>
|
||||
<logback.version>1.0.13</logback.version>
|
||||
<mockito.version>1.9.5</mockito.version>
|
||||
<mysql.version>5.1.23</mysql.version>
|
||||
<reactor.version>1.0.0.M3</reactor.version>
|
||||
<servlet-api.version>3.0.1</servlet-api.version>
|
||||
<slf4j.version>1.7.5</slf4j.version>
|
||||
@@ -104,6 +105,11 @@
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${mysql.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>nz.net.ultraq.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf-layout-dialect</artifactId>
|
||||
|
||||
Reference in New Issue
Block a user