diff --git a/extensions/flyway/deployment/src/main/java/io/quarkus/flyway/FlywayCallbacksLocator.java b/extensions/flyway/deployment/src/main/java/io/quarkus/flyway/FlywayCallbacksLocator.java index b4e0f4fbc9cd5..8d90513e8de45 100644 --- a/extensions/flyway/deployment/src/main/java/io/quarkus/flyway/FlywayCallbacksLocator.java +++ b/extensions/flyway/deployment/src/main/java/io/quarkus/flyway/FlywayCallbacksLocator.java @@ -76,7 +76,7 @@ public Map> getCallbacks() */ private Collection callbacksForDataSource(String dataSourceName) throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException { - final Optional> callbackConfig = flywayBuildConfig.getConfigForDataSourceName(dataSourceName).callbacks(); + final Optional> callbackConfig = flywayBuildConfig.getConfigForDataSourceName(dataSourceName).callbacks; if (!callbackConfig.isPresent()) { return Collections.emptyList(); } diff --git a/extensions/flyway/deployment/src/main/java/io/quarkus/flyway/FlywayProcessor.java b/extensions/flyway/deployment/src/main/java/io/quarkus/flyway/FlywayProcessor.java index b107b878e2b19..ce3fa9db00e21 100644 --- a/extensions/flyway/deployment/src/main/java/io/quarkus/flyway/FlywayProcessor.java +++ b/extensions/flyway/deployment/src/main/java/io/quarkus/flyway/FlywayProcessor.java @@ -99,7 +99,7 @@ MigrationStateBuildItem build(BuildProducer featureProducer, Map> applicationMigrationsToDs = new HashMap<>(); for (var i : dataSourceNames) { Collection migrationLocations = discoverApplicationMigrations( - flywayBuildConfig.getConfigForDataSourceName(i).locations()); + flywayBuildConfig.getConfigForDataSourceName(i).locations); applicationMigrationsToDs.put(i, migrationLocations); } Set datasourcesWithMigrations = new HashSet<>(); diff --git a/extensions/flyway/runtime/pom.xml b/extensions/flyway/runtime/pom.xml index e49a44b3d13a7..c09e75f82456d 100644 --- a/extensions/flyway/runtime/pom.xml +++ b/extensions/flyway/runtime/pom.xml @@ -55,11 +55,6 @@ quarkus-junit5-internal test - - io.quarkus - quarkus-junit5-mockito - test - diff --git a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayBuildTimeConfig.java b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayBuildTimeConfig.java index 58ae166ac6531..47e7a4878c7f4 100644 --- a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayBuildTimeConfig.java +++ b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayBuildTimeConfig.java @@ -1,40 +1,35 @@ package io.quarkus.flyway.runtime; +import java.util.Collections; import java.util.Map; import io.quarkus.datasource.common.runtime.DataSourceUtil; +import io.quarkus.runtime.annotations.ConfigItem; import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; -import io.smallrye.config.ConfigMapping; -import io.smallrye.config.WithParentName; -@ConfigMapping(prefix = "quarkus.flyway") -@ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED) -public interface FlywayBuildTimeConfig { +@ConfigRoot(name = "flyway", phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED) +public final class FlywayBuildTimeConfig { /** * Gets the {@link FlywayDataSourceBuildTimeConfig} for the given datasource name. */ - default FlywayDataSourceBuildTimeConfig getConfigForDataSourceName(String dataSourceName) { + public FlywayDataSourceBuildTimeConfig getConfigForDataSourceName(String dataSourceName) { if (DataSourceUtil.isDefault(dataSourceName)) { - return defaultDataSource(); + return defaultDataSource; } - FlywayDataSourceBuildTimeConfig config = namedDataSources().get(dataSourceName); - if (config == null) { - config = defaultDataSource(); - } - return config; + return namedDataSources.getOrDefault(dataSourceName, FlywayDataSourceBuildTimeConfig.defaultConfig()); } /** * Flyway configuration for the default datasource. */ - @WithParentName - FlywayDataSourceBuildTimeConfig defaultDataSource(); + @ConfigItem(name = ConfigItem.PARENT) + public FlywayDataSourceBuildTimeConfig defaultDataSource; /** * Flyway configurations for named datasources. */ - @WithParentName - Map namedDataSources(); -} + @ConfigItem(name = ConfigItem.PARENT) + public Map namedDataSources = Collections.emptyMap(); +} \ No newline at end of file diff --git a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayContainerProducer.java b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayContainerProducer.java index 9149f5f4b22a7..d58bb692839ed 100644 --- a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayContainerProducer.java +++ b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayContainerProducer.java @@ -51,8 +51,8 @@ public FlywayContainer createFlyway(DataSource dataSource, String dataSourceName final Flyway flyway = new FlywayCreator(matchingRuntimeConfig, matchingBuildTimeConfig, matchingConfigCustomizers( configCustomizerInstances, dataSourceName)).withCallbacks(callbacks) .createFlyway(dataSource); - return new FlywayContainer(flyway, matchingRuntimeConfig.cleanAtStart(), matchingRuntimeConfig.migrateAtStart(), - matchingRuntimeConfig.repairAtStart(), matchingRuntimeConfig.validateAtStart(), + return new FlywayContainer(flyway, matchingRuntimeConfig.cleanAtStart, matchingRuntimeConfig.migrateAtStart, + matchingRuntimeConfig.repairAtStart, matchingRuntimeConfig.validateAtStart, dataSourceName, hasMigrations, createPossible); } diff --git a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayCreator.java b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayCreator.java index 863c4e895a445..844be7c8fb053 100644 --- a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayCreator.java +++ b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayCreator.java @@ -49,63 +49,63 @@ public FlywayCreator withCallbacks(Collection callbacks) { public Flyway createFlyway(DataSource dataSource) { FluentConfiguration configure = Flyway.configure(); - if (flywayRuntimeConfig.jdbcUrl().isPresent()) { - if (flywayRuntimeConfig.username().isPresent() && flywayRuntimeConfig.password().isPresent()) { - configure.dataSource(flywayRuntimeConfig.jdbcUrl().get(), flywayRuntimeConfig.username().get(), - flywayRuntimeConfig.password().get()); + if (flywayRuntimeConfig.jdbcUrl.isPresent()) { + if (flywayRuntimeConfig.username.isPresent() && flywayRuntimeConfig.password.isPresent()) { + configure.dataSource(flywayRuntimeConfig.jdbcUrl.get(), flywayRuntimeConfig.username.get(), + flywayRuntimeConfig.password.get()); } else { throw new ConfigurationException( "Username and password must be defined when a JDBC URL is provided in the Flyway configuration"); } } else { - if (flywayRuntimeConfig.username().isPresent() && flywayRuntimeConfig.password().isPresent()) { + if (flywayRuntimeConfig.username.isPresent() && flywayRuntimeConfig.password.isPresent()) { AgroalDataSource agroalDataSource = (AgroalDataSource) dataSource; String jdbcUrl = agroalDataSource.getConfiguration().connectionPoolConfiguration() .connectionFactoryConfiguration().jdbcUrl(); - configure.dataSource(jdbcUrl, flywayRuntimeConfig.username().get(), - flywayRuntimeConfig.password().get()); + configure.dataSource(jdbcUrl, flywayRuntimeConfig.username.get(), + flywayRuntimeConfig.password.get()); } else { configure.dataSource(dataSource); } } - if (flywayRuntimeConfig.initSql().isPresent()) { - configure.initSql(flywayRuntimeConfig.initSql().get()); + if (flywayRuntimeConfig.initSql.isPresent()) { + configure.initSql(flywayRuntimeConfig.initSql.get()); } - if (flywayRuntimeConfig.connectRetries().isPresent()) { - configure.connectRetries(flywayRuntimeConfig.connectRetries().getAsInt()); + if (flywayRuntimeConfig.connectRetries.isPresent()) { + configure.connectRetries(flywayRuntimeConfig.connectRetries.getAsInt()); } - if (flywayRuntimeConfig.defaultSchema().isPresent()) { - configure.defaultSchema(flywayRuntimeConfig.defaultSchema().get()); + if (flywayRuntimeConfig.defaultSchema.isPresent()) { + configure.defaultSchema(flywayRuntimeConfig.defaultSchema.get()); } - if (flywayRuntimeConfig.schemas().isPresent()) { - configure.schemas(flywayRuntimeConfig.schemas().get().toArray(EMPTY_ARRAY)); + if (flywayRuntimeConfig.schemas.isPresent()) { + configure.schemas(flywayRuntimeConfig.schemas.get().toArray(EMPTY_ARRAY)); } - if (flywayRuntimeConfig.table().isPresent()) { - configure.table(flywayRuntimeConfig.table().get()); + if (flywayRuntimeConfig.table.isPresent()) { + configure.table(flywayRuntimeConfig.table.get()); } - configure.locations(flywayBuildTimeConfig.locations().toArray(EMPTY_ARRAY)); - if (flywayRuntimeConfig.sqlMigrationPrefix().isPresent()) { - configure.sqlMigrationPrefix(flywayRuntimeConfig.sqlMigrationPrefix().get()); + configure.locations(flywayBuildTimeConfig.locations.toArray(EMPTY_ARRAY)); + if (flywayRuntimeConfig.sqlMigrationPrefix.isPresent()) { + configure.sqlMigrationPrefix(flywayRuntimeConfig.sqlMigrationPrefix.get()); } - if (flywayRuntimeConfig.repeatableSqlMigrationPrefix().isPresent()) { - configure.repeatableSqlMigrationPrefix(flywayRuntimeConfig.repeatableSqlMigrationPrefix().get()); + if (flywayRuntimeConfig.repeatableSqlMigrationPrefix.isPresent()) { + configure.repeatableSqlMigrationPrefix(flywayRuntimeConfig.repeatableSqlMigrationPrefix.get()); } - configure.cleanDisabled(flywayRuntimeConfig.cleanDisabled()); - configure.baselineOnMigrate(flywayRuntimeConfig.baselineOnMigrate()); - configure.validateOnMigrate(flywayRuntimeConfig.validateOnMigrate()); - configure.validateMigrationNaming(flywayRuntimeConfig.validateMigrationNaming()); + configure.cleanDisabled(flywayRuntimeConfig.cleanDisabled); + configure.baselineOnMigrate(flywayRuntimeConfig.baselineOnMigrate); + configure.validateOnMigrate(flywayRuntimeConfig.validateOnMigrate); + configure.validateMigrationNaming(flywayRuntimeConfig.validateMigrationNaming); final String[] ignoreMigrationPatterns; - if (flywayRuntimeConfig.ignoreMigrationPatterns().isPresent()) { - ignoreMigrationPatterns = flywayRuntimeConfig.ignoreMigrationPatterns().get(); + if (flywayRuntimeConfig.ignoreMigrationPatterns.isPresent()) { + ignoreMigrationPatterns = flywayRuntimeConfig.ignoreMigrationPatterns.get(); } else { List patterns = new ArrayList<>(2); - if (flywayRuntimeConfig.ignoreMissingMigrations()) { + if (flywayRuntimeConfig.ignoreMissingMigrations) { patterns.add("*:Missing"); } - if (flywayRuntimeConfig.ignoreFutureMigrations()) { + if (flywayRuntimeConfig.ignoreFutureMigrations) { patterns.add("*:Future"); } // Default is *:Future @@ -113,21 +113,21 @@ public Flyway createFlyway(DataSource dataSource) { } configure.ignoreMigrationPatterns(ignoreMigrationPatterns); - configure.cleanOnValidationError(flywayRuntimeConfig.cleanOnValidationError()); - configure.outOfOrder(flywayRuntimeConfig.outOfOrder()); - if (flywayRuntimeConfig.baselineVersion().isPresent()) { - configure.baselineVersion(flywayRuntimeConfig.baselineVersion().get()); + configure.cleanOnValidationError(flywayRuntimeConfig.cleanOnValidationError); + configure.outOfOrder(flywayRuntimeConfig.outOfOrder); + if (flywayRuntimeConfig.baselineVersion.isPresent()) { + configure.baselineVersion(flywayRuntimeConfig.baselineVersion.get()); } - if (flywayRuntimeConfig.baselineDescription().isPresent()) { - configure.baselineDescription(flywayRuntimeConfig.baselineDescription().get()); + if (flywayRuntimeConfig.baselineDescription.isPresent()) { + configure.baselineDescription(flywayRuntimeConfig.baselineDescription.get()); } - configure.placeholders(flywayRuntimeConfig.placeholders()); - configure.createSchemas(flywayRuntimeConfig.createSchemas()); - if (flywayRuntimeConfig.placeholderPrefix().isPresent()) { - configure.placeholderPrefix(flywayRuntimeConfig.placeholderPrefix().get()); + configure.placeholders(flywayRuntimeConfig.placeholders); + configure.createSchemas(flywayRuntimeConfig.createSchemas); + if (flywayRuntimeConfig.placeholderPrefix.isPresent()) { + configure.placeholderPrefix(flywayRuntimeConfig.placeholderPrefix.get()); } - if (flywayRuntimeConfig.placeholderSuffix().isPresent()) { - configure.placeholderSuffix(flywayRuntimeConfig.placeholderSuffix().get()); + if (flywayRuntimeConfig.placeholderSuffix.isPresent()) { + configure.placeholderSuffix(flywayRuntimeConfig.placeholderSuffix.get()); } if (!callbacks.isEmpty()) { configure.callbacks(callbacks.toArray(new Callback[0])); diff --git a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayDataSourceBuildTimeConfig.java b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayDataSourceBuildTimeConfig.java index fa6382cf513aa..7668f4ca191ea 100644 --- a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayDataSourceBuildTimeConfig.java +++ b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayDataSourceBuildTimeConfig.java @@ -1,17 +1,18 @@ package io.quarkus.flyway.runtime; +import java.util.Collections; import java.util.List; import java.util.Optional; import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; +import io.quarkus.runtime.annotations.ConvertWith; import io.quarkus.runtime.configuration.TrimmedStringConverter; -import io.smallrye.config.WithConverter; -import io.smallrye.config.WithDefault; @ConfigGroup -public interface FlywayDataSourceBuildTimeConfig { +public final class FlywayDataSourceBuildTimeConfig { - String DEFAULT_LOCATION = "db/migration"; + private static final String DEFAULT_LOCATION = "db/migration"; /** * Comma-separated list of locations to scan recursively for migrations. The location type is determined by its prefix. @@ -22,9 +23,9 @@ public interface FlywayDataSourceBuildTimeConfig { * Locations starting with filesystem: point to a directory on the filesystem, may only contain SQL migrations and are only * scanned recursively down non-hidden directories. */ - @WithDefault(DEFAULT_LOCATION) - @WithConverter(TrimmedStringConverter.class) - List locations(); + @ConfigItem(defaultValue = DEFAULT_LOCATION) + @ConvertWith(TrimmedStringConverter.class) + public List locations; /** * Comma-separated list of fully qualified class names of Callback implementations @@ -32,5 +33,17 @@ public interface FlywayDataSourceBuildTimeConfig { * The {@link org.flywaydb.core.api.callback.Callback} subclass must have a no-args constructor and must not be abstract. * These classes must also not have any fields that hold state (unless that state is initialized in the constructor). */ - Optional> callbacks(); + @ConfigItem + public Optional> callbacks = Optional.empty(); + + /** + * Creates a {@link FlywayDataSourceBuildTimeConfig} with default settings. + * + * @return {@link FlywayDataSourceBuildTimeConfig} + */ + public static FlywayDataSourceBuildTimeConfig defaultConfig() { + FlywayDataSourceBuildTimeConfig defaultConfig = new FlywayDataSourceBuildTimeConfig(); + defaultConfig.locations = Collections.singletonList(DEFAULT_LOCATION); + return defaultConfig; + } } diff --git a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayDataSourceRuntimeConfig.java b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayDataSourceRuntimeConfig.java index 625a13025ca34..5f63532ea1e2e 100644 --- a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayDataSourceRuntimeConfig.java +++ b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayDataSourceRuntimeConfig.java @@ -1,21 +1,32 @@ package io.quarkus.flyway.runtime; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.OptionalInt; import io.quarkus.runtime.annotations.ConfigGroup; -import io.smallrye.config.WithDefault; +import io.quarkus.runtime.annotations.ConfigItem; @ConfigGroup -public interface FlywayDataSourceRuntimeConfig { +public final class FlywayDataSourceRuntimeConfig { + + /** + * Creates a {@link FlywayDataSourceRuntimeConfig} with default settings. + * + * @return {@link FlywayDataSourceRuntimeConfig} + */ + public static FlywayDataSourceRuntimeConfig defaultConfig() { + return new FlywayDataSourceRuntimeConfig(); + } /** * The maximum number of retries when attempting to connect to the database. After each failed attempt, Flyway will wait 1 * second before attempting to connect again, up to the maximum number of times specified by connectRetries. */ - OptionalInt connectRetries(); + @ConfigItem + public OptionalInt connectRetries = OptionalInt.empty(); /** * Sets the default schema managed by Flyway. This schema name is case-sensitive. If not specified, but schemas @@ -29,32 +40,37 @@ public interface FlywayDataSourceRuntimeConfig { *
  • This schema will be the default for the database connection (provided the database supports this concept).
  • * */ - Optional defaultSchema(); + @ConfigItem + public Optional defaultSchema = Optional.empty(); /** * The JDBC URL that Flyway uses to connect to the database. * Falls back to the datasource URL if not specified. */ - Optional jdbcUrl(); + @ConfigItem + public Optional jdbcUrl = Optional.empty(); /** * The username that Flyway uses to connect to the database. * If no specific JDBC URL is configured, falls back to the datasource username if not specified. */ - Optional username(); + @ConfigItem + public Optional username = Optional.empty(); /** * The password that Flyway uses to connect to the database. * If no specific JDBC URL is configured, falls back to the datasource password if not specified. */ - Optional password(); + @ConfigItem + public Optional password = Optional.empty(); /** * Comma-separated case-sensitive list of schemas managed by Flyway. * The first schema in the list will be automatically set as the default one during the migration. * It will also be the one containing the schema history table. */ - Optional> schemas(); + @ConfigItem + public Optional> schemas = Optional.empty(); /** * The name of Flyway's schema history table. @@ -63,136 +79,149 @@ public interface FlywayDataSourceRuntimeConfig { * When the flyway.schemas property is set (multi-schema mode), the schema history table is placed in the first schema of * the list. */ - Optional table(); + @ConfigItem + public Optional table = Optional.empty(); /** * The file name prefix for versioned SQL migrations. - *

    + * * Versioned SQL migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix , which using * the defaults translates to V1.1__My_description.sql */ - Optional sqlMigrationPrefix(); + @ConfigItem + public Optional sqlMigrationPrefix = Optional.empty(); /** * The file name prefix for repeatable SQL migrations. - *

    + * * Repeatable SQL migrations have the following file name structure: prefixSeparatorDESCRIPTIONsuffix , which using the * defaults translates to R__My_description.sql */ - Optional repeatableSqlMigrationPrefix(); + @ConfigItem + public Optional repeatableSqlMigrationPrefix = Optional.empty(); /** * true to execute Flyway clean command automatically when the application starts, false otherwise. + * */ - @WithDefault("false") - boolean cleanAtStart(); + @ConfigItem + public boolean cleanAtStart; /** * true to prevent Flyway clean operations, false otherwise. */ - @WithDefault("false") - boolean cleanDisabled(); + @ConfigItem + public boolean cleanDisabled; /** * true to automatically call clean when a validation error occurs, false otherwise. */ - @WithDefault("false") - boolean cleanOnValidationError(); + @ConfigItem + public boolean cleanOnValidationError; /** * true to execute Flyway automatically when the application starts, false otherwise. + * */ - @WithDefault("false") - boolean migrateAtStart(); + @ConfigItem + public boolean migrateAtStart; /** * true to execute a Flyway repair command when the application starts, false otherwise. + * */ - @WithDefault("false") - boolean repairAtStart(); + @ConfigItem + public boolean repairAtStart; /** * true to execute a Flyway validate command when the application starts, false otherwise. + * */ - @WithDefault("false") - boolean validateAtStart(); + @ConfigItem + public boolean validateAtStart; /** * Enable the creation of the history table if it does not exist already. */ - @WithDefault("false") - boolean baselineOnMigrate(); + @ConfigItem + public boolean baselineOnMigrate; /** * The initial baseline version. */ - Optional baselineVersion(); + @ConfigItem + public Optional baselineVersion = Optional.empty(); /** * The description to tag an existing schema with when executing baseline. */ - Optional baselineDescription(); + @ConfigItem + public Optional baselineDescription = Optional.empty(); /** * Whether to automatically call validate when performing a migration. */ - @WithDefault("true") - boolean validateOnMigrate(); + @ConfigItem(defaultValue = "true") + public boolean validateOnMigrate = true; /** * Allows migrations to be run "out of order". */ - @WithDefault("false") - boolean outOfOrder(); + @ConfigItem + public boolean outOfOrder; /** * Ignore missing migrations when reading the history table. When set to true migrations from older versions present in the * history table but absent in the configured locations will be ignored (and logged as a warning), when false (the default) * the validation step will fail. */ - @WithDefault("false") - boolean ignoreMissingMigrations(); + @ConfigItem + public boolean ignoreMissingMigrations; /** * Ignore future migrations when reading the history table. When set to true migrations from newer versions present in the * history table but absent in the configured locations will be ignored (and logged as a warning), when false (the default) * the validation step will fail. */ - @WithDefault("false") - boolean ignoreFutureMigrations(); + @ConfigItem + public boolean ignoreFutureMigrations; /** * Sets the placeholders to replace in SQL migration scripts. */ - Map placeholders(); + @ConfigItem + public Map placeholders = Collections.emptyMap(); /** * Whether Flyway should attempt to create the schemas specified in the schemas property */ - @WithDefault("true") - boolean createSchemas(); + @ConfigItem(defaultValue = "true") + public boolean createSchemas; /** * Prefix of every placeholder (default: ${ ) */ - Optional placeholderPrefix(); + @ConfigItem + public Optional placeholderPrefix = Optional.empty(); /** * Suffix of every placeholder (default: } ) */ - Optional placeholderSuffix(); + @ConfigItem + public Optional placeholderSuffix = Optional.empty(); /** * The SQL statements to run to initialize a new database connection immediately after opening it. */ - Optional initSql(); + @ConfigItem + public Optional initSql = Optional.empty(); /** * Whether to validate migrations and callbacks whose scripts do not obey the correct naming convention. A failure can be * useful to check that errors such as case sensitivity in migration prefixes have been corrected. */ - @WithDefault("false") - boolean validateMigrationNaming(); + @ConfigItem + public boolean validateMigrationNaming; /** * Ignore migrations during validate and repair according to a given list of patterns (see @@ -200,5 +229,6 @@ public interface FlywayDataSourceRuntimeConfig { * When this configuration is set, the ignoreFutureMigrations and ignoreMissingMigrations settings are ignored. Patterns are * comma separated. */ - Optional ignoreMigrationPatterns(); + @ConfigItem + public Optional ignoreMigrationPatterns = Optional.empty(); } diff --git a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayRecorder.java b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayRecorder.java index 36ded39d7b507..94c7919fe4615 100644 --- a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayRecorder.java +++ b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayRecorder.java @@ -76,7 +76,7 @@ public Flyway get() { } public void doStartActions() { - if (!config.getValue().enabled()) { + if (!config.getValue().enabled) { return; } for (FlywayContainer flywayContainer : FLYWAY_CONTAINERS) { diff --git a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayRuntimeConfig.java b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayRuntimeConfig.java index 13efcd42e082a..481ee6e821539 100644 --- a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayRuntimeConfig.java +++ b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayRuntimeConfig.java @@ -1,48 +1,42 @@ package io.quarkus.flyway.runtime; +import java.util.Collections; import java.util.Map; import io.quarkus.datasource.common.runtime.DataSourceUtil; +import io.quarkus.runtime.annotations.ConfigItem; import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; -import io.smallrye.config.ConfigMapping; -import io.smallrye.config.WithDefault; -import io.smallrye.config.WithParentName; -@ConfigMapping(prefix = "quarkus.flyway") -@ConfigRoot(phase = ConfigPhase.RUN_TIME) -public interface FlywayRuntimeConfig { +@ConfigRoot(name = "flyway", phase = ConfigPhase.RUN_TIME) +public final class FlywayRuntimeConfig { /** * Gets the {@link FlywayDataSourceRuntimeConfig} for the given datasource name. */ - default FlywayDataSourceRuntimeConfig getConfigForDataSourceName(String dataSourceName) { + public FlywayDataSourceRuntimeConfig getConfigForDataSourceName(String dataSourceName) { if (DataSourceUtil.isDefault(dataSourceName)) { - return defaultDataSource(); + return defaultDataSource; } - FlywayDataSourceRuntimeConfig config = namedDataSources().get(dataSourceName); - if (config == null) { - config = defaultDataSource(); - } - return config; + return namedDataSources.getOrDefault(dataSourceName, FlywayDataSourceRuntimeConfig.defaultConfig()); } /** * Flag to enable / disable Flyway. * */ - @WithDefault("true") - boolean enabled(); + @ConfigItem(defaultValue = "true") + public boolean enabled; /** * Flyway configuration for the default datasource. */ - @WithParentName - FlywayDataSourceRuntimeConfig defaultDataSource(); + @ConfigItem(name = ConfigItem.PARENT) + public FlywayDataSourceRuntimeConfig defaultDataSource = FlywayDataSourceRuntimeConfig.defaultConfig(); /** * Flyway configurations for named datasources. */ - @WithParentName - Map namedDataSources(); + @ConfigItem(name = ConfigItem.PARENT) + public Map namedDataSources = Collections.emptyMap(); } diff --git a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/devconsole/FlywayDevConsoleRecorder.java b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/devconsole/FlywayDevConsoleRecorder.java index fff138b184cd8..ef51023a14c12 100644 --- a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/devconsole/FlywayDevConsoleRecorder.java +++ b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/devconsole/FlywayDevConsoleRecorder.java @@ -76,7 +76,7 @@ protected void handlePostAsync(RoutingContext event, MultiMap form) throws Excep return; } FlywayDataSourceBuildTimeConfig config = buildTimeConfig.getConfigForDataSourceName(name); - if (config.locations().isEmpty()) { + if (config.locations.isEmpty()) { flashMessage(event, "Datasource has no locations configured"); return; } @@ -90,7 +90,7 @@ protected void handlePostAsync(RoutingContext event, MultiMap form) throws Excep // In the current project only Path path = resourcesDir.get(0); - Path migrationDir = path.resolve(config.locations().get(0)); + Path migrationDir = path.resolve(config.locations.get(0)); Files.createDirectories(migrationDir); Path file = migrationDir.resolve( "V1.0.0__" + artifactId + ".sql"); diff --git a/extensions/flyway/runtime/src/test/java/io/quarkus/flyway/runtime/FlywayCreatorTest.java b/extensions/flyway/runtime/src/test/java/io/quarkus/flyway/runtime/FlywayCreatorTest.java index 48e818499b472..17764887791ed 100644 --- a/extensions/flyway/runtime/src/test/java/io/quarkus/flyway/runtime/FlywayCreatorTest.java +++ b/extensions/flyway/runtime/src/test/java/io/quarkus/flyway/runtime/FlywayCreatorTest.java @@ -18,41 +18,23 @@ import org.flywaydb.core.api.configuration.Configuration; import org.flywaydb.core.api.pattern.ValidatePattern; import org.flywaydb.core.internal.util.ValidatePatternUtils; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.Mockito; - -import io.smallrye.config.SmallRyeConfig; -import io.smallrye.config.SmallRyeConfigBuilder; class FlywayCreatorTest { - private FlywayDataSourceRuntimeConfig runtimeConfig; - private FlywayDataSourceBuildTimeConfig buildConfig; - private final Configuration defaultConfig = Flyway.configure().load().getConfiguration(); + private FlywayDataSourceRuntimeConfig runtimeConfig = FlywayDataSourceRuntimeConfig.defaultConfig(); + private FlywayDataSourceBuildTimeConfig buildConfig = FlywayDataSourceBuildTimeConfig.defaultConfig(); + private Configuration defaultConfig = Flyway.configure().load().getConfiguration(); /** * class under test. */ private FlywayCreator creator; - @BeforeEach - void mockConfig() { - SmallRyeConfig config = new SmallRyeConfigBuilder().addDiscoveredSources().addDefaultSources().addDiscoveredConverters() - .withMapping(FlywayRuntimeConfig.class, "quarkus.flyway") - .withMapping(FlywayBuildTimeConfig.class, "quarkus.flyway") - .build(); - - FlywayRuntimeConfig flywayRuntimeConfig = config.getConfigMapping(FlywayRuntimeConfig.class); - FlywayBuildTimeConfig flywayBuildTimeConfig = config.getConfigMapping(FlywayBuildTimeConfig.class); - this.runtimeConfig = Mockito.spy(flywayRuntimeConfig.defaultDataSource()); - this.buildConfig = Mockito.spy(flywayBuildTimeConfig.defaultDataSource()); - } - @Test @DisplayName("locations default matches flyway default") void testLocationsDefault() { @@ -63,9 +45,9 @@ void testLocationsDefault() { @Test @DisplayName("locations carried over from configuration") void testLocationsOverridden() { - Mockito.when(buildConfig.locations()).thenReturn(Arrays.asList("db/migrations", "db/something")); + buildConfig.locations = Arrays.asList("db/migrations", "db/something"); creator = new FlywayCreator(runtimeConfig, buildConfig); - assertEquals(buildConfig.locations(), pathList(createdFlywayConfig().getLocations())); + assertEquals(buildConfig.locations, pathList(createdFlywayConfig().getLocations())); } @Test @@ -85,9 +67,9 @@ void testBaselineDescriptionDefault() { @Test @DisplayName("baseline description carried over from configuration") void testBaselineDescriptionOverridden() { - Mockito.when(runtimeConfig.baselineDescription()).thenReturn(Optional.of("baselineDescription")); + runtimeConfig.baselineDescription = Optional.of("baselineDescription"); creator = new FlywayCreator(runtimeConfig, buildConfig); - assertEquals(runtimeConfig.baselineDescription().get(), createdFlywayConfig().getBaselineDescription()); + assertEquals(runtimeConfig.baselineDescription.get(), createdFlywayConfig().getBaselineDescription()); } @Test @@ -100,9 +82,9 @@ void testBaselineVersionDefault() { @Test @DisplayName("baseline version carried over from configuration") void testBaselineVersionOverridden() { - Mockito.when(runtimeConfig.baselineVersion()).thenReturn(Optional.of("0.1.2")); + runtimeConfig.baselineVersion = Optional.of("0.1.2"); creator = new FlywayCreator(runtimeConfig, buildConfig); - assertEquals(runtimeConfig.baselineVersion().get(), createdFlywayConfig().getBaselineVersion().getVersion()); + assertEquals(runtimeConfig.baselineVersion.get(), createdFlywayConfig().getBaselineVersion().getVersion()); } @Test @@ -115,9 +97,9 @@ void testConnectionRetriesDefault() { @Test @DisplayName("connection retries carried over from configuration") void testConnectionRetriesOverridden() { - Mockito.when(runtimeConfig.connectRetries()).thenReturn(OptionalInt.of(12)); + runtimeConfig.connectRetries = OptionalInt.of(12); creator = new FlywayCreator(runtimeConfig, buildConfig); - assertEquals(runtimeConfig.connectRetries().getAsInt(), createdFlywayConfig().getConnectRetries()); + assertEquals(runtimeConfig.connectRetries.getAsInt(), createdFlywayConfig().getConnectRetries()); } @Test @@ -130,10 +112,9 @@ void testRepeatableSqlMigrationPrefixDefault() { @Test @DisplayName("repeatable SQL migration prefix carried over from configuration") void testRepeatableSqlMigrationPrefixOverridden() { - Mockito.when(runtimeConfig.repeatableSqlMigrationPrefix()).thenReturn(Optional.of("A")); + runtimeConfig.repeatableSqlMigrationPrefix = Optional.of("A"); creator = new FlywayCreator(runtimeConfig, buildConfig); - assertEquals(runtimeConfig.repeatableSqlMigrationPrefix().get(), - createdFlywayConfig().getRepeatableSqlMigrationPrefix()); + assertEquals(runtimeConfig.repeatableSqlMigrationPrefix.get(), createdFlywayConfig().getRepeatableSqlMigrationPrefix()); } @Test @@ -146,9 +127,9 @@ void testSchemasDefault() { @Test @DisplayName("schemas carried over from configuration") void testSchemasOverridden() { - Mockito.when(runtimeConfig.schemas()).thenReturn(Optional.of(asList("TEST_SCHEMA_1", "TEST_SCHEMA_2"))); + runtimeConfig.schemas = Optional.of(Arrays.asList("TEST_SCHEMA_1", "TEST_SCHEMA_2")); creator = new FlywayCreator(runtimeConfig, buildConfig); - assertEquals(runtimeConfig.schemas().get(), asList(createdFlywayConfig().getSchemas())); + assertEquals(runtimeConfig.schemas.get(), asList(createdFlywayConfig().getSchemas())); } @Test @@ -161,9 +142,9 @@ void testSqlMigrationPrefixDefault() { @Test @DisplayName("SQL migration prefix carried over from configuration") void testSqlMigrationPrefixOverridden() { - Mockito.when(runtimeConfig.sqlMigrationPrefix()).thenReturn(Optional.of("A")); + runtimeConfig.sqlMigrationPrefix = Optional.of("M"); creator = new FlywayCreator(runtimeConfig, buildConfig); - assertEquals(runtimeConfig.sqlMigrationPrefix().get(), createdFlywayConfig().getSqlMigrationPrefix()); + assertEquals(runtimeConfig.sqlMigrationPrefix.get(), createdFlywayConfig().getSqlMigrationPrefix()); } @Test @@ -176,31 +157,31 @@ void testTableDefault() { @Test @DisplayName("table carried over from configuration") void testTableOverridden() { - Mockito.when(runtimeConfig.table()).thenReturn(Optional.of("flyway_history_test_table")); + runtimeConfig.table = Optional.of("flyway_history_test_table"); creator = new FlywayCreator(runtimeConfig, buildConfig); - assertEquals(runtimeConfig.table().get(), createdFlywayConfig().getTable()); + assertEquals(runtimeConfig.table.get(), createdFlywayConfig().getTable()); } @Test @DisplayName("validate on migrate default matches to true") void testValidateOnMigrate() { creator = new FlywayCreator(runtimeConfig, buildConfig); - assertEquals(runtimeConfig.validateOnMigrate(), createdFlywayConfig().isValidateOnMigrate()); - assertTrue(runtimeConfig.validateOnMigrate()); + assertEquals(runtimeConfig.validateOnMigrate, createdFlywayConfig().isValidateOnMigrate()); + assertTrue(runtimeConfig.validateOnMigrate); } @Test @DisplayName("clean disabled default matches to false") void testCleanDisabled() { creator = new FlywayCreator(runtimeConfig, buildConfig); - assertEquals(runtimeConfig.cleanDisabled(), createdFlywayConfig().isCleanDisabled()); - assertFalse(runtimeConfig.cleanDisabled()); + assertEquals(runtimeConfig.cleanDisabled, createdFlywayConfig().isCleanDisabled()); + assertFalse(runtimeConfig.cleanDisabled); - Mockito.when(runtimeConfig.cleanDisabled()).thenReturn(false); + runtimeConfig.cleanDisabled = false; creator = new FlywayCreator(runtimeConfig, buildConfig); assertFalse(createdFlywayConfig().isCleanDisabled()); - Mockito.when(runtimeConfig.cleanDisabled()).thenReturn(true); + runtimeConfig.cleanDisabled = true; creator = new FlywayCreator(runtimeConfig, buildConfig); assertTrue(createdFlywayConfig().isCleanDisabled()); } @@ -208,11 +189,11 @@ void testCleanDisabled() { @Test @DisplayName("outOfOrder is correctly set") void testOutOfOrder() { - Mockito.when(runtimeConfig.outOfOrder()).thenReturn(false); + runtimeConfig.outOfOrder = false; creator = new FlywayCreator(runtimeConfig, buildConfig); assertFalse(createdFlywayConfig().isOutOfOrder()); - Mockito.when(runtimeConfig.outOfOrder()).thenReturn(true); + runtimeConfig.outOfOrder = true; creator = new FlywayCreator(runtimeConfig, buildConfig); assertTrue(createdFlywayConfig().isOutOfOrder()); } @@ -220,11 +201,11 @@ void testOutOfOrder() { @Test @DisplayName("ignoreMissingMigrations is correctly set") void testIgnoreMissingMigrations() { - Mockito.when(runtimeConfig.ignoreMissingMigrations()).thenReturn(false); + runtimeConfig.ignoreMissingMigrations = false; creator = new FlywayCreator(runtimeConfig, buildConfig); assertFalse(ValidatePatternUtils.isMissingIgnored(createdFlywayConfig().getIgnoreMigrationPatterns())); - Mockito.when(runtimeConfig.ignoreMissingMigrations()).thenReturn(true); + runtimeConfig.ignoreMissingMigrations = true; creator = new FlywayCreator(runtimeConfig, buildConfig); assertTrue(ValidatePatternUtils.isMissingIgnored(createdFlywayConfig().getIgnoreMigrationPatterns())); } @@ -232,11 +213,11 @@ void testIgnoreMissingMigrations() { @Test @DisplayName("ignoreFutureMigrations is correctly set") void testIgnoreFutureMigrations() { - Mockito.when(runtimeConfig.ignoreFutureMigrations()).thenReturn(false); + runtimeConfig.ignoreFutureMigrations = false; creator = new FlywayCreator(runtimeConfig, buildConfig); assertFalse(ValidatePatternUtils.isFutureIgnored(createdFlywayConfig().getIgnoreMigrationPatterns())); - Mockito.when(runtimeConfig.ignoreFutureMigrations()).thenReturn(true); + runtimeConfig.ignoreFutureMigrations = true; creator = new FlywayCreator(runtimeConfig, buildConfig); assertTrue(ValidatePatternUtils.isFutureIgnored(createdFlywayConfig().getIgnoreMigrationPatterns())); } @@ -245,14 +226,14 @@ void testIgnoreFutureMigrations() { @DisplayName("cleanOnValidationError defaults to false and is correctly set") void testCleanOnValidationError() { creator = new FlywayCreator(runtimeConfig, buildConfig); - assertEquals(runtimeConfig.cleanOnValidationError(), createdFlywayConfig().isCleanOnValidationError()); - assertFalse(runtimeConfig.cleanOnValidationError()); + assertEquals(runtimeConfig.cleanOnValidationError, createdFlywayConfig().isCleanOnValidationError()); + assertFalse(runtimeConfig.cleanOnValidationError); - Mockito.when(runtimeConfig.cleanOnValidationError()).thenReturn(false); + runtimeConfig.cleanOnValidationError = false; creator = new FlywayCreator(runtimeConfig, buildConfig); assertFalse(createdFlywayConfig().isCleanOnValidationError()); - Mockito.when(runtimeConfig.cleanOnValidationError()).thenReturn(true); + runtimeConfig.cleanOnValidationError = true; creator = new FlywayCreator(runtimeConfig, buildConfig); assertTrue(createdFlywayConfig().isCleanOnValidationError()); } @@ -261,20 +242,20 @@ void testCleanOnValidationError() { @MethodSource("validateOnMigrateOverwritten") @DisplayName("validate on migrate overwritten in configuration") void testValidateOnMigrateOverwritten(final boolean input, final boolean expected) { - Mockito.when(runtimeConfig.validateOnMigrate()).thenReturn(input); + runtimeConfig.validateOnMigrate = input; creator = new FlywayCreator(runtimeConfig, buildConfig); assertEquals(createdFlywayConfig().isValidateOnMigrate(), expected); - assertEquals(runtimeConfig.validateOnMigrate(), expected); + assertEquals(runtimeConfig.validateOnMigrate, expected); } @Test @DisplayName("validateMigrationNaming defaults to false and it is correctly set") void testValidateMigrationNaming() { creator = new FlywayCreator(runtimeConfig, buildConfig); - assertEquals(runtimeConfig.validateMigrationNaming(), createdFlywayConfig().isValidateMigrationNaming()); - assertFalse(runtimeConfig.validateMigrationNaming()); + assertEquals(runtimeConfig.validateMigrationNaming, createdFlywayConfig().isValidateMigrationNaming()); + assertFalse(runtimeConfig.validateMigrationNaming); - Mockito.when(runtimeConfig.validateMigrationNaming()).thenReturn(true); + runtimeConfig.validateMigrationNaming = true; creator = new FlywayCreator(runtimeConfig, buildConfig); assertTrue(createdFlywayConfig().isValidateMigrationNaming()); } @@ -284,13 +265,13 @@ void testValidateMigrationNaming() { void testIgnoreMigrationPatterns() { creator = new FlywayCreator(runtimeConfig, buildConfig); assertEquals(0, createdFlywayConfig().getIgnoreMigrationPatterns().length); - assertFalse(runtimeConfig.ignoreMigrationPatterns().isPresent()); + assertFalse(runtimeConfig.ignoreMigrationPatterns.isPresent()); - Mockito.when(runtimeConfig.ignoreMigrationPatterns()).thenReturn(Optional.of(new String[] { "*:missing" })); + runtimeConfig.ignoreMigrationPatterns = Optional.of(new String[] { "*:missing" }); creator = new FlywayCreator(runtimeConfig, buildConfig); final ValidatePattern[] existingIgnoreMigrationPatterns = createdFlywayConfig().getIgnoreMigrationPatterns(); assertEquals(1, existingIgnoreMigrationPatterns.length); - final String[] ignoreMigrationPatterns = runtimeConfig.ignoreMigrationPatterns().get(); + final String[] ignoreMigrationPatterns = runtimeConfig.ignoreMigrationPatterns.get(); final ValidatePattern[] validatePatterns = Arrays.stream(ignoreMigrationPatterns) .map(ValidatePattern::fromPattern).toArray(ValidatePattern[]::new); assertArrayEquals(validatePatterns, existingIgnoreMigrationPatterns);