Merge branch '2.4.x'

Closes gh-26782
This commit is contained in:
Phillip Webb
2021-06-06 21:06:38 -07:00
12 changed files with 163 additions and 29 deletions

View File

@@ -87,11 +87,8 @@ class ConfigDataEnvironment {
static final ConfigDataLocation[] DEFAULT_SEARCH_LOCATIONS;
static {
List<ConfigDataLocation> locations = new ArrayList<>();
locations.add(ConfigDataLocation.of("optional:classpath:/"));
locations.add(ConfigDataLocation.of("optional:classpath:/config/"));
locations.add(ConfigDataLocation.of("optional:file:./"));
locations.add(ConfigDataLocation.of("optional:file:./config/"));
locations.add(ConfigDataLocation.of("optional:file:./config/*/"));
locations.add(ConfigDataLocation.of("optional:classpath:/;optional:classpath:/config/"));
locations.add(ConfigDataLocation.of("optional:file:./;optional:file:./config/;optional:file:./config/*/"));
DEFAULT_SEARCH_LOCATIONS = locations.toArray(new ConfigDataLocation[0]);
}

View File

@@ -97,6 +97,32 @@ public final class ConfigDataLocation implements OriginProvider {
return this.origin;
}
/**
* Return an array of {@link ConfigDataLocation} elements built by splitting this
* {@link ConfigDataLocation} around a delimiter of {@code ";"}.
* @return the split locations
* @since 2.4.7
*/
public ConfigDataLocation[] split() {
return split(";");
}
/**
* Return an array of {@link ConfigDataLocation} elements built by splitting this
* {@link ConfigDataLocation} around the specified delimiter.
* @param delimiter the delimiter to split on
* @return the split locations
* @since 2.4.7
*/
public ConfigDataLocation[] split(String delimiter) {
String[] values = StringUtils.delimitedListToStringArray(toString(), delimiter);
ConfigDataLocation[] result = new ConfigDataLocation[values.length];
for (int i = 0; i < values.length; i++) {
result[i] = of(values[i]).withOrigin(getOrigin());
}
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {

View File

@@ -116,7 +116,16 @@ public class StandardConfigDataLocationResolver
@Override
public List<StandardConfigDataResource> resolve(ConfigDataLocationResolverContext context,
ConfigDataLocation location) throws ConfigDataNotFoundException {
return resolve(getReferences(context, location));
return resolve(getReferences(context, location.split()));
}
private Set<StandardConfigDataReference> getReferences(ConfigDataLocationResolverContext context,
ConfigDataLocation[] configDataLocations) {
Set<StandardConfigDataReference> references = new LinkedHashSet<>();
for (ConfigDataLocation configDataLocation : configDataLocations) {
references.addAll(getReferences(context, configDataLocation));
}
return references;
}
private Set<StandardConfigDataReference> getReferences(ConfigDataLocationResolverContext context,
@@ -139,15 +148,17 @@ public class StandardConfigDataLocationResolver
if (context.getParent() != null) {
return null;
}
return resolve(getProfileSpecificReferences(context, location, profiles));
return resolve(getProfileSpecificReferences(context, location.split(), profiles));
}
private Set<StandardConfigDataReference> getProfileSpecificReferences(ConfigDataLocationResolverContext context,
ConfigDataLocation configDataLocation, Profiles profiles) {
ConfigDataLocation[] configDataLocations, Profiles profiles) {
Set<StandardConfigDataReference> references = new LinkedHashSet<>();
String resourceLocation = getResourceLocation(context, configDataLocation);
for (String profile : profiles) {
references.addAll(getReferences(configDataLocation, resourceLocation, profile));
for (ConfigDataLocation configDataLocation : configDataLocations) {
String resourceLocation = getResourceLocation(context, configDataLocation);
references.addAll(getReferences(configDataLocation, resourceLocation, profile));
}
}
return references;
}

View File

@@ -772,6 +772,21 @@ class ConfigDataEnvironmentPostProcessorIntegrationTests {
assertThat(environment.containsProperty("test:boot:ps")).isFalse();
}
@Test // gh-26593
void runWhenHasFilesInRootAndConfigWithProfiles() {
ConfigurableApplicationContext context = this.application
.run("--spring.config.name=file-in-root-and-config-with-profile", "--spring.profiles.active=p1,p2");
ConfigurableEnvironment environment = context.getEnvironment();
assertThat(environment.containsProperty("file-in-root-and-config-with-profile")).isTrue();
assertThat(environment.containsProperty("file-in-root-and-config-with-profile-p1")).isTrue();
assertThat(environment.containsProperty("file-in-root-and-config-with-profile-p2")).isTrue();
assertThat(environment.containsProperty("config-file-in-root-and-config-with-profile")).isTrue();
assertThat(environment.containsProperty("config-file-in-root-and-config-with-profile-p1")).isTrue();
assertThat(environment.containsProperty("config-file-in-root-and-config-with-profile-p2")).isTrue();
assertThat(environment.getProperty("v1")).isEqualTo("config-file-in-root-and-config-with-profile-p2");
assertThat(environment.getProperty("v2")).isEqualTo("file-in-root-and-config-with-profile-p2");
}
private Condition<ConfigurableEnvironment> matchingPropertySource(final String sourceName) {
return new Condition<ConfigurableEnvironment>("environment containing property source " + sourceName) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 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.
@@ -134,4 +134,36 @@ class ConfigDataLocationTests {
assertThat(ConfigDataLocation.of("test")).hasToString("test");
}
@Test
void splitWhenNoSemiColonReturnsSingleElement() {
ConfigDataLocation location = ConfigDataLocation.of("test");
ConfigDataLocation[] split = location.split();
assertThat(split).containsExactly(ConfigDataLocation.of("test"));
}
@Test
void splitWhenSemiColonReturnsElements() {
ConfigDataLocation location = ConfigDataLocation.of("one;two;three");
ConfigDataLocation[] split = location.split();
assertThat(split).containsExactly(ConfigDataLocation.of("one"), ConfigDataLocation.of("two"),
ConfigDataLocation.of("three"));
}
@Test
void splitOnCharReturnsElements() {
ConfigDataLocation location = ConfigDataLocation.of("one::two::three");
ConfigDataLocation[] split = location.split("::");
assertThat(split).containsExactly(ConfigDataLocation.of("one"), ConfigDataLocation.of("two"),
ConfigDataLocation.of("three"));
}
@Test
void splitWhenHasOriginReturnsElementsWithOriginSet() {
Origin origin = mock(Origin.class);
ConfigDataLocation location = ConfigDataLocation.of("a;b").withOrigin(origin);
ConfigDataLocation[] split = location.split();
assertThat(split[0].getOrigin()).isEqualTo(origin);
assertThat(split[1].getOrigin()).isEqualTo(origin);
}
}

View File

@@ -0,0 +1,3 @@
config-file-in-root-and-config-with-profile-p1=true
v1=config-file-in-root-and-config-with-profile-p1
#v2 intentionally missing

View File

@@ -0,0 +1,3 @@
config-file-in-root-and-config-with-profile-p2=true
v1=config-file-in-root-and-config-with-profile-p2
#v2 intentionally missing

View File

@@ -0,0 +1,3 @@
config-file-in-root-and-config-with-profile=true
v1=config-file-in-root-and-config-with-profile
v2=config-file-in-root-and-config-with-profile

View File

@@ -0,0 +1,3 @@
file-in-root-and-config-with-profile-p1=true
v1=file-in-root-and-config-with-profile-p1
v2=file-in-root-and-config-with-profile-p1

View File

@@ -0,0 +1,3 @@
file-in-root-and-config-with-profile-p2=true
v1=file-in-root-and-config-with-profile-p2
v2=file-in-root-and-config-with-profile-p2

View File

@@ -0,0 +1,3 @@
file-in-root-and-config-with-profile=true
v1=file-in-root-and-config-with-profile
v2=file-in-root-and-config-with-profile