Upgrade to Flyway 9.20.1
Closes gh-36364 Co-authored-by: Andy Wilkinson <wilkinsona@vmware.com>
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -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;
|
||||
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;
|
||||
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;
|
||||
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 {
|
||||
@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 {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(FlywayConnectionDetails.class)
|
||||
PropertiesFlywayConnectionDetails flywayConnectionDetails(FlywayProperties properties) {
|
||||
return new PropertiesFlywayConnectionDetails(properties);
|
||||
PropertiesFlywayConnectionDetails flywayConnectionDetails() {
|
||||
return new PropertiesFlywayConnectionDetails(this.properties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
Flyway flyway(FlywayProperties properties, FlywayConnectionDetails connectionDetails,
|
||||
ResourceLoader resourceLoader, ObjectProvider<DataSource> dataSource,
|
||||
@FlywayDataSource ObjectProvider<DataSource> flywayDataSource,
|
||||
@ConditionalOnClass(name = "org.flywaydb.database.oracle.OracleConfigurationExtension")
|
||||
OracleFlywayConfigurationCustomizer oracleFlywayConfigurationCustomizer() {
|
||||
return new OracleFlywayConfigurationCustomizer(this.properties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
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 {
|
||||
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 {
|
||||
|
||||
}
|
||||
|
||||
@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);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
@@ -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;
|
||||
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;
|
||||
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 {
|
||||
+ "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 {
|
||||
.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)
|
||||
|
||||
@@ -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 {
|
||||
// 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());
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user