Merge branch '1.5.x'

This commit is contained in:
Stephane Nicoll 2016-10-06 13:30:14 +02:00
commit b54566c0cd
6 changed files with 108 additions and 7 deletions

View File

@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.jdbc;
import java.nio.charset.Charset;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;
import javax.sql.DataSource;
@ -57,6 +58,11 @@ public class DataSourceProperties
*/
private String name = "testdb";
/**
* Generate a random datasource name.
*/
private boolean generateUniqueName;
/**
* Fully qualified name of the connection pool implementation to use. By default, it
* is auto-detected from the classpath.
@ -148,6 +154,8 @@ public class DataSourceProperties
private Xa xa = new Xa();
private String uniqueName;
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
@ -183,6 +191,14 @@ public class DataSourceProperties
this.name = name;
}
public boolean isGenerateUniqueName() {
return this.generateUniqueName;
}
public void setGenerateUniqueName(boolean generateUniqueName) {
this.generateUniqueName = generateUniqueName;
}
public Class<? extends DataSource> getType() {
return this.type;
}
@ -268,7 +284,7 @@ public class DataSourceProperties
if (StringUtils.hasText(this.url)) {
return this.url;
}
String url = this.embeddedDatabaseConnection.getUrl(this.name);
String url = this.embeddedDatabaseConnection.getUrl(determineDatabaseName());
if (!StringUtils.hasText(url)) {
throw new DataSourceBeanCreationException(this.embeddedDatabaseConnection,
this.environment, "url");
@ -276,6 +292,16 @@ public class DataSourceProperties
return url;
}
private String determineDatabaseName() {
if (this.generateUniqueName) {
if (this.uniqueName == null) {
this.uniqueName = UUID.randomUUID().toString();
}
return this.uniqueName;
}
return this.name;
}
/**
* Return the configured username or {@code null} if none was configured.
* @return the configured username

View File

@ -55,7 +55,8 @@ public class EmbeddedDataSourceConfiguration implements BeanClassLoaderAware {
public EmbeddedDatabase dataSource() {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseConnection.get(this.classLoader).getType());
this.database = builder.setName(this.properties.getName()).build();
this.database = builder.setName(this.properties.getName())
.generateUniqueName(this.properties.isGenerateUniqueName()).build();
return this.database;
}

View File

@ -66,6 +66,19 @@ public class DataSourcePropertiesTests {
assertThat(properties.determineUrl()).isEqualTo("jdbc:mysql://mydb");
}
@Test
public void determineUrlWithGenerateUniqueName() throws Exception {
DataSourceProperties properties = new DataSourceProperties();
properties.setGenerateUniqueName(true);
properties.afterPropertiesSet();
assertThat(properties.determineUrl()).isEqualTo(properties.determineUrl());
DataSourceProperties properties2 = new DataSourceProperties();
properties2.setGenerateUniqueName(true);
properties2.afterPropertiesSet();
assertThat(properties.determineUrl()).isNotEqualTo(properties2.determineUrl());
}
@Test
public void determineUsername() throws Exception {
DataSourceProperties properties = new DataSourceProperties();

View File

@ -16,10 +16,16 @@
package org.springframework.boot.autoconfigure.jdbc;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
@ -28,18 +34,64 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link EmbeddedDataSourceConfiguration}.
*
* @author Dave Syer
* @author Stephane Nicoll
*/
public class EmbeddedDataSourceConfigurationTests {
private AnnotationConfigApplicationContext context;
@After
public void closeContext() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void testDefaultEmbeddedDatabase() throws Exception {
this.context = new AnnotationConfigApplicationContext();
this.context.register(EmbeddedDataSourceConfiguration.class);
this.context.refresh();
public void defaultEmbeddedDatabase() {
this.context = load();
assertThat(this.context.getBean(DataSource.class)).isNotNull();
this.context.close();
}
@Test
public void generateUniqueName() throws Exception {
this.context = load("spring.datasource.generate-unique-name=true");
AnnotationConfigApplicationContext context2 =
load("spring.datasource.generate-unique-name=true");
try {
DataSource dataSource = this.context.getBean(DataSource.class);
DataSource dataSource2 = context2.getBean(DataSource.class);
assertThat(getDatabaseName(dataSource))
.isNotEqualTo(getDatabaseName(dataSource2));
System.out.println(dataSource2);
}
finally {
context2.close();
}
}
private String getDatabaseName(DataSource dataSource) throws SQLException {
Connection connection = dataSource.getConnection();
try {
ResultSet catalogs = connection.getMetaData().getCatalogs();
if (catalogs.next()) {
return catalogs.getString(1);
}
else {
throw new IllegalStateException("Unable to get database name");
}
}
finally {
connection.close();
}
}
private AnnotationConfigApplicationContext load(String... environment) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(ctx, environment);
ctx.register(EmbeddedDataSourceConfiguration.class);
ctx.refresh();
return ctx;
}
}

View File

@ -595,6 +595,7 @@ content into your application; rather pick only the properties that you need.
spring.datasource.data-password= # Password of the database to execute DML scripts (if different).
spring.datasource.dbcp2.*= # Commons DBCP2 specific settings
spring.datasource.driver-class-name= # Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.
spring.datasource.generate-unique-name=false # Generate a random datasource name.
spring.datasource.hikari.*= # Hikari specific settings
spring.datasource.initialize=true # Populate the database using 'data.sql'.
spring.datasource.jmx-enabled=false # Enable JMX support (if provided by the underlying pool).

View File

@ -2664,6 +2664,14 @@ http://hsqldb.org/[HSQL] and http://db.apache.org/derby/[Derby] databases. You d
to provide any connection URLs, simply include a build dependency to the embedded database
that you want to use.
[NOTE]
====
If you are using this feature in your tests, you may notice that the same database is
reused by your whole test suite regardless of the number of application contexts that
you use. If you want to make sure that each context has a separate embedded database,
you should set `spring.datasource.generate-unique-name` to `true`.
====
For example, typical POM dependencies would be:
[source,xml,indent=0]