From ea8e0cfc48c55095d6ccaacbcd41e45d5eacd09f Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 21 Jan 2016 10:26:12 +0100 Subject: [PATCH] Support for simple numeric Flyway version While Flyway's `MigrationVersion` is a String value, a simple "0" is also a valid number. When such value is not wrapped in YAML, an integer is injected rather than a String which leads to a failure as we can't convert it. This commit updates the `StringToMigrationVersionConverter` to also supports conversion from a Number. This is a convenience for users using YAML for configuration Closes gh-4981 --- .../flyway/FlywayAutoConfiguration.java | 39 ++++++++++++++----- .../flyway/FlywayAutoConfigurationTests.java | 18 ++++++++- 2 files changed, 46 insertions(+), 11 deletions(-) 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 ba248e1c26..a91177d931 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,15 @@ package org.springframework.boot.autoconfigure.flyway; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + import javax.annotation.PostConstruct; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; +import org.apache.commons.lang.ObjectUtils; import org.flywaydb.core.Flyway; import org.flywaydb.core.api.MigrationVersion; @@ -38,7 +43,8 @@ import org.springframework.boot.context.properties.ConfigurationPropertiesBindin import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.ResourceLoader; import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean; @@ -63,8 +69,8 @@ public class FlywayAutoConfiguration { @Bean @ConfigurationPropertiesBinding - public StringToMigrationVersionConverter stringToMigrationVersionConverter() { - return new StringToMigrationVersionConverter(); + public StringOrNumberToMigrationVersionConverter stringOrNumberMigrationVersionConverter() { + return new StringOrNumberToMigrationVersionConverter(); } @Configuration @@ -169,14 +175,29 @@ public class FlywayAutoConfiguration { } /** - * Convert a String to a {@link MigrationVersion}. + * Convert a String or Number to a {@link MigrationVersion}. */ - private static class StringToMigrationVersionConverter - implements Converter { + private static class StringOrNumberToMigrationVersionConverter + implements GenericConverter { + + private static final Set CONVERTIBLE_PAIRS = createConvertiblePairs(); @Override - public MigrationVersion convert(String source) { - return MigrationVersion.fromVersion(source); + public Set getConvertibleTypes() { + return CONVERTIBLE_PAIRS; + } + + @Override + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + String value = ObjectUtils.toString(source); + return MigrationVersion.fromVersion(value); + } + + private static Set createConvertiblePairs() { + Set convertiblePairs = new HashSet(2); + convertiblePairs.add(new ConvertiblePair(String.class, MigrationVersion.class)); + convertiblePairs.add(new ConvertiblePair(Number.class, MigrationVersion.class)); + return Collections.unmodifiableSet(convertiblePairs); } } 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 c35491e9cb..86d5befcb1 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.springframework.boot.autoconfigure.flyway; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -42,6 +43,7 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; +import org.springframework.core.env.MapPropertySource; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.stereotype.Component; @@ -198,7 +200,7 @@ public class FlywayAutoConfigurationTests { } @Test - public void overrideBaselineVersion() throws Exception { + public void overrideBaselineVersionString() throws Exception { EnvironmentTestUtils.addEnvironment(this.context, "flyway.baseline-version=0"); registerAndRefresh(EmbeddedDataSourceConfiguration.class, FlywayAutoConfiguration.class, @@ -208,6 +210,18 @@ public class FlywayAutoConfigurationTests { equalTo(MigrationVersion.fromVersion("0"))); } + @Test + public void overrideBaselineVersionNumber() throws Exception { + Map source = Collections.singletonMap("flyway.baseline-version", 1); + this.context.getEnvironment().getPropertySources().addLast(new MapPropertySource("flyway", source)); + registerAndRefresh(EmbeddedDataSourceConfiguration.class, + FlywayAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + Flyway flyway = this.context.getBean(Flyway.class); + assertThat(flyway.getBaselineVersion(), + equalTo(MigrationVersion.fromVersion("1"))); + } + private void registerAndRefresh(Class... annotatedClasses) { this.context.register(annotatedClasses); this.context.refresh();