diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java index 98457feda0c..9e93303be9c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java @@ -30,7 +30,6 @@ import javax.sql.DataSource; import org.flywaydb.core.Flyway; import org.flywaydb.core.api.MigrationVersion; import org.flywaydb.core.api.callback.Callback; -import org.flywaydb.core.api.callback.FlywayCallback; import org.flywaydb.core.api.configuration.FluentConfiguration; import org.springframework.beans.factory.ObjectProvider; @@ -81,6 +80,7 @@ import org.springframework.util.StringUtils; * @author Dominic Gunn * @author Dan Zheng * @author András Deák + * @author Semyon Danilov * @since 1.1.0 */ @SuppressWarnings("deprecation") @@ -113,7 +113,7 @@ public class FlywayAutoConfiguration { ResourceLoader resourceLoader, ObjectProvider dataSource, @FlywayDataSource ObjectProvider flywayDataSource, ObjectProvider fluentConfigurationCustomizers, - ObjectProvider callbacks, ObjectProvider flywayCallbacks) { + ObjectProvider callbacks) { FluentConfiguration configuration = new FluentConfiguration(resourceLoader.getClassLoader()); DataSource dataSourceToMigrate = configureDataSource(configuration, properties, dataSourceProperties, flywayDataSource.getIfAvailable(), dataSource.getIfAvailable()); @@ -122,10 +122,8 @@ public class FlywayAutoConfiguration { List orderedCallbacks = callbacks.orderedStream().collect(Collectors.toList()); configureCallbacks(configuration, orderedCallbacks); fluentConfigurationCustomizers.orderedStream().forEach((customizer) -> customizer.customize(configuration)); - Flyway flyway = configuration.load(); - List orderedFlywayCallbacks = flywayCallbacks.orderedStream().collect(Collectors.toList()); - configureFlywayCallbacks(flyway, orderedCallbacks, orderedFlywayCallbacks); - return flyway; + configureFlywayCallbacks(configuration, orderedCallbacks); + return configuration.load(); } private DataSource configureDataSource(FluentConfiguration configuration, FlywayProperties properties, @@ -210,14 +208,9 @@ public class FlywayAutoConfiguration { } } - private void configureFlywayCallbacks(Flyway flyway, List callbacks, - List flywayCallbacks) { - if (!flywayCallbacks.isEmpty()) { - if (!callbacks.isEmpty()) { - throw new IllegalStateException("Found a mixture of Callback and FlywayCallback beans." - + " One type must be used exclusively."); - } - flyway.setCallbacks(flywayCallbacks.toArray(new FlywayCallback[0])); + private void configureFlywayCallbacks(FluentConfiguration flyway, List callbacks) { + if (!callbacks.isEmpty()) { + flyway.callbacks(callbacks.toArray(new Callback[0])); } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java index b9053631e08..fdb8ed92b59 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java @@ -16,7 +16,6 @@ package org.springframework.boot.autoconfigure.flyway; -import java.sql.Connection; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -30,7 +29,6 @@ import org.flywaydb.core.api.MigrationVersion; import org.flywaydb.core.api.callback.Callback; import org.flywaydb.core.api.callback.Context; import org.flywaydb.core.api.callback.Event; -import org.flywaydb.core.api.callback.FlywayCallback; import org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException; import org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform; import org.junit.jupiter.api.Test; @@ -89,7 +87,7 @@ class FlywayAutoConfigurationTests { this.contextRunner.withPropertyValues("spring.flyway.url:jdbc:hsqldb:mem:" + UUID.randomUUID()) .run((context) -> { assertThat(context).hasSingleBean(Flyway.class); - assertThat(context.getBean(Flyway.class).getDataSource()).isNotNull(); + assertThat(context.getBean(Flyway.class).getConfiguration().getDataSource()).isNotNull(); }); } @@ -98,7 +96,7 @@ class FlywayAutoConfigurationTests { this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) .withPropertyValues("spring.flyway.url:jdbc:hsqldb:mem:flywaytest").run((context) -> { assertThat(context).hasSingleBean(Flyway.class); - assertThat(context.getBean(Flyway.class).getDataSource()).isNotNull(); + assertThat(context.getBean(Flyway.class).getConfiguration().getDataSource()).isNotNull(); }); } @@ -109,7 +107,7 @@ class FlywayAutoConfigurationTests { "spring.flyway.user:sa") .run((context) -> { assertThat(context).hasSingleBean(Flyway.class); - assertThat(context.getBean(Flyway.class).getDataSource()).isNotNull(); + assertThat(context.getBean(Flyway.class).getConfiguration().getDataSource()).isNotNull(); }); } @@ -118,7 +116,7 @@ class FlywayAutoConfigurationTests { this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) .withPropertyValues("spring.flyway.url:jdbc:hsqldb:mem:flywaytest").run((context) -> { assertThat(context).hasSingleBean(Flyway.class); - DataSource dataSource = context.getBean(Flyway.class).getDataSource(); + DataSource dataSource = context.getBean(Flyway.class).getConfiguration().getDataSource(); assertThat(dataSource).isNotNull(); assertThat(dataSource).hasFieldOrPropertyWithValue("user", "sa"); assertThat(dataSource).hasFieldOrPropertyWithValue("password", ""); @@ -130,7 +128,7 @@ class FlywayAutoConfigurationTests { this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) .withPropertyValues("spring.flyway.user:sa").run((context) -> { assertThat(context).hasSingleBean(Flyway.class); - DataSource dataSource = context.getBean(Flyway.class).getDataSource(); + DataSource dataSource = context.getBean(Flyway.class).getConfiguration().getDataSource(); assertThat(dataSource).isNotNull(); assertThat(dataSource).extracting("url").asString().startsWith("jdbc:h2:mem:"); }); @@ -142,7 +140,7 @@ class FlywayAutoConfigurationTests { .withUserConfiguration(FlywayDataSourceConfiguration.class, EmbeddedDataSourceConfiguration.class) .run((context) -> { assertThat(context).hasSingleBean(Flyway.class); - assertThat(context.getBean(Flyway.class).getDataSource()) + assertThat(context.getBean(Flyway.class).getConfiguration().getDataSource()) .isEqualTo(context.getBean("flywayDataSource")); }); } @@ -151,7 +149,8 @@ class FlywayAutoConfigurationTests { void flywayDataSourceWithoutDataSourceAutoConfiguration() { this.contextRunner.withUserConfiguration(FlywayDataSourceConfiguration.class).run((context) -> { assertThat(context).hasSingleBean(Flyway.class); - assertThat(context.getBean(Flyway.class).getDataSource()).isEqualTo(context.getBean("flywayDataSource")); + assertThat(context.getBean(Flyway.class).getConfiguration().getDataSource()) + .isEqualTo(context.getBean("flywayDataSource")); }); } @@ -175,7 +174,8 @@ class FlywayAutoConfigurationTests { this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class).run((context) -> { assertThat(context).hasSingleBean(Flyway.class); Flyway flyway = context.getBean(Flyway.class); - assertThat(flyway.getLocations()).containsExactly(new Location("classpath:db/migration")); + assertThat(flyway.getConfiguration().getLocations()) + .containsExactly(new Location("classpath:db/migration")); }); } @@ -186,8 +186,8 @@ class FlywayAutoConfigurationTests { .run((context) -> { assertThat(context).hasSingleBean(Flyway.class); Flyway flyway = context.getBean(Flyway.class); - assertThat(flyway.getLocations()).containsExactly(new Location("classpath:db/changelog"), - new Location("classpath:db/migration")); + assertThat(flyway.getConfiguration().getLocations()).containsExactly( + new Location("classpath:db/changelog"), new Location("classpath:db/migration")); }); } @@ -199,8 +199,8 @@ class FlywayAutoConfigurationTests { .run((context) -> { assertThat(context).hasSingleBean(Flyway.class); Flyway flyway = context.getBean(Flyway.class); - assertThat(flyway.getLocations()).containsExactly(new Location("classpath:db/changelog"), - new Location("classpath:db/migration")); + assertThat(flyway.getConfiguration().getLocations()).containsExactly( + new Location("classpath:db/changelog"), new Location("classpath:db/migration")); }); } @@ -210,7 +210,7 @@ class FlywayAutoConfigurationTests { .withPropertyValues("spring.flyway.schemas:public").run((context) -> { assertThat(context).hasSingleBean(Flyway.class); Flyway flyway = context.getBean(Flyway.class); - assertThat(Arrays.asList(flyway.getSchemas()).toString()).isEqualTo("[public]"); + assertThat(Arrays.asList(flyway.getConfiguration().getSchemas()).toString()).isEqualTo("[public]"); }); } @@ -289,7 +289,8 @@ class FlywayAutoConfigurationTests { .withPropertyValues("spring.flyway.baseline-version=0").run((context) -> { assertThat(context).hasSingleBean(Flyway.class); Flyway flyway = context.getBean(Flyway.class); - assertThat(flyway.getBaselineVersion()).isEqualTo(MigrationVersion.fromVersion("0")); + assertThat(flyway.getConfiguration().getBaselineVersion()) + .isEqualTo(MigrationVersion.fromVersion("0")); }); } @@ -299,7 +300,8 @@ class FlywayAutoConfigurationTests { .withPropertyValues("spring.flyway.baseline-version=1").run((context) -> { assertThat(context).hasSingleBean(Flyway.class); Flyway flyway = context.getBean(Flyway.class); - assertThat(flyway.getBaselineVersion()).isEqualTo(MigrationVersion.fromVersion("1")); + assertThat(flyway.getConfiguration().getBaselineVersion()) + .isEqualTo(MigrationVersion.fromVersion("1")); }); } @@ -310,8 +312,8 @@ class FlywayAutoConfigurationTests { .run((context) -> { assertThat(context).hasSingleBean(Flyway.class); Flyway flyway = context.getBean(Flyway.class); - assertThat(flyway.getLocations()).containsExactlyInAnyOrder(new Location("classpath:db/vendors/h2"), - new Location("classpath:db/changelog")); + assertThat(flyway.getConfiguration().getLocations()).containsExactlyInAnyOrder( + new Location("classpath:db/vendors/h2"), new Location("classpath:db/changelog")); }); } @@ -321,7 +323,8 @@ class FlywayAutoConfigurationTests { .withPropertyValues("spring.flyway.locations=classpath:db/vendors/{vendor}").run((context) -> { assertThat(context).hasSingleBean(Flyway.class); Flyway flyway = context.getBean(Flyway.class); - assertThat(flyway.getLocations()).containsExactly(new Location("classpath:db/vendors/h2")); + assertThat(flyway.getConfiguration().getLocations()) + .containsExactly(new Location("classpath:db/vendors/h2")); }); } @@ -333,41 +336,14 @@ class FlywayAutoConfigurationTests { Flyway flyway = context.getBean(Flyway.class); Callback callbackOne = context.getBean("callbackOne", Callback.class); Callback callbackTwo = context.getBean("callbackTwo", Callback.class); - assertThat(flyway.getCallbacks()).hasSize(2); - assertThat(flyway.getCallbacks()).containsExactly(callbackTwo, callbackOne); + assertThat(flyway.getConfiguration().getCallbacks()).hasSize(2); + assertThat(flyway.getConfiguration().getCallbacks()).containsExactly(callbackTwo, callbackOne); InOrder orderedCallbacks = inOrder(callbackOne, callbackTwo); orderedCallbacks.verify(callbackTwo).handle(any(Event.class), any(Context.class)); orderedCallbacks.verify(callbackOne).handle(any(Event.class), any(Context.class)); }); } - @Test - void legacyCallbacksAreConfiguredAndOrdered() { - this.contextRunner - .withUserConfiguration(EmbeddedDataSourceConfiguration.class, LegacyCallbackConfiguration.class) - .run((context) -> { - assertThat(context).hasSingleBean(Flyway.class); - Flyway flyway = context.getBean(Flyway.class); - FlywayCallback callbackOne = context.getBean("legacyCallbackOne", FlywayCallback.class); - FlywayCallback callbackTwo = context.getBean("legacyCallbackTwo", FlywayCallback.class); - assertThat(flyway.getCallbacks()).hasSize(2); - InOrder orderedCallbacks = inOrder(callbackOne, callbackTwo); - orderedCallbacks.verify(callbackTwo).beforeMigrate(any(Connection.class)); - orderedCallbacks.verify(callbackOne).beforeMigrate(any(Connection.class)); - }); - } - - @Test - void callbacksAndLegacyCallbacksCannotBeMixed() { - this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class, - LegacyCallbackConfiguration.class, CallbackConfiguration.class).run((context) -> { - assertThat(context).hasFailed(); - assertThat(context.getStartupFailure()) - .hasMessageContaining("Found a mixture of Callback and FlywayCallback beans." - + " One type must be used exclusively."); - }); - } - @Test void configurationCustomizersAreConfiguredAndOrdered() { this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class, @@ -519,7 +495,7 @@ class FlywayAutoConfigurationTests { @Bean Flyway flyway() { - return new Flyway(); + return Flyway.configure().load(); } @Bean @@ -572,23 +548,6 @@ class FlywayAutoConfigurationTests { } - @Configuration(proxyBeanMethods = false) - static class LegacyCallbackConfiguration { - - @Bean - @Order(1) - FlywayCallback legacyCallbackOne() { - return mock(FlywayCallback.class); - } - - @Bean - @Order(0) - FlywayCallback legacyCallbackTwo() { - return mock(FlywayCallback.class); - } - - } - @Configuration(proxyBeanMethods = false) static class ConfigurationCustomizerConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayPropertiesTests.java index 83cf4753b66..672f4d388cf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayPropertiesTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayPropertiesTests.java @@ -96,9 +96,10 @@ class FlywayPropertiesTests { ignoreProperties(properties, "url", "user", "password", "enabled", "checkLocation", "createDataSource"); // High level object we can't set with properties - ignoreProperties(configuration, "classLoader", "dataSource", "resolvers", "callbacks"); + ignoreProperties(configuration, "classLoader", "dataSource", "resolvers", "callbacks", "javaMigrations"); // Properties we don't want to expose - ignoreProperties(configuration, "resolversAsClassNames", "callbacksAsClassNames"); + ignoreProperties(configuration, "resolversAsClassNames", "callbacksAsClassNames", "tablespace", + "oracleSqlplusWarn"); // Handled by the conversion service ignoreProperties(configuration, "baselineVersionAsString", "encodingAsString", "locationsAsStrings", "targetAsString"); @@ -107,8 +108,6 @@ class FlywayPropertiesTests { ignoreProperties(properties, "initSqls"); // Handled as dryRunOutput ignoreProperties(configuration, "dryRunOutputAsFile", "dryRunOutputAsFileName"); - // Deprecated - ignoreProperties(configuration, "errorHandlers", "errorHandlersAsClassNames"); List configurationKeys = new ArrayList<>(configuration.keySet()); Collections.sort(configurationKeys); List propertiesKeys = new ArrayList<>(properties.keySet()); diff --git a/spring-boot-project/spring-boot-dependencies/pom.xml b/spring-boot-project/spring-boot-dependencies/pom.xml index 286a7e32e08..92b22b64000 100644 --- a/spring-boot-project/spring-boot-dependencies/pom.xml +++ b/spring-boot-project/spring-boot-dependencies/pom.xml @@ -60,7 +60,7 @@ 2.10.6 3.8.0 2.2.0 - 5.2.4 + 6.0.1 2.3.28 6.8.2 3.0.2