Browse Source

Upgrade to Flyway 9.20.1

Closes gh-36364

Co-authored-by: Andy Wilkinson <wilkinsona@vmware.com>
pull/36422/head
Stephane Nicoll 3 years ago
parent
commit
fb640c04e7
  1. 1
      spring-boot-project/spring-boot-autoconfigure/build.gradle
  2. 87
      spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java
  3. 9
      spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway91AutoConfigurationTests.java
  4. 53
      spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java
  5. 5
      spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayPropertiesTests.java
  6. 3
      spring-boot-project/spring-boot-dependencies/build.gradle

1
spring-boot-project/spring-boot-autoconfigure/build.gradle

@ -104,6 +104,7 @@ dependencies { @@ -104,6 +104,7 @@ dependencies {
exclude group: "commons-logging", module: "commons-logging"
}
optional("org.flywaydb:flyway-core")
optional("org.flywaydb:flyway-database-oracle")
optional("org.flywaydb:flyway-sqlserver")
optional("org.freemarker:freemarker")
optional("org.glassfish.jersey.containers:jersey-container-servlet-core")

87
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java

@ -24,6 +24,9 @@ import java.util.HashSet; @@ -24,6 +24,9 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
import javax.sql.DataSource;
@ -32,6 +35,8 @@ import org.flywaydb.core.api.MigrationVersion; @@ -32,6 +35,8 @@ import org.flywaydb.core.api.MigrationVersion;
import org.flywaydb.core.api.callback.Callback;
import org.flywaydb.core.api.configuration.FluentConfiguration;
import org.flywaydb.core.api.migration.JavaMigration;
import org.flywaydb.core.extensibility.ConfigurationExtension;
import org.flywaydb.database.oracle.OracleConfigurationExtension;
import org.flywaydb.database.sqlserver.SQLServerConfigurationExtension;
import org.springframework.aot.hint.RuntimeHints;
@ -61,6 +66,8 @@ import org.springframework.context.annotation.Conditional; @@ -61,6 +66,8 @@ import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.core.io.ResourceLoader;
@ -71,6 +78,7 @@ import org.springframework.util.Assert; @@ -71,6 +78,7 @@ import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.function.SingletonSupplier;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Flyway database migrations.
@ -116,6 +124,12 @@ public class FlywayAutoConfiguration { @@ -116,6 +124,12 @@ public class FlywayAutoConfiguration {
@EnableConfigurationProperties(FlywayProperties.class)
public static class FlywayConfiguration {
private final FlywayProperties properties;
FlywayConfiguration(FlywayProperties properties) {
this.properties = properties;
}
@Bean
ResourceProviderCustomizer resourceProviderCustomizer() {
return new ResourceProviderCustomizer();
@ -123,21 +137,26 @@ public class FlywayAutoConfiguration { @@ -123,21 +137,26 @@ public class FlywayAutoConfiguration {
@Bean
@ConditionalOnMissingBean(FlywayConnectionDetails.class)
PropertiesFlywayConnectionDetails flywayConnectionDetails(FlywayProperties properties) {
return new PropertiesFlywayConnectionDetails(properties);
PropertiesFlywayConnectionDetails flywayConnectionDetails() {
return new PropertiesFlywayConnectionDetails(this.properties);
}
@Bean
@ConditionalOnClass(name = "org.flywaydb.database.oracle.OracleConfigurationExtension")
OracleFlywayConfigurationCustomizer oracleFlywayConfigurationCustomizer() {
return new OracleFlywayConfigurationCustomizer(this.properties);
}
@Bean
Flyway flyway(FlywayProperties properties, FlywayConnectionDetails connectionDetails,
ResourceLoader resourceLoader, ObjectProvider<DataSource> dataSource,
@FlywayDataSource ObjectProvider<DataSource> flywayDataSource,
Flyway flyway(FlywayConnectionDetails connectionDetails, ResourceLoader resourceLoader,
ObjectProvider<DataSource> dataSource, @FlywayDataSource ObjectProvider<DataSource> flywayDataSource,
ObjectProvider<FlywayConfigurationCustomizer> fluentConfigurationCustomizers,
ObjectProvider<JavaMigration> javaMigrations, ObjectProvider<Callback> callbacks,
ResourceProviderCustomizer resourceProviderCustomizer) {
FluentConfiguration configuration = new FluentConfiguration(resourceLoader.getClassLoader());
configureDataSource(configuration, flywayDataSource.getIfAvailable(), dataSource.getIfUnique(),
connectionDetails);
configureProperties(configuration, properties);
configureProperties(configuration, this.properties);
configureCallbacks(configuration, callbacks.orderedStream().toList());
configureJavaMigrations(configuration, javaMigrations.orderedStream().toList());
fluentConfigurationCustomizers.orderedStream().forEach((customizer) -> customizer.customize(configuration));
@ -242,12 +261,6 @@ public class FlywayAutoConfiguration { @@ -242,12 +261,6 @@ public class FlywayAutoConfiguration {
map.from(properties.getDryRunOutput()).to(configuration::dryRunOutput);
map.from(properties.getErrorOverrides()).to(configuration::errorOverrides);
map.from(properties.getLicenseKey()).to(configuration::licenseKey);
// No method references for Oracle props for compatibility with Flyway 9.20+
map.from(properties.getOracleSqlplus()).to((oracleSqlplus) -> configuration.oracleSqlplus(oracleSqlplus));
map.from(properties.getOracleSqlplusWarn())
.to((oracleSqlplusWarn) -> configuration.oracleSqlplusWarn(oracleSqlplusWarn));
map.from(properties.getOracleKerberosCacheFile())
.to((oracleKerberosCacheFile) -> configuration.oracleKerberosCacheFile(oracleKerberosCacheFile));
map.from(properties.getStream()).to(configuration::stream);
map.from(properties.getUndoSqlMigrationPrefix()).to(configuration::undoSqlMigrationPrefix);
map.from(properties.getCherryPick()).to(configuration::cherryPick);
@ -445,4 +458,54 @@ public class FlywayAutoConfiguration { @@ -445,4 +458,54 @@ public class FlywayAutoConfiguration {
}
@Order(Ordered.HIGHEST_PRECEDENCE)
static final class OracleFlywayConfigurationCustomizer implements FlywayConfigurationCustomizer {
private final FlywayProperties properties;
OracleFlywayConfigurationCustomizer(FlywayProperties properties) {
this.properties = properties;
}
@Override
public void customize(FluentConfiguration configuration) {
ConfigurationExtensionMapper<OracleConfigurationExtension> map = new ConfigurationExtensionMapper<>(
PropertyMapper.get().alwaysApplyingWhenNonNull(), () -> {
OracleConfigurationExtension extension = configuration.getPluginRegister()
.getPlugin(OracleConfigurationExtension.class);
Assert.notNull(extension, "Flyway Oracle extension missing");
return extension;
});
map.apply(this.properties.getOracleSqlplus(), OracleConfigurationExtension::setSqlplus);
map.apply(this.properties.getOracleSqlplusWarn(), OracleConfigurationExtension::setSqlplusWarn);
map.apply(this.properties.getOracleWalletLocation(), OracleConfigurationExtension::setWalletLocation);
map.apply(this.properties.getOracleKerberosCacheFile(), OracleConfigurationExtension::setKerberosCacheFile);
}
}
static class ConfigurationExtensionMapper<T extends ConfigurationExtension> {
private final PropertyMapper map;
private final Supplier<T> extensionProvider;
ConfigurationExtensionMapper(PropertyMapper map, Supplier<T> extensionProvider) {
this.map = map;
this.extensionProvider = SingletonSupplier.of(extensionProvider);
}
<V> void apply(V value, BiConsumer<T, V> mapper) {
this.map.from(value).to(withExtension(mapper));
}
private <V> Consumer<V> withExtension(BiConsumer<T, V> mapper) {
return (value) -> {
T extension = this.extensionProvider.get();
mapper.accept(extension, value);
};
}
}
}

9
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway920AutoConfigurationTests.java → spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway91AutoConfigurationTests.java

@ -23,18 +23,19 @@ import org.junit.jupiter.api.Test; @@ -23,18 +23,19 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
import org.springframework.boot.testsupport.classpath.ClassPathOverrides;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link FlywayAutoConfiguration} with Flyway 9.20.
* Tests for {@link FlywayAutoConfiguration} with Flyway 9.19.
*
* @author Andy Wilkinson
*/
@ClassPathOverrides({ "org.flywaydb:flyway-core:9.20.0", "org.flywaydb:flyway-sqlserver:9.20.0",
"com.h2database:h2:2.1.210" })
class Flyway920AutoConfigurationTests {
@ClassPathExclusions("flyway-*.jar")
@ClassPathOverrides("org.flywaydb:flyway-core:9.19.4")
class Flyway91AutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class))

53
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java

@ -31,8 +31,10 @@ import org.flywaydb.core.api.MigrationVersion; @@ -31,8 +31,10 @@ 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.configuration.FluentConfiguration;
import org.flywaydb.core.api.migration.JavaMigration;
import org.flywaydb.core.internal.license.FlywayTeamsUpgradeRequiredException;
import org.flywaydb.database.oracle.OracleConfigurationExtension;
import org.flywaydb.database.sqlserver.SQLServerConfigurationExtension;
import org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform;
import org.jooq.DSLContext;
@ -49,6 +51,7 @@ import org.springframework.beans.factory.BeanCreationException; @@ -49,6 +51,7 @@ import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.FlywayAutoConfigurationRuntimeHints;
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.OracleFlywayConfigurationCustomizer;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
@ -84,6 +87,7 @@ import org.springframework.stereotype.Component; @@ -84,6 +87,7 @@ import org.springframework.stereotype.Component;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
@ -602,18 +606,56 @@ class FlywayAutoConfigurationTests { @@ -602,18 +606,56 @@ class FlywayAutoConfigurationTests {
+ "Enterprise features, download Flyway Teams Edition & Flyway Enterprise Edition"));
}
@Test
void oracleExtensionIsNotLoadedByDefault() {
FluentConfiguration configuration = mock(FluentConfiguration.class);
new OracleFlywayConfigurationCustomizer(new FlywayProperties()).customize(configuration);
then(configuration).shouldHaveNoInteractions();
}
@Test
void oracleSqlplusIsCorrectlyMapped() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.flyway.oracle-sqlplus=true")
.run(validateFlywayTeamsPropertyOnly("oracle.sqlplus"));
.run((context) -> assertThat(context.getBean(Flyway.class)
.getConfiguration()
.getPluginRegister()
.getPlugin(OracleConfigurationExtension.class)
.getSqlplus()).isTrue());
}
@Test
void oracleSqlplusWarnIsCorrectlyMapped() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.flyway.oracle-sqlplus-warn=true")
.run(validateFlywayTeamsPropertyOnly("oracle.sqlplusWarn"));
.run((context) -> assertThat(context.getBean(Flyway.class)
.getConfiguration()
.getPluginRegister()
.getPlugin(OracleConfigurationExtension.class)
.getSqlplusWarn()).isTrue());
}
@Test
void oracleWallerLocationIsCorrectlyMapped() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.flyway.oracle-wallet-location=/tmp/my.wallet")
.run((context) -> assertThat(context.getBean(Flyway.class)
.getConfiguration()
.getPluginRegister()
.getPlugin(OracleConfigurationExtension.class)
.getWalletLocation()).isEqualTo("/tmp/my.wallet"));
}
@Test
void oracleKerberosCacheFileIsCorrectlyMapped() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.flyway.oracle-kerberos-cache-file=/tmp/cache")
.run((context) -> assertThat(context.getBean(Flyway.class)
.getConfiguration()
.getPluginRegister()
.getPlugin(OracleConfigurationExtension.class)
.getKerberosCacheFile()).isEqualTo("/tmp/cache"));
}
@Test
@ -683,13 +725,6 @@ class FlywayAutoConfigurationTests { @@ -683,13 +725,6 @@ class FlywayAutoConfigurationTests {
.run(validateFlywayTeamsPropertyOnly("kerberosConfigFile"));
}
@Test
void oracleKerberosCacheFileIsCorrectlyMapped() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.flyway.oracle-kerberos-cache-file=/tmp/cache")
.run(validateFlywayTeamsPropertyOnly("oracle.kerberosCacheFile"));
}
@Test
void outputQueryResultsIsCorrectlyMapped() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)

5
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayPropertiesTests.java

@ -109,6 +109,9 @@ class FlywayPropertiesTests { @@ -109,6 +109,9 @@ class FlywayPropertiesTests {
PropertyAccessorFactory.forBeanPropertyAccess(new ClassicConfiguration()));
// Properties specific settings
ignoreProperties(properties, "url", "driverClassName", "user", "password", "enabled");
// Property that moved to a separate Oracle plugin
ignoreProperties(properties, "oracleSqlplus", "oracleSqlplusWarn", "oracleKerberosCacheFile",
"oracleWalletLocation");
// Property that moved to a separate SQL plugin
ignoreProperties(properties, "sqlServerKerberosLoginFile");
// High level object we can't set with properties
@ -128,7 +131,7 @@ class FlywayPropertiesTests { @@ -128,7 +131,7 @@ class FlywayPropertiesTests {
// Handled as createSchemas
ignoreProperties(configuration, "shouldCreateSchemas");
// Getters for the DataSource settings rather than actual properties
ignoreProperties(configuration, "password", "url", "user");
ignoreProperties(configuration, "databaseType", "password", "url", "user");
// Properties not exposed by Flyway
ignoreProperties(configuration, "failOnMissingTarget");
List<String> configurationKeys = new ArrayList<>(configuration.keySet());

3
spring-boot-project/spring-boot-dependencies/build.gradle

@ -279,10 +279,11 @@ bom { @@ -279,10 +279,11 @@ bom {
]
}
}
library("Flyway", "9.19.4") {
library("Flyway", "9.20.1") {
group("org.flywaydb") {
modules = [
"flyway-core",
"flyway-database-oracle",
"flyway-firebird",
"flyway-mysql",
"flyway-sqlserver"

Loading…
Cancel
Save