diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java index 5974e6b9a3..0b5f64f9a6 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java @@ -40,11 +40,14 @@ import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfigurat import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jdbc.DatabaseDriver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.GenericConverter; import org.springframework.core.io.ResourceLoader; +import org.springframework.jdbc.support.JdbcUtils; +import org.springframework.jdbc.support.MetaDataAccessException; import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.util.Assert; @@ -79,6 +82,8 @@ public class FlywayAutoConfiguration { @EnableConfigurationProperties(FlywayProperties.class) public static class FlywayConfiguration { + private static final String VENDOR_PLACEHOLDER = "{vendor}"; + private final FlywayProperties properties; private final ResourceLoader resourceLoader; @@ -126,7 +131,31 @@ public class FlywayAutoConfiguration { @Bean @ConfigurationProperties(prefix = "flyway") public Flyway flyway() { - Flyway flyway = new Flyway(); + Flyway flyway = new Flyway() { + + @Override + public void setLocations(String... locations) { + if (usesVendorLocation()) { + try { + String url = (String) JdbcUtils.extractDatabaseMetaData( + getDataSource(), "getURL"); + DatabaseDriver vendor = DatabaseDriver.fromJdbcUrl(url); + if (vendor != DatabaseDriver.UNKNOWN) { + for (int i = 0; i < locations.length; i++) { + locations[i] = locations[i].replace( + VENDOR_PLACEHOLDER, + vendor.name().toLowerCase()); + } + } + } + catch (MetaDataAccessException e) { + throw new IllegalStateException(e); + } + } + super.setLocations(locations); + } + + }; if (this.properties.isCreateDataSource()) { flyway.setDataSource(this.properties.getUrl(), this.properties.getUser(), this.properties.getPassword(), @@ -142,6 +171,15 @@ public class FlywayAutoConfiguration { return flyway; } + private boolean usesVendorLocation() { + for (String location : this.properties.getLocations()) { + if (location.contains(VENDOR_PLACEHOLDER)) { + return true; + } + } + return false; + } + @Bean @ConditionalOnMissingBean public FlywayMigrationInitializer flywayInitializer(Flyway flyway) { diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java index c9426e6171..196ff1e286 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java @@ -234,6 +234,18 @@ public class FlywayAutoConfigurationTests { .isEqualTo(MigrationVersion.fromVersion("1")); } + @Test + public void useVendorDirectory() throws Exception { + EnvironmentTestUtils.addEnvironment(this.context, + "flyway.locations:classpath:db/vendors/{vendor}"); + registerAndRefresh(EmbeddedDataSourceConfiguration.class, + FlywayAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + Flyway flyway = this.context.getBean(Flyway.class); + assertThat(flyway.getLocations()).containsExactly( + "classpath:db/vendors/h2"); + } + private void registerAndRefresh(Class... annotatedClasses) { this.context.register(annotatedClasses); this.context.refresh(); diff --git a/spring-boot-autoconfigure/src/test/resources/db/vendors/h2/V1__init.sql b/spring-boot-autoconfigure/src/test/resources/db/vendors/h2/V1__init.sql new file mode 100644 index 0000000000..e69de29bb2