Upgrade to Flyway 8.0.0

Closes gh-28296
This commit is contained in:
Andy Wilkinson 2021-10-12 13:39:18 +01:00
parent 668513e740
commit 509427b671
8 changed files with 159 additions and 20 deletions

View File

@ -210,10 +210,7 @@ public class FlywayAutoConfiguration {
map.from(properties.isCleanDisabled()).to(configuration::cleanDisabled);
map.from(properties.isCleanOnValidationError()).to(configuration::cleanOnValidationError);
map.from(properties.isGroup()).to(configuration::group);
map.from(properties.isIgnoreMissingMigrations()).to(configuration::ignoreMissingMigrations);
map.from(properties.isIgnoreIgnoredMigrations()).to(configuration::ignoreIgnoredMigrations);
map.from(properties.isIgnorePendingMigrations()).to(configuration::ignorePendingMigrations);
map.from(properties.isIgnoreFutureMigrations()).to(configuration::ignoreFutureMigrations);
configureIgnoredMigrations(configuration, properties, map);
map.from(properties.isMixed()).to(configuration::mixed);
map.from(properties.isOutOfOrder()).to(configuration::outOfOrder);
map.from(properties.isSkipDefaultCallbacks()).to(configuration::skipDefaultCallbacks);
@ -262,6 +259,18 @@ public class FlywayAutoConfiguration {
// No method reference for compatibility with Flyway version < 7.9
map.from(properties.getDetectEncoding())
.to((detectEncoding) -> configuration.detectEncoding(detectEncoding));
// No method reference for compatibility with Flyway version < 8.0
map.from(properties.getBaselineMigrationPrefix())
.to((baselineMigrationPrefix) -> configuration.baselineMigrationPrefix(baselineMigrationPrefix));
}
@SuppressWarnings("deprecation")
private void configureIgnoredMigrations(FluentConfiguration configuration, FlywayProperties properties,
PropertyMapper map) {
map.from(properties.isIgnoreMissingMigrations()).to(configuration::ignoreMissingMigrations);
map.from(properties.isIgnoreIgnoredMigrations()).to(configuration::ignoreIgnoredMigrations);
map.from(properties.isIgnorePendingMigrations()).to(configuration::ignorePendingMigrations);
map.from(properties.isIgnoreFutureMigrations()).to(configuration::ignoreFutureMigrations);
}
private void configureFailOnMissingLocations(FluentConfiguration configuration,

View File

@ -227,21 +227,25 @@ public class FlywayProperties {
/**
* Whether to ignore missing migrations when reading the schema history table.
*/
@Deprecated
private boolean ignoreMissingMigrations;
/**
* Whether to ignore ignored migrations when reading the schema history table.
*/
@Deprecated
private boolean ignoreIgnoredMigrations;
/**
* Whether to ignore pending migrations when reading the schema history table.
*/
@Deprecated
private boolean ignorePendingMigrations;
/**
* Whether to ignore future migrations when reading the schema history table.
*/
@Deprecated
private boolean ignoreFutureMigrations = true;
/**
@ -371,9 +375,9 @@ public class FlywayProperties {
private Boolean detectEncoding;
/**
* Filename prefix of state scripts. Requires Flyway Teams.
* Filename prefix for baseline migrations. Requires Flyway Teams.
*/
private String stateScriptPrefix;
private String baselineMigrationPrefix;
/**
* Prefix of placeholders in migration scripts.
@ -672,34 +676,46 @@ public class FlywayProperties {
this.group = group;
}
@Deprecated
@DeprecatedConfigurationProperty(replacement = "spring.flyway.ignore-migration-patterns")
public boolean isIgnoreMissingMigrations() {
return this.ignoreMissingMigrations;
}
@Deprecated
public void setIgnoreMissingMigrations(boolean ignoreMissingMigrations) {
this.ignoreMissingMigrations = ignoreMissingMigrations;
}
@Deprecated
@DeprecatedConfigurationProperty(replacement = "spring.flyway.ignore-migration-patterns")
public boolean isIgnoreIgnoredMigrations() {
return this.ignoreIgnoredMigrations;
}
@Deprecated
public void setIgnoreIgnoredMigrations(boolean ignoreIgnoredMigrations) {
this.ignoreIgnoredMigrations = ignoreIgnoredMigrations;
}
@Deprecated
@DeprecatedConfigurationProperty(replacement = "spring.flyway.ignore-migration-patterns")
public boolean isIgnorePendingMigrations() {
return this.ignorePendingMigrations;
}
@Deprecated
public void setIgnorePendingMigrations(boolean ignorePendingMigrations) {
this.ignorePendingMigrations = ignorePendingMigrations;
}
@Deprecated
@DeprecatedConfigurationProperty(replacement = "spring.flyway.ignore-migration-patterns")
public boolean isIgnoreFutureMigrations() {
return this.ignoreFutureMigrations;
}
@Deprecated
public void setIgnoreFutureMigrations(boolean ignoreFutureMigrations) {
this.ignoreFutureMigrations = ignoreFutureMigrations;
}
@ -888,12 +904,12 @@ public class FlywayProperties {
this.detectEncoding = detectEncoding;
}
public String getStateScriptPrefix() {
return this.stateScriptPrefix;
public String getBaselineMigrationPrefix() {
return this.baselineMigrationPrefix;
}
public void setStateScriptPrefix(String stateScriptPrefix) {
this.stateScriptPrefix = stateScriptPrefix;
public void setBaselineMigrationPrefix(String baselineMigrationPrefix) {
this.baselineMigrationPrefix = baselineMigrationPrefix;
}
public String getScriptPlaceholderPrefix() {

View File

@ -872,6 +872,10 @@
"http://localhost:9200"
]
},
{
"name": "spring.flyway.baseline-migration-prefix",
"defaultValue": "B"
},
{
"name": "spring.flyway.connect-retries-interval",
"defaultValue": 120

View File

@ -117,7 +117,7 @@ class Flyway5xAutoConfigurationTests {
}
@Override
public boolean isStateScript() {
public boolean isBaselineMigration() {
return false;
}

View File

@ -0,0 +1,100 @@
/*
* Copyright 2012-2020 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.autoconfigure.flyway;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.Location;
import org.flywaydb.core.api.callback.Callback;
import org.flywaydb.core.api.callback.Context;
import org.flywaydb.core.api.callback.Event;
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.ClassPathOverrides;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link FlywayAutoConfiguration} with Flyway 7.x.
*
* @author Andy Wilkinson
*/
@ClassPathOverrides("org.flywaydb:flyway-core:7.15.0")
class Flyway7xAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class))
.withPropertyValues("spring.datasource.generate-unique-name=true");
@Test
void defaultFlyway() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class).run((context) -> {
assertThat(context).hasSingleBean(Flyway.class);
Flyway flyway = context.getBean(Flyway.class);
assertThat(flyway.getConfiguration().getLocations())
.containsExactly(new Location("classpath:db/migration"));
});
}
@Test
void callbacksAreConfigured() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class, CallbackConfiguration.class)
.run((context) -> {
assertThat(context).hasSingleBean(Flyway.class);
Flyway flyway = context.getBean(Flyway.class);
Callback callbackOne = context.getBean("callbackOne", Callback.class);
Callback callbackTwo = context.getBean("callbackTwo", Callback.class);
assertThat(flyway.getConfiguration().getCallbacks()).hasSize(2);
assertThat(flyway.getConfiguration().getCallbacks()).containsExactlyInAnyOrder(callbackTwo,
callbackOne);
verify(callbackOne, atLeastOnce()).handle(any(Event.class), any(Context.class));
verify(callbackTwo, atLeastOnce()).handle(any(Event.class), any(Context.class));
});
}
@Configuration(proxyBeanMethods = false)
static class CallbackConfiguration {
@Bean
Callback callbackOne() {
return mockCallback();
}
@Bean
Callback callbackTwo() {
return mockCallback();
}
private Callback mockCallback() {
Callback callback = mock(Callback.class);
given(callback.supports(any(Event.class), any(Context.class))).willReturn(true);
given(callback.getCallbackName()).willReturn("callback");
return callback;
}
}
}

View File

@ -499,8 +499,9 @@ class FlywayAutoConfigurationTests {
assertThat(context).hasSingleBean(Flyway.class);
Flyway flyway = context.getBean(Flyway.class);
assertThat(flyway.getConfiguration().getConnectRetries()).isEqualTo(5);
assertThat(flyway.getConfiguration().isIgnoreMissingMigrations()).isTrue();
assertThat(flyway.getConfiguration().isIgnorePendingMigrations()).isTrue();
assertThat(flyway.getConfiguration().getBaselineDescription()).isEqualTo("<< Custom baseline >>");
assertThat(flyway.getConfiguration().getBaselineVersion())
.isEqualTo(MigrationVersion.fromVersion("1"));
});
}
@ -657,6 +658,13 @@ class FlywayAutoConfigurationTests {
});
}
@Test
void baselineMigrationPrefixIsCorrectlyMapped() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.flyway.baseline-migration-prefix=BL")
.run(validateFlywayTeamsPropertyOnly("baselineMigrationPrefix"));
}
private ContextConsumer<AssertableApplicationContext> validateFlywayTeamsPropertyOnly(String propertyName) {
return (context) -> {
assertThat(context).hasFailed();
@ -892,13 +900,13 @@ class FlywayAutoConfigurationTests {
@Bean
@Order(1)
FlywayConfigurationCustomizer customizerOne() {
return (configuration) -> configuration.connectRetries(5).ignorePendingMigrations(true);
return (configuration) -> configuration.connectRetries(5).baselineVersion("1");
}
@Bean
@Order(0)
FlywayConfigurationCustomizer customizerTwo() {
return (configuration) -> configuration.connectRetries(10).ignoreMissingMigrations(true);
return (configuration) -> configuration.connectRetries(10).baselineDescription("<< Custom baseline >>");
}
}
@ -1008,7 +1016,7 @@ class FlywayAutoConfigurationTests {
}
@Override
public boolean isStateScript() {
public boolean isBaselineMigration() {
return false;
}

View File

@ -44,11 +44,12 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class FlywayPropertiesTests {
@SuppressWarnings("deprecation")
@Test
void defaultValuesAreConsistent() {
FlywayProperties properties = new FlywayProperties();
Configuration configuration = new FluentConfiguration();
assertThat(configuration.getFailOnMissingLocations()).isEqualTo(properties.isFailOnMissingLocations());
assertThat(configuration.isFailOnMissingLocations()).isEqualTo(properties.isFailOnMissingLocations());
assertThat(properties.getLocations().stream().map(Location::new).toArray(Location[]::new))
.isEqualTo(configuration.getLocations());
assertThat(properties.getEncoding()).isEqualTo(configuration.getEncoding());
@ -61,7 +62,7 @@ class FlywayPropertiesTests {
assertThat(configuration.getLockRetryCount()).isEqualTo(50);
assertThat(properties.getDefaultSchema()).isEqualTo(configuration.getDefaultSchema());
assertThat(properties.getSchemas()).isEqualTo(Arrays.asList(configuration.getSchemas()));
assertThat(properties.isCreateSchemas()).isEqualTo(configuration.getCreateSchemas());
assertThat(properties.isCreateSchemas()).isEqualTo(configuration.isCreateSchemas());
assertThat(properties.getTable()).isEqualTo(configuration.getTable());
assertThat(properties.getBaselineDescription()).isEqualTo(configuration.getBaselineDescription());
assertThat(MigrationVersion.fromVersion(properties.getBaselineVersion()))
@ -113,7 +114,8 @@ class FlywayPropertiesTests {
ignoreProperties(configuration, "callbacks", "classLoader", "dataSource", "javaMigrations",
"javaMigrationClassProvider", "resourceProvider", "resolvers");
// Properties we don't want to expose
ignoreProperties(configuration, "resolversAsClassNames", "callbacksAsClassNames", "apiExtensions", "loggers");
ignoreProperties(configuration, "resolversAsClassNames", "callbacksAsClassNames", "apiExtensions", "loggers",
"driver");
// Handled by the conversion service
ignoreProperties(configuration, "baselineVersionAsString", "encodingAsString", "locationsAsStrings",
"targetAsString");

View File

@ -309,7 +309,7 @@ bom {
]
}
}
library("Flyway", "7.15.0") {
library("Flyway", "8.0.0") {
group("org.flywaydb") {
modules = [
"flyway-core"