Transparently handle migration from number to java.util.Duration

See gh-11794
pull/11825/merge
Stephane Nicoll 7 years ago
parent d7c20be3e7
commit 43e5e83d9c

@ -16,6 +16,7 @@
package org.springframework.boot.context.properties.migrator;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
@ -108,21 +109,42 @@ class PropertiesMigrationReporter {
ConfigurationMetadataProperty replacement = this.allProperties
.get(replacementId);
if (replacement != null) {
return replacement.getType().equals(metadata.getType());
}
replacement = getMapProperty(replacementId);
if (replacement != null) {
return replacement.getType().startsWith("java.util.Map")
&& replacement.getType().endsWith(metadata.getType() + ">");
return isCompatibleType(metadata.getType(), replacement.getType());
}
return isCompatibleType(metadata.getType(),
detectMapValueReplacementType(replacementId));
}
return false;
}
private boolean isCompatibleType(String currentType, String replacementType) {
if (replacementType == null || currentType == null) {
return false;
}
if (replacementType.equals(currentType)) {
return true;
}
if (replacementType.equals(Duration.class.getName())
&& (currentType.equals(Long.class.getName())
|| currentType.equals(Integer.class.getName()))) {
return true;
}
return false;
}
private ConfigurationMetadataProperty getMapProperty(String fullId) {
private String detectMapValueReplacementType(String fullId) {
int i = fullId.lastIndexOf('.');
if (i != -1) {
return this.allProperties.get(fullId.substring(0, i));
ConfigurationMetadataProperty property = this.allProperties.get(
fullId.substring(0, i));
String type = property.getType();
if (type != null
&& type.startsWith(Map.class.getName())) {
int lastComma = type.lastIndexOf(',');
if (lastComma != -1) {
return type.substring(lastComma + 1, type.length() - 1).trim();
}
}
}
return null;
}

@ -18,7 +18,9 @@ package org.springframework.boot.context.properties.migrator;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
@ -29,6 +31,7 @@ import org.springframework.boot.env.PropertiesPropertySourceLoader;
import org.springframework.boot.origin.Origin;
import org.springframework.boot.origin.OriginLookup;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.PropertySources;
@ -115,6 +118,29 @@ public class PropertiesMigrationReporterTests {
.doesNotContain("debug");
}
@Test
public void durationTypeIsHandledTransparently() {
MutablePropertySources propertySources = this.environment.getPropertySources();
Map<String, Object> content = new LinkedHashMap<>();
content.put("test.cache-seconds", 50);
content.put("test.time-to-live-ms", 1234L);
content.put("test.ttl", 5678L);
propertySources.addFirst(
new MapPropertySource("test", content));
assertThat(propertySources).hasSize(2);
String report = createWarningReport(
loadRepository("metadata/type-conversion-metadata.json"));
assertThat(report).contains("Property source 'test'", "test.cache-seconds",
"test.cache", "test.time-to-live-ms", "test.time-to-live", "test.ttl",
"test.mapped.ttl");
assertThat(mapToNames(propertySources)).containsExactly("migrate-test", "test",
"mockProperties");
PropertySource<?> propertySource = propertySources.get("migrate-test");
assertMappedProperty(propertySource, "test.cache", 50, null);
assertMappedProperty(propertySource, "test.time-to-live", 1234L, null);
assertMappedProperty(propertySource, "test.mapped.ttl", 5678L, null);
}
private List<String> mapToNames(PropertySources sources) {
List<String> names = new ArrayList<>();
for (PropertySource<?> source : sources) {

@ -0,0 +1,40 @@
{
"properties": [
{
"name": "test.cache",
"type": "java.time.Duration"
},
{
"name": "test.time-to-live",
"type": "java.time.Duration"
},
{
"name": "test.mapped",
"type": "java.util.Map<java.lang.String, java.time.Duration>"
},
{
"name": "test.cache-seconds",
"type": "java.lang.Integer",
"deprecation": {
"replacement": "test.cache",
"level": "error"
}
},
{
"name": "test.time-to-live-ms",
"type": "java.lang.Long",
"deprecation": {
"replacement": "test.time-to-live",
"level": "error"
}
},
{
"name": "test.ttl",
"type": "java.lang.Long",
"deprecation": {
"replacement": "test.mapped.ttl",
"level": "error"
}
}
]
}
Loading…
Cancel
Save