Improve FailureAnalyzer for embedded datasource
See gh-11953
This commit is contained in:
parent
2b9006b3fd
commit
e66745a98a
|
|
@ -16,26 +16,72 @@
|
|||
|
||||
package org.springframework.boot.autoconfigure.jdbc;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.DataSourceBeanCreationException;
|
||||
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
|
||||
import org.springframework.boot.diagnostics.FailureAnalysis;
|
||||
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* An {@link AbstractFailureAnalyzer} for failures caused by a
|
||||
* {@link DataSourceBeanCreationException}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Patryk Kostrzewa
|
||||
*/
|
||||
class DataSourceBeanCreationFailureAnalyzer
|
||||
extends AbstractFailureAnalyzer<DataSourceBeanCreationException> {
|
||||
extends AbstractFailureAnalyzer<DataSourceBeanCreationException>
|
||||
implements EnvironmentAware {
|
||||
|
||||
private Environment environment;
|
||||
|
||||
@Override
|
||||
protected FailureAnalysis analyze(Throwable rootFailure,
|
||||
DataSourceBeanCreationException cause) {
|
||||
String message = cause.getMessage();
|
||||
String description = message.substring(0, message.indexOf('.')).trim();
|
||||
String action = message.substring(message.indexOf('.') + 1).trim();
|
||||
return new FailureAnalysis(description, action, cause);
|
||||
return getFailureAnalysis(cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
private FailureAnalysis getFailureAnalysis(DataSourceBeanCreationException cause) {
|
||||
|
||||
final EmbeddedDatabaseConnection connection = cause.getConnection();
|
||||
final String action;
|
||||
|
||||
if (EmbeddedDatabaseConnection.NONE == connection) {
|
||||
action = "If you want an embedded database "
|
||||
+ "please put a supported one on the classpath.";
|
||||
}
|
||||
else {
|
||||
action = "If you have database settings to be loaded "
|
||||
+ "from a particular profile you may need to activate it"
|
||||
+ getActiveProfiles();
|
||||
}
|
||||
return new FailureAnalysis(cause.getMessage(), action, cause);
|
||||
}
|
||||
|
||||
private String getActiveProfiles() {
|
||||
|
||||
final StringBuilder message = new StringBuilder();
|
||||
if (Objects.nonNull(this.environment)) {
|
||||
String[] profiles = this.environment.getActiveProfiles();
|
||||
if (ObjectUtils.isEmpty(profiles)) {
|
||||
message.append(" (no profiles are currently active).");
|
||||
}
|
||||
else {
|
||||
message.append(" (the profiles ");
|
||||
message.append(StringUtils.arrayToCommaDelimitedString(profiles));
|
||||
message.append(" are currently active).");
|
||||
}
|
||||
}
|
||||
return message.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,11 +32,8 @@ import org.springframework.boot.jdbc.DataSourceBuilder;
|
|||
import org.springframework.boot.jdbc.DataSourceInitializationMode;
|
||||
import org.springframework.boot.jdbc.DatabaseDriver;
|
||||
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
|
|
@ -47,16 +44,15 @@ import org.springframework.util.StringUtils;
|
|||
* @author Stephane Nicoll
|
||||
* @author Benedikt Ritter
|
||||
* @author Eddú Meléndez
|
||||
* @author Patryk Kostrzewa
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.datasource")
|
||||
public class DataSourceProperties
|
||||
implements BeanClassLoaderAware, EnvironmentAware, InitializingBean {
|
||||
implements BeanClassLoaderAware, InitializingBean {
|
||||
|
||||
private ClassLoader classLoader;
|
||||
|
||||
private Environment environment;
|
||||
|
||||
/**
|
||||
* Name of the datasource. Default to "testdb" when using an embedded database.
|
||||
*/
|
||||
|
|
@ -166,11 +162,6 @@ public class DataSourceProperties
|
|||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.embeddedDatabaseConnection = EmbeddedDatabaseConnection
|
||||
|
|
@ -244,8 +235,9 @@ public class DataSourceProperties
|
|||
driverClassName = this.embeddedDatabaseConnection.getDriverClassName();
|
||||
}
|
||||
if (!StringUtils.hasText(driverClassName)) {
|
||||
throw new DataSourceBeanCreationException(this.embeddedDatabaseConnection,
|
||||
this.environment, "driver class");
|
||||
throw new DataSourceBeanCreationException(
|
||||
"Failed to determine a suitable driver class",
|
||||
this.embeddedDatabaseConnection);
|
||||
}
|
||||
return driverClassName;
|
||||
}
|
||||
|
|
@ -290,8 +282,9 @@ public class DataSourceProperties
|
|||
String url = (databaseName == null ? null
|
||||
: this.embeddedDatabaseConnection.getUrl(databaseName));
|
||||
if (!StringUtils.hasText(url)) {
|
||||
throw new DataSourceBeanCreationException(this.embeddedDatabaseConnection,
|
||||
this.environment, "url");
|
||||
throw new DataSourceBeanCreationException(
|
||||
"Failed to determine suitable jdbc url",
|
||||
this.embeddedDatabaseConnection);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
|
@ -522,37 +515,17 @@ public class DataSourceProperties
|
|||
|
||||
static class DataSourceBeanCreationException extends BeanCreationException {
|
||||
|
||||
DataSourceBeanCreationException(EmbeddedDatabaseConnection connection,
|
||||
Environment environment, String property) {
|
||||
super(getMessage(connection, environment, property));
|
||||
private final EmbeddedDatabaseConnection connection;
|
||||
|
||||
DataSourceBeanCreationException(String message,
|
||||
EmbeddedDatabaseConnection connection) {
|
||||
|
||||
super(message);
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
private static String getMessage(EmbeddedDatabaseConnection connection,
|
||||
Environment environment, String property) {
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.append("Cannot determine embedded database " + property
|
||||
+ " for database type " + connection + ". ");
|
||||
message.append("If you want an embedded database please put a supported "
|
||||
+ "one on the classpath. ");
|
||||
message.append("If you have database settings to be loaded from a "
|
||||
+ "particular profile you may need to active it");
|
||||
if (environment != null) {
|
||||
String[] profiles = environment.getActiveProfiles();
|
||||
if (ObjectUtils.isEmpty(profiles)) {
|
||||
message.append(" (no profiles are currently active)");
|
||||
}
|
||||
else {
|
||||
message.append(" (the profiles \""
|
||||
+ StringUtils.arrayToCommaDelimitedString(
|
||||
environment.getActiveProfiles())
|
||||
+ "\" are currently active)");
|
||||
|
||||
}
|
||||
}
|
||||
message.append(".");
|
||||
return message.toString();
|
||||
public EmbeddedDatabaseConnection getConnection() {
|
||||
return this.connection;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,12 +41,8 @@ public class DataSourceBeanCreationFailureAnalyzerTests {
|
|||
@Test
|
||||
public void failureAnalysisIsPerformed() {
|
||||
FailureAnalysis failureAnalysis = performAnalysis(TestConfiguration.class);
|
||||
assertThat(failureAnalysis.getDescription()).isEqualTo(
|
||||
"Cannot determine embedded database driver class for database type NONE");
|
||||
assertThat(failureAnalysis.getAction()).isEqualTo("If you want an embedded "
|
||||
+ "database please put a supported one on the classpath. If you have "
|
||||
+ "database settings to be loaded from a particular profile you may "
|
||||
+ "need to active it (no profiles are currently active).");
|
||||
assertThat(failureAnalysis.getDescription()).isEqualTo("Failed to determine a suitable driver class");
|
||||
assertThat(failureAnalysis.getAction()).isEqualTo("If you want an embedded database please put a supported one on the classpath.");
|
||||
}
|
||||
|
||||
private FailureAnalysis performAnalysis(Class<?> configuration) {
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ public class DataSourcePropertiesTests {
|
|||
new FilteredClassLoader("org.h2", "org.apache.derby", "org.hsqldb"));
|
||||
properties.afterPropertiesSet();
|
||||
this.thrown.expect(DataSourceProperties.DataSourceBeanCreationException.class);
|
||||
this.thrown.expectMessage("Cannot determine embedded database url");
|
||||
this.thrown.expectMessage("Failed to determine suitable jdbc url");
|
||||
properties.determineUrl();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue