Upgrade to Flyway 5.1.3

Closes gh-13672
pull/13706/head
Andy Wilkinson 6 years ago
parent 2348047450
commit b6b37c91bb

@ -29,6 +29,7 @@ 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.springframework.beans.factory.ObjectProvider;
@ -71,6 +72,7 @@ import org.springframework.util.StringUtils;
* @author Dominic Gunn
* @since 1.1.0
*/
@SuppressWarnings("deprecation")
@Configuration
@ConditionalOnClass(Flyway.class)
@ConditionalOnBean(DataSource.class)
@ -109,13 +111,16 @@ public class FlywayAutoConfiguration {
private final FlywayMigrationStrategy migrationStrategy;
private List<FlywayCallback> flywayCallbacks;
private final List<Callback> callbacks;
private final List<FlywayCallback> flywayCallbacks;
public FlywayConfiguration(FlywayProperties properties,
DataSourceProperties dataSourceProperties, ResourceLoader resourceLoader,
ObjectProvider<DataSource> dataSource,
@FlywayDataSource ObjectProvider<DataSource> flywayDataSource,
ObjectProvider<FlywayMigrationStrategy> migrationStrategy,
ObjectProvider<List<Callback>> callbacks,
ObjectProvider<List<FlywayCallback>> flywayCallbacks) {
this.properties = properties;
this.dataSourceProperties = dataSourceProperties;
@ -123,6 +128,7 @@ public class FlywayAutoConfiguration {
this.dataSource = dataSource.getIfUnique();
this.flywayDataSource = flywayDataSource.getIfAvailable();
this.migrationStrategy = migrationStrategy.getIfAvailable();
this.callbacks = callbacks.getIfAvailable(Collections::emptyList);
this.flywayCallbacks = flywayCallbacks.getIfAvailable(Collections::emptyList);
}
@ -146,7 +152,20 @@ public class FlywayAutoConfiguration {
else {
flyway.setDataSource(this.dataSource);
}
flyway.setCallbacks(this.flywayCallbacks.toArray(new FlywayCallback[0]));
if (this.flywayCallbacks.isEmpty()) {
flyway.setCallbacks(this.callbacks.toArray(new Callback[0]));
}
else {
if (this.callbacks.isEmpty()) {
flyway.setCallbacks(
this.flywayCallbacks.toArray(new FlywayCallback[0]));
}
else {
throw new IllegalStateException(
"Found a mixture of Callback and FlywayCallback beans."
+ " One type must be used exclusively.");
}
}
String[] locations = new LocationResolver(flyway.getDataSource())
.resolveLocations(this.properties.getLocations());
checkLocationExists(locations);

@ -24,7 +24,11 @@ import java.util.Map;
import javax.sql.DataSource;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.Location;
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.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform;
import org.junit.Test;
@ -48,6 +52,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.Mockito.inOrder;
import static org.mockito.Mockito.mock;
@ -62,6 +67,7 @@ import static org.mockito.Mockito.mock;
* @author Stephane Nicoll
* @author Dominic Gunn
*/
@SuppressWarnings("deprecation")
public class FlywayAutoConfigurationTests {
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
@ -137,7 +143,7 @@ public class FlywayAutoConfigurationTests {
assertThat(context).hasSingleBean(Flyway.class);
Flyway flyway = context.getBean(Flyway.class);
assertThat(flyway.getLocations())
.containsExactly("classpath:db/migration");
.containsExactly(new Location("classpath:db/migration"));
});
}
@ -150,7 +156,8 @@ public class FlywayAutoConfigurationTests {
assertThat(context).hasSingleBean(Flyway.class);
Flyway flyway = context.getBean(Flyway.class);
assertThat(flyway.getLocations()).containsExactly(
"classpath:db/changelog", "classpath:db/migration");
new Location("classpath:db/changelog"),
new Location("classpath:db/migration"));
});
}
@ -163,7 +170,8 @@ public class FlywayAutoConfigurationTests {
assertThat(context).hasSingleBean(Flyway.class);
Flyway flyway = context.getBean(Flyway.class);
assertThat(flyway.getLocations()).containsExactly(
"classpath:db/changelog", "classpath:db/migration");
new Location("classpath:db/changelog"),
new Location("classpath:db/migration"));
});
}
@ -278,7 +286,8 @@ public class FlywayAutoConfigurationTests {
assertThat(context).hasSingleBean(Flyway.class);
Flyway flyway = context.getBean(Flyway.class);
assertThat(flyway.getLocations()).containsExactlyInAnyOrder(
"classpath:db/vendors/h2", "classpath:db/changelog");
new Location("classpath:db/vendors/h2"),
new Location("classpath:db/changelog"));
});
}
@ -291,7 +300,7 @@ public class FlywayAutoConfigurationTests {
assertThat(context).hasSingleBean(Flyway.class);
Flyway flyway = context.getBean(Flyway.class);
assertThat(flyway.getLocations())
.containsExactly("classpath:db/vendors/h2");
.containsExactly(new Location("classpath:db/vendors/h2"));
});
}
@ -301,14 +310,31 @@ public class FlywayAutoConfigurationTests {
CallbackConfiguration.class).run((context) -> {
assertThat(context).hasSingleBean(Flyway.class);
Flyway flyway = context.getBean(Flyway.class);
FlywayCallback callbackOne = context.getBean("callbackOne",
FlywayCallback.class);
FlywayCallback callbackTwo = context.getBean("callbackTwo",
FlywayCallback.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);
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
public 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)
@ -316,6 +342,19 @@ public class FlywayAutoConfigurationTests {
});
}
@Test
public 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.");
});
}
@Configuration
protected static class FlywayDataSourceConfiguration {
@ -395,13 +434,37 @@ public class FlywayAutoConfigurationTests {
@Bean
@Order(1)
public FlywayCallback callbackOne() {
public Callback callbackOne() {
return mockCallback();
}
@Bean
@Order(0)
public Callback callbackTwo() {
return mockCallback();
}
private Callback mockCallback() {
Callback callback = mock(Callback.class);
given(callback.supports(any(Event.class), any(Context.class)))
.willReturn(true);
return callback;
}
}
@Configuration
static class LegacyCallbackConfiguration {
@Bean
@Order(1)
public FlywayCallback legacyCallbackOne() {
return mock(FlywayCallback.class);
}
@Bean
@Order(0)
public FlywayCallback callbackTwo() {
public FlywayCallback legacyCallbackTwo() {
return mock(FlywayCallback.class);
}

@ -58,7 +58,7 @@
<ehcache.version>2.10.5</ehcache.version>
<ehcache3.version>3.5.2</ehcache3.version>
<embedded-mongo.version>2.1.1</embedded-mongo.version>
<flyway.version>5.0.7</flyway.version>
<flyway.version>5.1.3</flyway.version>
<freemarker.version>2.3.28</freemarker.version>
<elasticsearch.version>6.3.0</elasticsearch.version>
<glassfish-el.version>3.0.0</glassfish-el.version>

@ -2225,9 +2225,10 @@ more control, provide a `@Bean` that implements
Flyway supports SQL and Java https://flywaydb.org/documentation/callbacks.html[callbacks].
To use SQL-based callbacks, place the callback scripts in the `classpath:db/migration`
folder. To use Java-based callbacks, create one or more beans that implement
`FlywayCallback` or, preferably, extend `BaseFlywayCallback`. Any such beans are
automatically registered with `Flyway`. They can be ordered by using `@Order` or by
implementing `Ordered`.
`Callback`. Any such beans are automatically registered with `Flyway`. They can be
ordered by using `@Order` or by implementing `Ordered`. Beans that implement the
deprecated `FlywayCallback` interface can also be detected, however they cannot be used
alongside `Callback` beans.
By default, Flyway autowires the (`@Primary`) `DataSource` in your context and
uses that for migrations. If you like to use a different `DataSource`, you can create

Loading…
Cancel
Save