Skip to content

Commit ce9ffd1

Browse files
committed
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
1 parent a52d553 commit ce9ffd1

File tree

7 files changed

+137
-87
lines changed

7 files changed

+137
-87
lines changed

spring-boot-project/spring-boot-integration/build.gradle

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ dependencies {
2929
api(project(":spring-boot-project:spring-boot"))
3030
api("org.springframework.integration:spring-integration-core")
3131

32-
implementation(project(":spring-boot-project:spring-boot-sql"))
33-
3432
optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure"))
3533
optional(project(":spring-boot-project:spring-boot-autoconfigure"))
3634
optional(project(":spring-boot-project:spring-boot-jdbc"))

spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationAutoConfiguration.java

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -264,16 +264,25 @@ protected static class IntegrationComponentScanConfiguration {
264264
* Integration JDBC configuration.
265265
*/
266266
@Configuration(proxyBeanMethods = false)
267-
@ConditionalOnClass({ JdbcMessageStore.class, DataSourceScriptDatabaseInitializer.class })
268267
@ConditionalOnSingleCandidate(DataSource.class)
269-
@Conditional(OnIntegrationDatasourceInitializationCondition.class)
268+
@ConditionalOnClass({ JdbcMessageStore.class, DataSourceScriptDatabaseInitializer.class })
269+
@EnableConfigurationProperties(IntegrationJdbcProperties.class)
270270
protected static class IntegrationJdbcConfiguration {
271271

272272
@Bean
273273
@ConditionalOnMissingBean
274-
public IntegrationDataSourceScriptDatabaseInitializer integrationDataSourceInitializer(DataSource dataSource,
275-
IntegrationProperties properties) {
276-
return new IntegrationDataSourceScriptDatabaseInitializer(dataSource, properties.getJdbc());
274+
@Conditional(OnIntegrationDatasourceInitializationCondition.class)
275+
IntegrationDataSourceScriptDatabaseInitializer integrationDataSourceInitializer(DataSource dataSource,
276+
IntegrationJdbcProperties properties) {
277+
return new IntegrationDataSourceScriptDatabaseInitializer(dataSource, properties);
278+
}
279+
280+
static class OnIntegrationDatasourceInitializationCondition extends OnDatabaseInitializationCondition {
281+
282+
OnIntegrationDatasourceInitializationCondition() {
283+
super("Integration", "spring.integration.jdbc.initialize-schema");
284+
}
285+
277286
}
278287

279288
}
@@ -374,12 +383,4 @@ static class TcpAddressConfigured {
374383

375384
}
376385

377-
static class OnIntegrationDatasourceInitializationCondition extends OnDatabaseInitializationCondition {
378-
379-
OnIntegrationDatasourceInitializationCondition() {
380-
super("Integration", "spring.integration.jdbc.initialize-schema");
381-
}
382-
383-
}
384-
385386
}

spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationDataSourceScriptDatabaseInitializer.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ public class IntegrationDataSourceScriptDatabaseInitializer extends DataSourceSc
4242
* @param properties the Spring Integration JDBC properties
4343
* @see #getSettings
4444
*/
45-
public IntegrationDataSourceScriptDatabaseInitializer(DataSource dataSource,
46-
IntegrationProperties.Jdbc properties) {
45+
public IntegrationDataSourceScriptDatabaseInitializer(DataSource dataSource, IntegrationJdbcProperties properties) {
4746
this(dataSource, getSettings(dataSource, properties));
4847
}
4948

@@ -59,7 +58,7 @@ public IntegrationDataSourceScriptDatabaseInitializer(DataSource dataSource,
5958
}
6059

6160
/**
62-
* Adapts {@link IntegrationProperties.Jdbc Spring Integration JDBC properties} to
61+
* Adapts {@link IntegrationJdbcProperties Spring Integration JDBC properties} to
6362
* {@link DatabaseInitializationSettings} replacing any {@literal @@platform@@}
6463
* placeholders.
6564
* @param dataSource the Spring Integration data source
@@ -68,15 +67,15 @@ public IntegrationDataSourceScriptDatabaseInitializer(DataSource dataSource,
6867
* @see #IntegrationDataSourceScriptDatabaseInitializer(DataSource,
6968
* DatabaseInitializationSettings)
7069
*/
71-
static DatabaseInitializationSettings getSettings(DataSource dataSource, IntegrationProperties.Jdbc properties) {
70+
static DatabaseInitializationSettings getSettings(DataSource dataSource, IntegrationJdbcProperties properties) {
7271
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
7372
settings.setSchemaLocations(resolveSchemaLocations(dataSource, properties));
7473
settings.setMode(properties.getInitializeSchema());
7574
settings.setContinueOnError(true);
7675
return settings;
7776
}
7877

79-
private static List<String> resolveSchemaLocations(DataSource dataSource, IntegrationProperties.Jdbc properties) {
78+
private static List<String> resolveSchemaLocations(DataSource dataSource, IntegrationJdbcProperties properties) {
8079
PlatformPlaceholderDatabaseDriverResolver platformResolver = new PlatformPlaceholderDatabaseDriverResolver();
8180
platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.MARIADB, "mysql");
8281
if (StringUtils.hasText(properties.getPlatform())) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright 2012-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.integration.autoconfigure;
18+
19+
import org.springframework.boot.context.properties.ConfigurationProperties;
20+
import org.springframework.boot.sql.init.DatabaseInitializationMode;
21+
22+
/**
23+
* Configuration properties for Spring Integration JDBC.
24+
*
25+
* @author Vedran Pavic
26+
* @author Stephane Nicoll
27+
* @author Artem Bilan
28+
* @since 4.0.0
29+
*/
30+
@ConfigurationProperties("spring.integration.jdbc")
31+
public class IntegrationJdbcProperties {
32+
33+
private static final String DEFAULT_SCHEMA_LOCATION = "classpath:org/springframework/"
34+
+ "integration/jdbc/schema-@@platform@@.sql";
35+
36+
/**
37+
* Path to the SQL file to use to initialize the database schema.
38+
*/
39+
private String schema = DEFAULT_SCHEMA_LOCATION;
40+
41+
/**
42+
* Platform to use in initialization scripts if the @@platform@@ placeholder is used.
43+
* Auto-detected by default.
44+
*/
45+
private String platform;
46+
47+
/**
48+
* Database schema initialization mode.
49+
*/
50+
private DatabaseInitializationMode initializeSchema = DatabaseInitializationMode.EMBEDDED;
51+
52+
public String getSchema() {
53+
return this.schema;
54+
}
55+
56+
public void setSchema(String schema) {
57+
this.schema = schema;
58+
}
59+
60+
public String getPlatform() {
61+
return this.platform;
62+
}
63+
64+
public void setPlatform(String platform) {
65+
this.platform = platform;
66+
}
67+
68+
public DatabaseInitializationMode getInitializeSchema() {
69+
return this.initializeSchema;
70+
}
71+
72+
public void setInitializeSchema(DatabaseInitializationMode initializeSchema) {
73+
this.initializeSchema = initializeSchema;
74+
}
75+
76+
}

spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationProperties.java

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import java.util.List;
2323

2424
import org.springframework.boot.context.properties.ConfigurationProperties;
25-
import org.springframework.boot.sql.init.DatabaseInitializationMode;
2625

2726
/**
2827
* Configuration properties for Spring Integration.
@@ -41,8 +40,6 @@ public class IntegrationProperties {
4140

4241
private final Error error = new Error();
4342

44-
private final Jdbc jdbc = new Jdbc();
45-
4643
private final RSocket rsocket = new RSocket();
4744

4845
private final Poller poller = new Poller();
@@ -61,10 +58,6 @@ public Error getError() {
6158
return this.error;
6259
}
6360

64-
public Jdbc getJdbc() {
65-
return this.jdbc;
66-
}
67-
6861
public RSocket getRsocket() {
6962
return this.rsocket;
7063
}
@@ -212,53 +205,6 @@ public void setIgnoreFailures(boolean ignoreFailures) {
212205

213206
}
214207

215-
public static class Jdbc {
216-
217-
private static final String DEFAULT_SCHEMA_LOCATION = "classpath:org/springframework/"
218-
+ "integration/jdbc/schema-@@platform@@.sql";
219-
220-
/**
221-
* Path to the SQL file to use to initialize the database schema.
222-
*/
223-
private String schema = DEFAULT_SCHEMA_LOCATION;
224-
225-
/**
226-
* Platform to use in initialization scripts if the @@platform@@ placeholder is
227-
* used. Auto-detected by default.
228-
*/
229-
private String platform;
230-
231-
/**
232-
* Database schema initialization mode.
233-
*/
234-
private DatabaseInitializationMode initializeSchema = DatabaseInitializationMode.EMBEDDED;
235-
236-
public String getSchema() {
237-
return this.schema;
238-
}
239-
240-
public void setSchema(String schema) {
241-
this.schema = schema;
242-
}
243-
244-
public String getPlatform() {
245-
return this.platform;
246-
}
247-
248-
public void setPlatform(String platform) {
249-
this.platform = platform;
250-
}
251-
252-
public DatabaseInitializationMode getInitializeSchema() {
253-
return this.initializeSchema;
254-
}
255-
256-
public void setInitializeSchema(DatabaseInitializationMode initializeSchema) {
257-
this.initializeSchema = initializeSchema;
258-
}
259-
260-
}
261-
262208
public static class RSocket {
263209

264210
private final Client client = new Client();

spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/autoconfigure/IntegrationAutoConfigurationTests.java

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration;
4747
import org.springframework.boot.integration.autoconfigure.IntegrationAutoConfiguration.IntegrationComponentScanConfiguration;
4848
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
49+
import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties;
4950
import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration;
5051
import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration;
5152
import org.springframework.boot.jdbc.autoconfigure.JdbcTemplateAutoConfiguration;
@@ -56,6 +57,7 @@
5657
import org.springframework.boot.rsocket.autoconfigure.RSocketStrategiesAutoConfiguration;
5758
import org.springframework.boot.sql.init.DatabaseInitializationMode;
5859
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
60+
import org.springframework.boot.test.context.FilteredClassLoader;
5961
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
6062
import org.springframework.boot.testsupport.assertj.SimpleAsyncTaskExecutorAssert;
6163
import org.springframework.boot.testsupport.classpath.resources.WithResource;
@@ -207,8 +209,8 @@ void integrationJdbcDataSourceInitializerEnabled() {
207209
.withPropertyValues("spring.datasource.generate-unique-name=true",
208210
"spring.integration.jdbc.initialize-schema=always")
209211
.run((context) -> {
210-
IntegrationProperties properties = context.getBean(IntegrationProperties.class);
211-
assertThat(properties.getJdbc().getInitializeSchema()).isEqualTo(DatabaseInitializationMode.ALWAYS);
212+
IntegrationJdbcProperties properties = context.getBean(IntegrationJdbcProperties.class);
213+
assertThat(properties.getInitializeSchema()).isEqualTo(DatabaseInitializationMode.ALWAYS);
212214
JdbcOperations jdbc = context.getBean(JdbcOperations.class);
213215
assertThat(jdbc.queryForList("select * from INT_MESSAGE")).isEmpty();
214216
assertThat(jdbc.queryForList("select * from INT_GROUP_TO_MESSAGE")).isEmpty();
@@ -227,8 +229,8 @@ void whenIntegrationJdbcDataSourceInitializerIsEnabledThenFlywayCanBeUsed() {
227229
.withPropertyValues("spring.datasource.generate-unique-name=true",
228230
"spring.integration.jdbc.initialize-schema=always")
229231
.run((context) -> {
230-
IntegrationProperties properties = context.getBean(IntegrationProperties.class);
231-
assertThat(properties.getJdbc().getInitializeSchema()).isEqualTo(DatabaseInitializationMode.ALWAYS);
232+
IntegrationJdbcProperties properties = context.getBean(IntegrationJdbcProperties.class);
233+
assertThat(properties.getInitializeSchema()).isEqualTo(DatabaseInitializationMode.ALWAYS);
232234
JdbcOperations jdbc = context.getBean(JdbcOperations.class);
233235
assertThat(jdbc.queryForList("select * from INT_MESSAGE")).isEmpty();
234236
assertThat(jdbc.queryForList("select * from INT_GROUP_TO_MESSAGE")).isEmpty();
@@ -247,8 +249,8 @@ void integrationJdbcDataSourceInitializerDisabled() {
247249
"spring.integration.jdbc.initialize-schema=never")
248250
.run((context) -> {
249251
assertThat(context).doesNotHaveBean(IntegrationDataSourceScriptDatabaseInitializer.class);
250-
IntegrationProperties properties = context.getBean(IntegrationProperties.class);
251-
assertThat(properties.getJdbc().getInitializeSchema()).isEqualTo(DatabaseInitializationMode.NEVER);
252+
IntegrationJdbcProperties properties = context.getBean(IntegrationJdbcProperties.class);
253+
assertThat(properties.getInitializeSchema()).isEqualTo(DatabaseInitializationMode.NEVER);
252254
JdbcOperations jdbc = context.getBean(JdbcOperations.class);
253255
assertThatExceptionOfType(BadSqlGrammarException.class)
254256
.isThrownBy(() -> jdbc.queryForList("select * from INT_MESSAGE"));
@@ -262,13 +264,29 @@ void integrationJdbcDataSourceInitializerEnabledByDefaultWithEmbeddedDb() {
262264
JdbcTemplateAutoConfiguration.class, IntegrationAutoConfiguration.class))
263265
.withPropertyValues("spring.datasource.generate-unique-name=true")
264266
.run((context) -> {
265-
IntegrationProperties properties = context.getBean(IntegrationProperties.class);
266-
assertThat(properties.getJdbc().getInitializeSchema()).isEqualTo(DatabaseInitializationMode.EMBEDDED);
267+
IntegrationJdbcProperties properties = context.getBean(IntegrationJdbcProperties.class);
268+
assertThat(properties.getInitializeSchema()).isEqualTo(DatabaseInitializationMode.EMBEDDED);
267269
JdbcOperations jdbc = context.getBean(JdbcOperations.class);
268270
assertThat(jdbc.queryForList("select * from INT_MESSAGE")).isEmpty();
269271
});
270272
}
271273

274+
@Test
275+
void integrationJdbcDataSourceInitializerBacksOffWithoutSpringBootJdbc() {
276+
this.contextRunner.withBean(DataSource.class, IntegrationAutoConfigurationTests::createTestDataSource)
277+
.withClassLoader(new FilteredClassLoader("org.springframework.boot.jdbc"))
278+
.run((context) -> assertThat(context)
279+
.doesNotHaveBean(IntegrationDataSourceScriptDatabaseInitializer.class));
280+
}
281+
282+
@Test
283+
void integrationJdbcDataSourceInitializerBacksOffWithoutSpringBootJdbcAndSql() {
284+
this.contextRunner.withBean(DataSource.class, IntegrationAutoConfigurationTests::createTestDataSource)
285+
.withClassLoader(new FilteredClassLoader("org.springframework.boot.jdbc", "org.springframework.boot.sql"))
286+
.run((context) -> assertThat(context)
287+
.doesNotHaveBean(IntegrationDataSourceScriptDatabaseInitializer.class));
288+
}
289+
272290
@Test
273291
void rsocketSupportEnabled() {
274292
this.contextRunner.withUserConfiguration(RSocketServerConfiguration.class)
@@ -573,6 +591,18 @@ void pollerMetadataCanBeCustomizedViaPollerMetadataCustomizer() {
573591
});
574592
}
575593

594+
private static DataSource createTestDataSource() {
595+
DataSourceProperties properties = new DataSourceProperties();
596+
properties.setGenerateUniqueName(true);
597+
try {
598+
properties.afterPropertiesSet();
599+
}
600+
catch (Exception ex) {
601+
throw new RuntimeException(ex);
602+
}
603+
return properties.initializeDataSourceBuilder().build();
604+
}
605+
576606
@Configuration(proxyBeanMethods = false)
577607
static class CustomMBeanExporter {
578608

@@ -632,8 +662,8 @@ static class CustomIntegrationDatabaseInitializerConfiguration {
632662

633663
@Bean
634664
IntegrationDataSourceScriptDatabaseInitializer customInitializer(DataSource dataSource,
635-
IntegrationProperties properties) {
636-
return new IntegrationDataSourceScriptDatabaseInitializer(dataSource, properties.getJdbc());
665+
IntegrationJdbcProperties properties) {
666+
return new IntegrationDataSourceScriptDatabaseInitializer(dataSource, properties);
637667
}
638668

639669
}

spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/autoconfigure/IntegrationDataSourceScriptDatabaseInitializerTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ class IntegrationDataSourceScriptDatabaseInitializerTests {
3636
@Test
3737
void getSettingsWithPlatformDoesNotTouchDataSource() {
3838
DataSource dataSource = mock(DataSource.class);
39-
IntegrationProperties properties = new IntegrationProperties();
40-
properties.getJdbc().setPlatform("test");
39+
IntegrationJdbcProperties properties = new IntegrationJdbcProperties();
40+
properties.setPlatform("test");
4141
DatabaseInitializationSettings settings = IntegrationDataSourceScriptDatabaseInitializer.getSettings(dataSource,
42-
properties.getJdbc());
42+
properties);
4343
assertThat(settings.getSchemaLocations())
4444
.containsOnly("classpath:org/springframework/integration/jdbc/schema-test.sql");
4545
then(dataSource).shouldHaveNoInteractions();

0 commit comments

Comments
 (0)