Merge branch '2.7.x' into 3.0.x
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 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.
|
||||
@@ -77,7 +77,7 @@ class PropertiesMigrationListener implements ApplicationListener<SpringApplicati
|
||||
private ConfigurationMetadataRepository loadRepository(ConfigurationMetadataRepositoryJsonBuilder builder)
|
||||
throws IOException {
|
||||
Resource[] resources = new PathMatchingResourcePatternResolver()
|
||||
.getResources("classpath*:/META-INF/spring-configuration-metadata.json");
|
||||
.getResources("classpath*:/META-INF/spring-configuration-metadata.json");
|
||||
for (Resource resource : resources) {
|
||||
try (InputStream inputStream = resource.getInputStream()) {
|
||||
builder.withJsonResource(inputStream);
|
||||
|
||||
@@ -45,7 +45,7 @@ class PropertiesMigrationReport {
|
||||
}
|
||||
StringBuilder report = new StringBuilder();
|
||||
report.append(String
|
||||
.format("%nThe use of configuration keys that have been renamed was found in the environment:%n%n"));
|
||||
.format("%nThe use of configuration keys that have been renamed was found in the environment:%n%n"));
|
||||
append(report, content);
|
||||
report.append(String.format("%n"));
|
||||
report.append("Each configuration key has been temporarily mapped to its "
|
||||
@@ -66,8 +66,8 @@ class PropertiesMigrationReport {
|
||||
return null;
|
||||
}
|
||||
StringBuilder report = new StringBuilder();
|
||||
report.append(String.format(
|
||||
"%nThe use of configuration keys that are no longer supported was found in the environment:%n%n"));
|
||||
report.append(String
|
||||
.format("%nThe use of configuration keys that are no longer supported was found in the environment:%n%n"));
|
||||
append(report, content);
|
||||
report.append(String.format("%n"));
|
||||
report.append("Please refer to the release notes or reference guide for potential alternatives.");
|
||||
@@ -77,8 +77,11 @@ class PropertiesMigrationReport {
|
||||
|
||||
private Map<String, List<PropertyMigration>> getContent(
|
||||
Function<LegacyProperties, List<PropertyMigration>> extractor) {
|
||||
return this.content.entrySet().stream().filter((entry) -> !extractor.apply(entry.getValue()).isEmpty()).collect(
|
||||
Collectors.toMap(Map.Entry::getKey, (entry) -> new ArrayList<>(extractor.apply(entry.getValue()))));
|
||||
return this.content.entrySet()
|
||||
.stream()
|
||||
.filter((entry) -> !extractor.apply(entry.getValue()).isEmpty())
|
||||
.collect(
|
||||
Collectors.toMap(Map.Entry::getKey, (entry) -> new ArrayList<>(extractor.apply(entry.getValue()))));
|
||||
}
|
||||
|
||||
private void append(StringBuilder report, Map<String, List<PropertyMigration>> content) {
|
||||
|
||||
@@ -80,8 +80,9 @@ class PropertiesMigrationReporter {
|
||||
private PropertySource<?> mapPropertiesWithReplacement(PropertiesMigrationReport report, String name,
|
||||
List<PropertyMigration> properties) {
|
||||
report.add(name, properties);
|
||||
List<PropertyMigration> renamed = properties.stream().filter(PropertyMigration::isCompatibleType)
|
||||
.collect(Collectors.toList());
|
||||
List<PropertyMigration> renamed = properties.stream()
|
||||
.filter(PropertyMigration::isCompatibleType)
|
||||
.collect(Collectors.toList());
|
||||
if (renamed.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
@@ -103,8 +104,10 @@ class PropertiesMigrationReporter {
|
||||
private Map<String, List<PropertyMigration>> getMatchingProperties(
|
||||
Predicate<ConfigurationMetadataProperty> filter) {
|
||||
MultiValueMap<String, PropertyMigration> result = new LinkedMultiValueMap<>();
|
||||
List<ConfigurationMetadataProperty> candidates = this.allProperties.values().stream().filter(filter)
|
||||
.collect(Collectors.toList());
|
||||
List<ConfigurationMetadataProperty> candidates = this.allProperties.values()
|
||||
.stream()
|
||||
.filter(filter)
|
||||
.collect(Collectors.toList());
|
||||
getPropertySourcesAsMap().forEach((propertySourceName, propertySource) -> candidates.forEach((metadata) -> {
|
||||
ConfigurationPropertyName metadataName = ConfigurationPropertyName.isValid(metadata.getId())
|
||||
? ConfigurationPropertyName.of(metadata.getId())
|
||||
@@ -118,12 +121,13 @@ class PropertiesMigrationReporter {
|
||||
// Prefix match for maps
|
||||
if (isMapType(metadata) && propertySource instanceof IterableConfigurationPropertySource) {
|
||||
IterableConfigurationPropertySource iterableSource = (IterableConfigurationPropertySource) propertySource;
|
||||
iterableSource.stream().filter(metadataName::isAncestorOf).map(propertySource::getConfigurationProperty)
|
||||
.forEach((property) -> {
|
||||
ConfigurationMetadataProperty replacement = determineReplacementMetadata(metadata);
|
||||
result.add(propertySourceName,
|
||||
new PropertyMigration(property, metadata, replacement, true));
|
||||
});
|
||||
iterableSource.stream()
|
||||
.filter(metadataName::isAncestorOf)
|
||||
.map(propertySource::getConfigurationProperty)
|
||||
.forEach((property) -> {
|
||||
ConfigurationMetadataProperty replacement = determineReplacementMetadata(metadata);
|
||||
result.add(propertySourceName, new PropertyMigration(property, metadata, replacement, true));
|
||||
});
|
||||
}
|
||||
}));
|
||||
return result;
|
||||
|
||||
@@ -38,7 +38,7 @@ import org.springframework.util.StringUtils;
|
||||
class PropertyMigration {
|
||||
|
||||
public static final Comparator<PropertyMigration> COMPARATOR = Comparator
|
||||
.comparing((property) -> property.getMetadata().getId());
|
||||
.comparing((property) -> property.getMetadata().getId());
|
||||
|
||||
private final ConfigurationProperty property;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 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.
|
||||
@@ -48,9 +48,10 @@ class PropertiesMigrationListenerTests {
|
||||
@Test
|
||||
void sampleReport(CapturedOutput output) {
|
||||
this.context = createSampleApplication().run("--logging.file=test.log");
|
||||
assertThat(output).contains("commandLineArgs").contains("logging.file.name")
|
||||
.contains("Each configuration key has been temporarily mapped")
|
||||
.doesNotContain("Please refer to the release notes");
|
||||
assertThat(output).contains("commandLineArgs")
|
||||
.contains("logging.file.name")
|
||||
.contains("Each configuration key has been temporarily mapped")
|
||||
.doesNotContain("Please refer to the release notes");
|
||||
}
|
||||
|
||||
private SpringApplication createSampleApplication() {
|
||||
|
||||
@@ -90,7 +90,7 @@ class PropertiesMigrationReporterTests {
|
||||
@Test
|
||||
void errorReport() throws IOException {
|
||||
this.environment.getPropertySources()
|
||||
.addFirst(loadPropertySource("test1", "config/config-warnings.properties"));
|
||||
.addFirst(loadPropertySource("test1", "config/config-warnings.properties"));
|
||||
this.environment.getPropertySources().addFirst(loadPropertySource("test2", "config/config-error.properties"));
|
||||
String report = createErrorReport(loadRepository("metadata/sample-metadata.json"));
|
||||
assertThat(report).isNotNull();
|
||||
@@ -102,7 +102,7 @@ class PropertiesMigrationReporterTests {
|
||||
@Test
|
||||
void errorReportNoReplacement() throws IOException {
|
||||
this.environment.getPropertySources()
|
||||
.addFirst(loadPropertySource("first", "config/config-error-no-replacement.properties"));
|
||||
.addFirst(loadPropertySource("first", "config/config-error-no-replacement.properties"));
|
||||
this.environment.getPropertySources().addFirst(loadPropertySource("second", "config/config-error.properties"));
|
||||
String report = createErrorReport(loadRepository("metadata/sample-metadata.json"));
|
||||
assertThat(report).isNotNull();
|
||||
@@ -134,7 +134,7 @@ class PropertiesMigrationReporterTests {
|
||||
@Test
|
||||
void reasonIsProvidedIfPropertyCouldNotBeRenamed() throws IOException {
|
||||
this.environment.getPropertySources()
|
||||
.addFirst(loadPropertySource("test", "config/config-error-no-compatible-type.properties"));
|
||||
.addFirst(loadPropertySource("test", "config/config-error-no-compatible-type.properties"));
|
||||
String report = createErrorReport(loadRepository("metadata/type-conversion-metadata.json"));
|
||||
assertThat(report).isNotNull();
|
||||
assertThat(report).containsSubsequence("Property source 'test'", "wrong.inconvertible", "Line: 1",
|
||||
@@ -144,7 +144,7 @@ class PropertiesMigrationReporterTests {
|
||||
@Test
|
||||
void invalidReplacementHandled() throws IOException {
|
||||
this.environment.getPropertySources()
|
||||
.addFirst(loadPropertySource("first", "config/config-error-invalid-replacement.properties"));
|
||||
.addFirst(loadPropertySource("first", "config/config-error-invalid-replacement.properties"));
|
||||
String report = createErrorReport(loadRepository("metadata/sample-metadata-invalid-replacement.json"));
|
||||
assertThat(report).isNotNull();
|
||||
assertThat(report).containsSubsequence("Property source 'first'", "deprecated.six.test", "Line: 1", "Reason",
|
||||
@@ -155,7 +155,7 @@ class PropertiesMigrationReporterTests {
|
||||
@Test
|
||||
void invalidNameHandledGracefully() {
|
||||
this.environment.getPropertySources()
|
||||
.addFirst(new MapPropertySource("first", Collections.singletonMap("invalid.property-name", "value")));
|
||||
.addFirst(new MapPropertySource("first", Collections.singletonMap("invalid.property-name", "value")));
|
||||
String report = createWarningReport(loadRepository("metadata/sample-metadata-invalid-name.json"));
|
||||
assertThat(report).isNotNull();
|
||||
assertThat(report).contains("Key: invalid.propertyname").contains("Replacement: valid.property-name");
|
||||
@@ -163,42 +163,46 @@ class PropertiesMigrationReporterTests {
|
||||
|
||||
@Test
|
||||
void mapPropertiesDeprecatedNoReplacement() throws IOException {
|
||||
this.environment.getPropertySources().addFirst(
|
||||
new MapPropertySource("first", Collections.singletonMap("custom.map-no-replacement.key", "value")));
|
||||
this.environment.getPropertySources()
|
||||
.addFirst(
|
||||
new MapPropertySource("first", Collections.singletonMap("custom.map-no-replacement.key", "value")));
|
||||
String report = createErrorReport(loadRepository("metadata/sample-metadata.json"));
|
||||
assertThat(report).isNotNull();
|
||||
assertThat(report).contains("Key: custom.map-no-replacement.key")
|
||||
.contains("Reason: This is no longer supported.");
|
||||
.contains("Reason: This is no longer supported.");
|
||||
}
|
||||
|
||||
@Test
|
||||
void mapPropertiesDeprecatedWithReplacement() throws IOException {
|
||||
this.environment.getPropertySources().addFirst(
|
||||
new MapPropertySource("first", Collections.singletonMap("custom.map-with-replacement.key", "value")));
|
||||
this.environment.getPropertySources()
|
||||
.addFirst(new MapPropertySource("first",
|
||||
Collections.singletonMap("custom.map-with-replacement.key", "value")));
|
||||
String report = createWarningReport(loadRepository("metadata/sample-metadata.json"));
|
||||
assertThat(report).isNotNull();
|
||||
assertThat(report).contains("Key: custom.map-with-replacement.key")
|
||||
.contains("Replacement: custom.the-map-replacement.key");
|
||||
.contains("Replacement: custom.the-map-replacement.key");
|
||||
}
|
||||
|
||||
@Test
|
||||
void mapPropertiesDeprecatedWithReplacementRelaxedBindingUnderscore() {
|
||||
this.environment.getPropertySources().addFirst(
|
||||
new MapPropertySource("first", Collections.singletonMap("custom.map_with_replacement.key", "value")));
|
||||
this.environment.getPropertySources()
|
||||
.addFirst(new MapPropertySource("first",
|
||||
Collections.singletonMap("custom.map_with_replacement.key", "value")));
|
||||
String report = createWarningReport(loadRepository("metadata/sample-metadata.json"));
|
||||
assertThat(report).isNotNull();
|
||||
assertThat(report).contains("Key: custom.mapwithreplacement.key")
|
||||
.contains("Replacement: custom.the-map-replacement.key");
|
||||
.contains("Replacement: custom.the-map-replacement.key");
|
||||
}
|
||||
|
||||
@Test
|
||||
void mapPropertiesDeprecatedWithReplacementRelaxedBindingCamelCase() {
|
||||
this.environment.getPropertySources().addFirst(
|
||||
new MapPropertySource("first", Collections.singletonMap("custom.MapWithReplacement.key", "value")));
|
||||
this.environment.getPropertySources()
|
||||
.addFirst(
|
||||
new MapPropertySource("first", Collections.singletonMap("custom.MapWithReplacement.key", "value")));
|
||||
String report = createWarningReport(loadRepository("metadata/sample-metadata.json"));
|
||||
assertThat(report).isNotNull();
|
||||
assertThat(report).contains("Key: custom.mapwithreplacement.key")
|
||||
.contains("Replacement: custom.the-map-replacement.key");
|
||||
.contains("Replacement: custom.the-map-replacement.key");
|
||||
}
|
||||
|
||||
private List<String> mapToNames(PropertySources sources) {
|
||||
|
||||
Reference in New Issue
Block a user