diff --git a/flyway/src/main/java/io/micronaut/flyway/ValidatePatternTypeConverter.java b/flyway/src/main/java/io/micronaut/flyway/ValidatePatternTypeConverter.java new file mode 100644 index 00000000..22fb05ba --- /dev/null +++ b/flyway/src/main/java/io/micronaut/flyway/ValidatePatternTypeConverter.java @@ -0,0 +1,44 @@ +/* + * Copyright 2017-2022 original 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 io.micronaut.flyway; + +import io.micronaut.core.convert.ConversionContext; +import io.micronaut.core.convert.TypeConverter; +import jakarta.inject.Singleton; +import org.flywaydb.core.api.pattern.ValidatePattern; + +import java.util.Optional; + +/** + * Converts String's to Flyway ValidatePattern required for reading ignore-migration-patterns parameter. + * + * @author Nenad Vico + * @see org.flywaydb.core.api.pattern.ValidatePattern + * @since 5.4.1 + */ +@Singleton +public class ValidatePatternTypeConverter implements TypeConverter { + + @Override + public Optional convert(String pattern, + Class targetType, + ConversionContext context) { + if (pattern == null || pattern.trim().length() == 0) { + return Optional.empty(); + } + return Optional.of(ValidatePattern.fromPattern(pattern)); + } +} diff --git a/flyway/src/test/groovy/io/micronaut/flyway/FlywayConfigurationPropertiesEnabledSpec.groovy b/flyway/src/test/groovy/io/micronaut/flyway/FlywayConfigurationPropertiesEnabledSpec.groovy index 7e7efd42..524b5a95 100644 --- a/flyway/src/test/groovy/io/micronaut/flyway/FlywayConfigurationPropertiesEnabledSpec.groovy +++ b/flyway/src/test/groovy/io/micronaut/flyway/FlywayConfigurationPropertiesEnabledSpec.groovy @@ -3,6 +3,8 @@ package io.micronaut.flyway import io.micronaut.context.exceptions.NoSuchBeanException import io.micronaut.inject.qualifiers.Qualifiers import org.flywaydb.core.Flyway +import org.flywaydb.core.api.MigrationState +import org.flywaydb.core.api.pattern.ValidatePattern import javax.sql.DataSource @@ -59,6 +61,32 @@ class FlywayConfigurationPropertiesEnabledSpec extends AbstractFlywaySpec { noExceptionThrown() } + void 'if flyway configuration then ValidatePatternTypeConverter and Flyway beans are created'() { + given: + run('spec.name' : FlywayConfigurationPropertiesEnabledSpec.simpleName, + 'flyway.datasources.movies.enabled' : true, + 'flyway.datasources.movies.ignore-migration-patterns' : "*:missing", + 'datasources.movies.url' : 'jdbc:h2:mem:flyway2Db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE', + 'datasources.movies.username' : DS_USERNAME, + 'datasources.movies.password' : DS_PASSWORD, + 'datasources.movies.driverClassName': DS_DRIVER) + + when: + applicationContext.getBean(DataSource, Qualifiers.byName('movies')) + def configuration = applicationContext.getBean(FlywayConfigurationProperties, Qualifiers.byName('movies')) + applicationContext.getBean(Flyway, Qualifiers.byName('movies')) + + then: + noExceptionThrown() + + and: + configuration.fluentConfiguration.ignoreMigrationPatterns.length == 1 + configuration.fluentConfiguration.ignoreMigrationPatterns[0].matchesMigration(false, MigrationState.MISSING_SUCCESS) + + expect: + applicationContext.getConversionService().canConvert(String.class, ValidatePattern.class) + } + void 'if flyway is disabled, then FlywayConfigurationProperties bean is created but Flyway bean is not'() { given: run('spec.name' : FlywayConfigurationPropertiesEnabledSpec.simpleName, diff --git a/flyway/src/test/groovy/io/micronaut/flyway/ValidatePatternTypeConverterSpec.groovy b/flyway/src/test/groovy/io/micronaut/flyway/ValidatePatternTypeConverterSpec.groovy new file mode 100644 index 00000000..c7b9cf4c --- /dev/null +++ b/flyway/src/test/groovy/io/micronaut/flyway/ValidatePatternTypeConverterSpec.groovy @@ -0,0 +1,83 @@ +package io.micronaut.flyway + +import org.flywaydb.core.api.ErrorCode +import org.flywaydb.core.api.FlywayException +import org.flywaydb.core.api.MigrationState +import org.flywaydb.core.api.pattern.ValidatePattern +import org.flywaydb.core.internal.license.FlywayTeamsUpgradeRequiredException +import spock.lang.Specification + +/** + * @author Nenad Vico + */ +class ValidatePatternTypeConverterSpec extends Specification { + + + void "test empty string conversion"() { + given: + ValidatePatternTypeConverter validatePatternTypeConverter = new ValidatePatternTypeConverter() + + expect: + !validatePatternTypeConverter.convert("", ValidatePattern.class).isPresent() + } + + void "test wrong string conversion"() { + given: + ValidatePatternTypeConverter validatePatternTypeConverter = new ValidatePatternTypeConverter() + + when: + validatePatternTypeConverter.convert("junk", ValidatePattern.class) + + then: + def e = thrown(FlywayException) + e.errorCode == ErrorCode.ERROR + e.message == 'Invalid pattern \'junk\'. Pattern must be of the form : See https://rd.gt/37m4hXD for full details' + } + + void "test future string conversion"() { + given: + ValidatePatternTypeConverter validatePatternTypeConverter = new ValidatePatternTypeConverter() + + expect: + validatePatternTypeConverter.convert("*:future", ValidatePattern.class).get() + .matchesMigration(false, MigrationState.FUTURE_SUCCESS) + } + + void "test repeatable string conversion"() { + given: + ValidatePatternTypeConverter validatePatternTypeConverter = new ValidatePatternTypeConverter() + + when: + validatePatternTypeConverter.convert("repeatable:*", ValidatePattern.class) + + then: + def e = thrown(FlywayTeamsUpgradeRequiredException) + e.errorCode == ErrorCode.ERROR + e.message == 'Flyway Teams Edition upgrade required: ignoreMigrationPattern with type \'repeatable\' is not supported by Flyway Community Edition\n' + + 'Try Flyway Teams Edition for free: https://rd.gt/2VzHpkY' + } + + void "test versioned string conversion"() { + given: + ValidatePatternTypeConverter validatePatternTypeConverter = new ValidatePatternTypeConverter() + + when: + validatePatternTypeConverter.convert("versioned:missing", ValidatePattern.class) + + then: + def e = thrown(FlywayTeamsUpgradeRequiredException) + e.errorCode == ErrorCode.ERROR + e.message == 'Flyway Teams Edition upgrade required: ignoreMigrationPattern with type \'versioned\' is not supported by Flyway Community Edition\n' + + 'Try Flyway Teams Edition for free: https://rd.gt/2VzHpkY' + } + + void "test missing string conversion"() { + given: + ValidatePatternTypeConverter validatePatternTypeConverter = new ValidatePatternTypeConverter() + + expect: + validatePatternTypeConverter.convert("*:missing", ValidatePattern.class).get() + .matchesMigration(false, MigrationState.MISSING_SUCCESS) + } + +}