Make Integration DataSource init back off without s-b-sql
Previously, the DataSource initialization would back off without spring-boot-jdbc but spring-boot-sql was a required dependency. Without spring-boot-sql, a failure would occur due to the absence of OnDatabaseInitializationCondition. This commit updates the auto-configuration so that spring-boot-sql is now an optional dependency and DataSource initialization backs off in its absence. Closes gh-46244
This commit is contained in:
parent
a52d5538ee
commit
ce9ffd17fd
|
@ -29,8 +29,6 @@ dependencies {
|
|||
api(project(":spring-boot-project:spring-boot"))
|
||||
api("org.springframework.integration:spring-integration-core")
|
||||
|
||||
implementation(project(":spring-boot-project:spring-boot-sql"))
|
||||
|
||||
optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure"))
|
||||
optional(project(":spring-boot-project:spring-boot-autoconfigure"))
|
||||
optional(project(":spring-boot-project:spring-boot-jdbc"))
|
||||
|
|
|
@ -264,16 +264,25 @@ public class IntegrationAutoConfiguration {
|
|||
* Integration JDBC configuration.
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ JdbcMessageStore.class, DataSourceScriptDatabaseInitializer.class })
|
||||
@ConditionalOnSingleCandidate(DataSource.class)
|
||||
@Conditional(OnIntegrationDatasourceInitializationCondition.class)
|
||||
@ConditionalOnClass({ JdbcMessageStore.class, DataSourceScriptDatabaseInitializer.class })
|
||||
@EnableConfigurationProperties(IntegrationJdbcProperties.class)
|
||||
protected static class IntegrationJdbcConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public IntegrationDataSourceScriptDatabaseInitializer integrationDataSourceInitializer(DataSource dataSource,
|
||||
IntegrationProperties properties) {
|
||||
return new IntegrationDataSourceScriptDatabaseInitializer(dataSource, properties.getJdbc());
|
||||
@Conditional(OnIntegrationDatasourceInitializationCondition.class)
|
||||
IntegrationDataSourceScriptDatabaseInitializer integrationDataSourceInitializer(DataSource dataSource,
|
||||
IntegrationJdbcProperties properties) {
|
||||
return new IntegrationDataSourceScriptDatabaseInitializer(dataSource, properties);
|
||||
}
|
||||
|
||||
static class OnIntegrationDatasourceInitializationCondition extends OnDatabaseInitializationCondition {
|
||||
|
||||
OnIntegrationDatasourceInitializationCondition() {
|
||||
super("Integration", "spring.integration.jdbc.initialize-schema");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -374,12 +383,4 @@ public class IntegrationAutoConfiguration {
|
|||
|
||||
}
|
||||
|
||||
static class OnIntegrationDatasourceInitializationCondition extends OnDatabaseInitializationCondition {
|
||||
|
||||
OnIntegrationDatasourceInitializationCondition() {
|
||||
super("Integration", "spring.integration.jdbc.initialize-schema");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -42,8 +42,7 @@ public class IntegrationDataSourceScriptDatabaseInitializer extends DataSourceSc
|
|||
* @param properties the Spring Integration JDBC properties
|
||||
* @see #getSettings
|
||||
*/
|
||||
public IntegrationDataSourceScriptDatabaseInitializer(DataSource dataSource,
|
||||
IntegrationProperties.Jdbc properties) {
|
||||
public IntegrationDataSourceScriptDatabaseInitializer(DataSource dataSource, IntegrationJdbcProperties properties) {
|
||||
this(dataSource, getSettings(dataSource, properties));
|
||||
}
|
||||
|
||||
|
@ -59,7 +58,7 @@ public class IntegrationDataSourceScriptDatabaseInitializer extends DataSourceSc
|
|||
}
|
||||
|
||||
/**
|
||||
* Adapts {@link IntegrationProperties.Jdbc Spring Integration JDBC properties} to
|
||||
* Adapts {@link IntegrationJdbcProperties Spring Integration JDBC properties} to
|
||||
* {@link DatabaseInitializationSettings} replacing any {@literal @@platform@@}
|
||||
* placeholders.
|
||||
* @param dataSource the Spring Integration data source
|
||||
|
@ -68,7 +67,7 @@ public class IntegrationDataSourceScriptDatabaseInitializer extends DataSourceSc
|
|||
* @see #IntegrationDataSourceScriptDatabaseInitializer(DataSource,
|
||||
* DatabaseInitializationSettings)
|
||||
*/
|
||||
static DatabaseInitializationSettings getSettings(DataSource dataSource, IntegrationProperties.Jdbc properties) {
|
||||
static DatabaseInitializationSettings getSettings(DataSource dataSource, IntegrationJdbcProperties properties) {
|
||||
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
|
||||
settings.setSchemaLocations(resolveSchemaLocations(dataSource, properties));
|
||||
settings.setMode(properties.getInitializeSchema());
|
||||
|
@ -76,7 +75,7 @@ public class IntegrationDataSourceScriptDatabaseInitializer extends DataSourceSc
|
|||
return settings;
|
||||
}
|
||||
|
||||
private static List<String> resolveSchemaLocations(DataSource dataSource, IntegrationProperties.Jdbc properties) {
|
||||
private static List<String> resolveSchemaLocations(DataSource dataSource, IntegrationJdbcProperties properties) {
|
||||
PlatformPlaceholderDatabaseDriverResolver platformResolver = new PlatformPlaceholderDatabaseDriverResolver();
|
||||
platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.MARIADB, "mysql");
|
||||
if (StringUtils.hasText(properties.getPlatform())) {
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright 2012-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.integration.autoconfigure;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationMode;
|
||||
|
||||
/**
|
||||
* Configuration properties for Spring Integration JDBC.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @author Stephane Nicoll
|
||||
* @author Artem Bilan
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@ConfigurationProperties("spring.integration.jdbc")
|
||||
public class IntegrationJdbcProperties {
|
||||
|
||||
private static final String DEFAULT_SCHEMA_LOCATION = "classpath:org/springframework/"
|
||||
+ "integration/jdbc/schema-@@platform@@.sql";
|
||||
|
||||
/**
|
||||
* Path to the SQL file to use to initialize the database schema.
|
||||
*/
|
||||
private String schema = DEFAULT_SCHEMA_LOCATION;
|
||||
|
||||
/**
|
||||
* Platform to use in initialization scripts if the @@platform@@ placeholder is used.
|
||||
* Auto-detected by default.
|
||||
*/
|
||||
private String platform;
|
||||
|
||||
/**
|
||||
* Database schema initialization mode.
|
||||
*/
|
||||
private DatabaseInitializationMode initializeSchema = DatabaseInitializationMode.EMBEDDED;
|
||||
|
||||
public String getSchema() {
|
||||
return this.schema;
|
||||
}
|
||||
|
||||
public void setSchema(String schema) {
|
||||
this.schema = schema;
|
||||
}
|
||||
|
||||
public String getPlatform() {
|
||||
return this.platform;
|
||||
}
|
||||
|
||||
public void setPlatform(String platform) {
|
||||
this.platform = platform;
|
||||
}
|
||||
|
||||
public DatabaseInitializationMode getInitializeSchema() {
|
||||
return this.initializeSchema;
|
||||
}
|
||||
|
||||
public void setInitializeSchema(DatabaseInitializationMode initializeSchema) {
|
||||
this.initializeSchema = initializeSchema;
|
||||
}
|
||||
|
||||
}
|
|
@ -22,7 +22,6 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationMode;
|
||||
|
||||
/**
|
||||
* Configuration properties for Spring Integration.
|
||||
|
@ -41,8 +40,6 @@ public class IntegrationProperties {
|
|||
|
||||
private final Error error = new Error();
|
||||
|
||||
private final Jdbc jdbc = new Jdbc();
|
||||
|
||||
private final RSocket rsocket = new RSocket();
|
||||
|
||||
private final Poller poller = new Poller();
|
||||
|
@ -61,10 +58,6 @@ public class IntegrationProperties {
|
|||
return this.error;
|
||||
}
|
||||
|
||||
public Jdbc getJdbc() {
|
||||
return this.jdbc;
|
||||
}
|
||||
|
||||
public RSocket getRsocket() {
|
||||
return this.rsocket;
|
||||
}
|
||||
|
@ -212,53 +205,6 @@ public class IntegrationProperties {
|
|||
|
||||
}
|
||||
|
||||
public static class Jdbc {
|
||||
|
||||
private static final String DEFAULT_SCHEMA_LOCATION = "classpath:org/springframework/"
|
||||
+ "integration/jdbc/schema-@@platform@@.sql";
|
||||
|
||||
/**
|
||||
* Path to the SQL file to use to initialize the database schema.
|
||||
*/
|
||||
private String schema = DEFAULT_SCHEMA_LOCATION;
|
||||
|
||||
/**
|
||||
* Platform to use in initialization scripts if the @@platform@@ placeholder is
|
||||
* used. Auto-detected by default.
|
||||
*/
|
||||
private String platform;
|
||||
|
||||
/**
|
||||
* Database schema initialization mode.
|
||||
*/
|
||||
private DatabaseInitializationMode initializeSchema = DatabaseInitializationMode.EMBEDDED;
|
||||
|
||||
public String getSchema() {
|
||||
return this.schema;
|
||||
}
|
||||
|
||||
public void setSchema(String schema) {
|
||||
this.schema = schema;
|
||||
}
|
||||
|
||||
public String getPlatform() {
|
||||
return this.platform;
|
||||
}
|
||||
|
||||
public void setPlatform(String platform) {
|
||||
this.platform = platform;
|
||||
}
|
||||
|
||||
public DatabaseInitializationMode getInitializeSchema() {
|
||||
return this.initializeSchema;
|
||||
}
|
||||
|
||||
public void setInitializeSchema(DatabaseInitializationMode initializeSchema) {
|
||||
this.initializeSchema = initializeSchema;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class RSocket {
|
||||
|
||||
private final Client client = new Client();
|
||||
|
|
|
@ -46,6 +46,7 @@ import org.springframework.boot.context.properties.source.MutuallyExclusiveConfi
|
|||
import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration;
|
||||
import org.springframework.boot.integration.autoconfigure.IntegrationAutoConfiguration.IntegrationComponentScanConfiguration;
|
||||
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties;
|
||||
import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration;
|
||||
import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration;
|
||||
import org.springframework.boot.jdbc.autoconfigure.JdbcTemplateAutoConfiguration;
|
||||
|
@ -56,6 +57,7 @@ import org.springframework.boot.rsocket.autoconfigure.RSocketServerAutoConfigura
|
|||
import org.springframework.boot.rsocket.autoconfigure.RSocketStrategiesAutoConfiguration;
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationMode;
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.testsupport.assertj.SimpleAsyncTaskExecutorAssert;
|
||||
import org.springframework.boot.testsupport.classpath.resources.WithResource;
|
||||
|
@ -207,8 +209,8 @@ class IntegrationAutoConfigurationTests {
|
|||
.withPropertyValues("spring.datasource.generate-unique-name=true",
|
||||
"spring.integration.jdbc.initialize-schema=always")
|
||||
.run((context) -> {
|
||||
IntegrationProperties properties = context.getBean(IntegrationProperties.class);
|
||||
assertThat(properties.getJdbc().getInitializeSchema()).isEqualTo(DatabaseInitializationMode.ALWAYS);
|
||||
IntegrationJdbcProperties properties = context.getBean(IntegrationJdbcProperties.class);
|
||||
assertThat(properties.getInitializeSchema()).isEqualTo(DatabaseInitializationMode.ALWAYS);
|
||||
JdbcOperations jdbc = context.getBean(JdbcOperations.class);
|
||||
assertThat(jdbc.queryForList("select * from INT_MESSAGE")).isEmpty();
|
||||
assertThat(jdbc.queryForList("select * from INT_GROUP_TO_MESSAGE")).isEmpty();
|
||||
|
@ -227,8 +229,8 @@ class IntegrationAutoConfigurationTests {
|
|||
.withPropertyValues("spring.datasource.generate-unique-name=true",
|
||||
"spring.integration.jdbc.initialize-schema=always")
|
||||
.run((context) -> {
|
||||
IntegrationProperties properties = context.getBean(IntegrationProperties.class);
|
||||
assertThat(properties.getJdbc().getInitializeSchema()).isEqualTo(DatabaseInitializationMode.ALWAYS);
|
||||
IntegrationJdbcProperties properties = context.getBean(IntegrationJdbcProperties.class);
|
||||
assertThat(properties.getInitializeSchema()).isEqualTo(DatabaseInitializationMode.ALWAYS);
|
||||
JdbcOperations jdbc = context.getBean(JdbcOperations.class);
|
||||
assertThat(jdbc.queryForList("select * from INT_MESSAGE")).isEmpty();
|
||||
assertThat(jdbc.queryForList("select * from INT_GROUP_TO_MESSAGE")).isEmpty();
|
||||
|
@ -247,8 +249,8 @@ class IntegrationAutoConfigurationTests {
|
|||
"spring.integration.jdbc.initialize-schema=never")
|
||||
.run((context) -> {
|
||||
assertThat(context).doesNotHaveBean(IntegrationDataSourceScriptDatabaseInitializer.class);
|
||||
IntegrationProperties properties = context.getBean(IntegrationProperties.class);
|
||||
assertThat(properties.getJdbc().getInitializeSchema()).isEqualTo(DatabaseInitializationMode.NEVER);
|
||||
IntegrationJdbcProperties properties = context.getBean(IntegrationJdbcProperties.class);
|
||||
assertThat(properties.getInitializeSchema()).isEqualTo(DatabaseInitializationMode.NEVER);
|
||||
JdbcOperations jdbc = context.getBean(JdbcOperations.class);
|
||||
assertThatExceptionOfType(BadSqlGrammarException.class)
|
||||
.isThrownBy(() -> jdbc.queryForList("select * from INT_MESSAGE"));
|
||||
|
@ -262,13 +264,29 @@ class IntegrationAutoConfigurationTests {
|
|||
JdbcTemplateAutoConfiguration.class, IntegrationAutoConfiguration.class))
|
||||
.withPropertyValues("spring.datasource.generate-unique-name=true")
|
||||
.run((context) -> {
|
||||
IntegrationProperties properties = context.getBean(IntegrationProperties.class);
|
||||
assertThat(properties.getJdbc().getInitializeSchema()).isEqualTo(DatabaseInitializationMode.EMBEDDED);
|
||||
IntegrationJdbcProperties properties = context.getBean(IntegrationJdbcProperties.class);
|
||||
assertThat(properties.getInitializeSchema()).isEqualTo(DatabaseInitializationMode.EMBEDDED);
|
||||
JdbcOperations jdbc = context.getBean(JdbcOperations.class);
|
||||
assertThat(jdbc.queryForList("select * from INT_MESSAGE")).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void integrationJdbcDataSourceInitializerBacksOffWithoutSpringBootJdbc() {
|
||||
this.contextRunner.withBean(DataSource.class, IntegrationAutoConfigurationTests::createTestDataSource)
|
||||
.withClassLoader(new FilteredClassLoader("org.springframework.boot.jdbc"))
|
||||
.run((context) -> assertThat(context)
|
||||
.doesNotHaveBean(IntegrationDataSourceScriptDatabaseInitializer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void integrationJdbcDataSourceInitializerBacksOffWithoutSpringBootJdbcAndSql() {
|
||||
this.contextRunner.withBean(DataSource.class, IntegrationAutoConfigurationTests::createTestDataSource)
|
||||
.withClassLoader(new FilteredClassLoader("org.springframework.boot.jdbc", "org.springframework.boot.sql"))
|
||||
.run((context) -> assertThat(context)
|
||||
.doesNotHaveBean(IntegrationDataSourceScriptDatabaseInitializer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void rsocketSupportEnabled() {
|
||||
this.contextRunner.withUserConfiguration(RSocketServerConfiguration.class)
|
||||
|
@ -573,6 +591,18 @@ class IntegrationAutoConfigurationTests {
|
|||
});
|
||||
}
|
||||
|
||||
private static DataSource createTestDataSource() {
|
||||
DataSourceProperties properties = new DataSourceProperties();
|
||||
properties.setGenerateUniqueName(true);
|
||||
try {
|
||||
properties.afterPropertiesSet();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
return properties.initializeDataSourceBuilder().build();
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomMBeanExporter {
|
||||
|
||||
|
@ -632,8 +662,8 @@ class IntegrationAutoConfigurationTests {
|
|||
|
||||
@Bean
|
||||
IntegrationDataSourceScriptDatabaseInitializer customInitializer(DataSource dataSource,
|
||||
IntegrationProperties properties) {
|
||||
return new IntegrationDataSourceScriptDatabaseInitializer(dataSource, properties.getJdbc());
|
||||
IntegrationJdbcProperties properties) {
|
||||
return new IntegrationDataSourceScriptDatabaseInitializer(dataSource, properties);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,10 +36,10 @@ class IntegrationDataSourceScriptDatabaseInitializerTests {
|
|||
@Test
|
||||
void getSettingsWithPlatformDoesNotTouchDataSource() {
|
||||
DataSource dataSource = mock(DataSource.class);
|
||||
IntegrationProperties properties = new IntegrationProperties();
|
||||
properties.getJdbc().setPlatform("test");
|
||||
IntegrationJdbcProperties properties = new IntegrationJdbcProperties();
|
||||
properties.setPlatform("test");
|
||||
DatabaseInitializationSettings settings = IntegrationDataSourceScriptDatabaseInitializer.getSettings(dataSource,
|
||||
properties.getJdbc());
|
||||
properties);
|
||||
assertThat(settings.getSchemaLocations())
|
||||
.containsOnly("classpath:org/springframework/integration/jdbc/schema-test.sql");
|
||||
then(dataSource).shouldHaveNoInteractions();
|
||||
|
|
Loading…
Reference in New Issue