diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java index 9b768756ca..a47791944d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java @@ -36,6 +36,7 @@ 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.core.internal.database.postgresql.PostgreSQLConfigurationExtension; import org.flywaydb.database.oracle.OracleConfigurationExtension; import org.flywaydb.database.sqlserver.SQLServerConfigurationExtension; @@ -153,6 +154,12 @@ public class FlywayAutoConfiguration { return new OracleFlywayConfigurationCustomizer(this.properties); } + @Bean + @ConditionalOnClass(name = "org.flywaydb.core.internal.database.postgresql.PostgreSQLConfigurationExtension") + PostgresqlFlywayConfigurationCustomizer postgresqlFlywayConfigurationCustomizer() { + return new PostgresqlFlywayConfigurationCustomizer(this.properties); + } + @Bean Flyway flyway(FlywayConnectionDetails connectionDetails, ResourceLoader resourceLoader, ObjectProvider dataSource, @FlywayDataSource ObjectProvider flywayDataSource, @@ -478,6 +485,30 @@ public class FlywayAutoConfiguration { } + @Order(Ordered.HIGHEST_PRECEDENCE) + static final class PostgresqlFlywayConfigurationCustomizer implements FlywayConfigurationCustomizer { + + private final FlywayProperties properties; + + PostgresqlFlywayConfigurationCustomizer(FlywayProperties properties) { + this.properties = properties; + } + + @Override + public void customize(FluentConfiguration configuration) { + ConfigurationExtensionMapper map = new ConfigurationExtensionMapper<>( + PropertyMapper.get().alwaysApplyingWhenNonNull(), () -> { + PostgreSQLConfigurationExtension extension = configuration.getPluginRegister() + .getPlugin(PostgreSQLConfigurationExtension.class); + Assert.notNull(extension, "PostgreSQL extension missing"); + return extension; + }); + map.apply(this.properties.getPostgresql().getTransactionalLock(), + PostgreSQLConfigurationExtension::setTransactionalLock); + } + + } + @Order(Ordered.HIGHEST_PRECEDENCE) static final class SqlServerFlywayConfigurationCustomizer implements FlywayConfigurationCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayProperties.java index b629e7c425..b1a1dd7afd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayProperties.java @@ -372,6 +372,8 @@ public class FlywayProperties { */ private Boolean detectEncoding; + private final Postgresql postgresql = new Postgresql(); + public boolean isEnabled() { return this.enabled; } @@ -868,4 +870,29 @@ public class FlywayProperties { this.detectEncoding = detectEncoding; } + public Postgresql getPostgresql() { + return this.postgresql; + } + + /** + * {@code PostgreSQLConfigurationExtension} properties. + */ + public static class Postgresql { + + /** + * Whether transactional advisory locks should be used. If set to false, + * session-level locks are used instead. + */ + private Boolean transactionalLock; + + public Boolean getTransactionalLock() { + return this.transactionalLock; + } + + public void setTransactionalLock(Boolean transactionalLock) { + this.transactionalLock = transactionalLock; + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java index 62c03c62b6..52bf67ce14 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java @@ -33,6 +33,7 @@ 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.database.postgresql.PostgreSQLConfigurationExtension; import org.flywaydb.core.internal.license.FlywayTeamsUpgradeRequiredException; import org.flywaydb.database.oracle.OracleConfigurationExtension; import org.flywaydb.database.sqlserver.SQLServerConfigurationExtension; @@ -52,6 +53,7 @@ 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.flyway.FlywayAutoConfiguration.PostgresqlFlywayConfigurationCustomizer; import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.SqlServerFlywayConfigurationCustomizer; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; @@ -733,6 +735,24 @@ class FlywayAutoConfigurationTests { .run(validateFlywayTeamsPropertyOnly("outputQueryResults")); } + @Test + void postgresqlExtensionIsNotLoadedByDefault() { + FluentConfiguration configuration = mock(FluentConfiguration.class); + new PostgresqlFlywayConfigurationCustomizer(new FlywayProperties()).customize(configuration); + then(configuration).shouldHaveNoInteractions(); + } + + @Test + void postgresqlTransactionalLockIsCorrectlyMapped() { + this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) + .withPropertyValues("spring.flyway.postgresql.transactional-lock=false") + .run((context) -> assertThat(context.getBean(Flyway.class) + .getConfiguration() + .getPluginRegister() + .getPlugin(PostgreSQLConfigurationExtension.class) + .isTransactionalLock()).isFalse()); + } + @Test void sqlServerExtensionIsNotLoadedByDefault() { FluentConfiguration configuration = mock(FluentConfiguration.class); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayPropertiesTests.java index b6bca04ce2..d36ecc54cc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayPropertiesTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayPropertiesTests.java @@ -112,6 +112,8 @@ class FlywayPropertiesTests { // Property that moved to a separate Oracle plugin ignoreProperties(properties, "oracleSqlplus", "oracleSqlplusWarn", "oracleKerberosCacheFile", "oracleWalletLocation"); + // Postgresql extension + ignoreProperties(properties, "postgresql"); // Property that moved to a separate SQL plugin ignoreProperties(properties, "sqlServerKerberosLoginFile"); // High level object we can't set with properties