From 32e1289bbcdc0c1bf8ff9a375600cb9f9277f73d Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 10 Dec 2020 11:03:03 +0000 Subject: [PATCH] Use unique names for wildcard property sources Update `StandardConfigDataLoader` to use unique names for property sources imported from a wildcard location. Prior to this commit, all the property sources created from the same wildcard location would have the same name. Each time a property source that is equal to an existing property source is added, it replaces the existing property source. Property source equality is name-based so this resulted in the last property sources from the wildcard location winning. This commit updates `StandardConfigDataLoader` to use the resolved Resource rather than the wildcard location in which it was discovered in the name of the property source that it creates, ensuring that each is property source from a wildcard location is uniquely named. Fixes gh-24428 --- .../config/StandardConfigDataLoader.java | 2 +- ...ironmentPostProcessorIntegrationTests.java | 19 +++++++++++++++---- .../config/StandardConfigDataLoaderTests.java | 10 ++++++---- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/StandardConfigDataLoader.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/StandardConfigDataLoader.java index bd8f730dfc..eb8ad51bcc 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/StandardConfigDataLoader.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/StandardConfigDataLoader.java @@ -40,7 +40,7 @@ public class StandardConfigDataLoader implements ConfigDataLoader> propertySources = reference.getPropertySourceLoader().load(name, originTrackedResource); return new ConfigData(propertySources); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentPostProcessorIntegrationTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentPostProcessorIntegrationTests.java index b321ef6f92..0741b280f5 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentPostProcessorIntegrationTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentPostProcessorIntegrationTests.java @@ -383,8 +383,8 @@ class ConfigDataEnvironmentPostProcessorIntegrationTests { List names = StreamSupport.stream(context.getEnvironment().getPropertySources().spliterator(), false) .map(org.springframework.core.env.PropertySource::getName).collect(Collectors.toList()); assertThat(names).contains( - "Config resource 'classpath:configdata/profiles/testsetprofiles.yml' via location 'classpath:configdata/profiles/' (document #0)", - "Config resource 'classpath:configdata/profiles/testsetprofiles.yml' via location 'classpath:configdata/profiles/' (document #1)"); + "Config resource 'class path resource [configdata/profiles/testsetprofiles.yml]' via location 'classpath:configdata/profiles/' (document #0)", + "Config resource 'class path resource [configdata/profiles/testsetprofiles.yml]' via location 'classpath:configdata/profiles/' (document #1)"); } @Test @@ -411,7 +411,7 @@ class ConfigDataEnvironmentPostProcessorIntegrationTests { String location = "file:src/test/resources/specificlocation.properties"; ConfigurableApplicationContext context = this.application.run("--spring.config.location=" + location); assertThat(context.getEnvironment()).has(matchingPropertySource( - "Config resource 'file:src/test/resources/specificlocation.properties' via location '" + location + "Config resource 'file [src/test/resources/specificlocation.properties]' via location '" + location + "'")); } @@ -420,7 +420,8 @@ class ConfigDataEnvironmentPostProcessorIntegrationTests { String location = "src/test/resources/specificlocation.properties"; ConfigurableApplicationContext context = this.application.run("--spring.config.location=" + location); assertThat(context.getEnvironment()).has(matchingPropertySource( - "Config resource 'src/test/resources/specificlocation.properties' via location '" + location + "'")); + "Config resource 'file [src/test/resources/specificlocation.properties]' via location '" + location + + "'")); } @Test @@ -619,6 +620,16 @@ class ConfigDataEnvironmentPostProcessorIntegrationTests { assertThat(origin.getParent().toString()).contains("application-import-with-placeholder"); } + @Test + void runWhenHasWildcardLocationLoadsFromAllMatchingLocations() { + ConfigurableApplicationContext context = this.application.run( + "--spring.config.location=optional:file:src/test/resources/config/*/", + "--spring.config.name=testproperties"); + ConfigurableEnvironment environment = context.getEnvironment(); + assertThat(environment.getProperty("first.property")).isEqualTo("apple"); + assertThat(environment.getProperty("second.property")).isEqualTo("ball"); + } + private Condition matchingPropertySource(final String sourceName) { return new Condition("environment containing property source " + sourceName) { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/StandardConfigDataLoaderTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/StandardConfigDataLoaderTests.java index ee69d6a545..e4f38fbb24 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/StandardConfigDataLoaderTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/StandardConfigDataLoaderTests.java @@ -51,11 +51,13 @@ public class StandardConfigDataLoaderTests { assertThat(configData.getPropertySources().size()).isEqualTo(2); PropertySource source1 = configData.getPropertySources().get(0); PropertySource source2 = configData.getPropertySources().get(1); - assertThat(source1.getName()).isEqualTo("Config resource 'classpath:configdata/yaml/application.yml' " - + "via location 'classpath:configdata/yaml/application.yml' (document #0)"); + assertThat(source1.getName()) + .isEqualTo("Config resource 'class path resource [configdata/yaml/application.yml]' " + + "via location 'classpath:configdata/yaml/application.yml' (document #0)"); assertThat(source1.getProperty("foo")).isEqualTo("bar"); - assertThat(source2.getName()).isEqualTo("Config resource 'classpath:configdata/yaml/application.yml' " - + "via location 'classpath:configdata/yaml/application.yml' (document #1)"); + assertThat(source2.getName()) + .isEqualTo("Config resource 'class path resource [configdata/yaml/application.yml]' " + + "via location 'classpath:configdata/yaml/application.yml' (document #1)"); assertThat(source2.getProperty("hello")).isEqualTo("world"); }