Browse Source

Refine mandatory location checking logic

Update `ConfigDataEnvironment.checkMandatoryLocations` to use the
actual locations that were imported, including those that were skipped
because the related `ConfigDataResource` had already been imported by a
different location.

Prior to this commit, any location that was skipped because it had
already been imported would throw a `ConfigDataNotFoundException`.

Closes gh-26147

Co-authored-by: Scott Frederick <sfrederick@vmware.com>
Co-authored-by: Madhura Bhave <mbhave@vmware.com>
pull/26435/head
Phillip Webb 5 years ago
parent
commit
efad44be43
  1. 9
      spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironment.java
  2. 13
      spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataImporter.java
  3. 8
      spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentPostProcessorIntegrationTests.java
  4. 2
      spring-boot-project/spring-boot/src/test/resources/application-import-with-profile-variant-and-direct-profile-import-dev.properties
  5. 2
      spring-boot-project/spring-boot/src/test/resources/application-import-with-profile-variant-and-direct-profile-import.properties

9
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironment.java

@ -233,7 +233,7 @@ class ConfigDataEnvironment { @@ -233,7 +233,7 @@ class ConfigDataEnvironment {
contributors = processWithoutProfiles(contributors, importer, activationContext);
activationContext = withProfiles(contributors, activationContext);
contributors = processWithProfiles(contributors, importer, activationContext);
applyToEnvironment(contributors, activationContext);
applyToEnvironment(contributors, activationContext, importer.getLoadedLocations());
}
private ConfigDataEnvironmentContributors processInitial(ConfigDataEnvironmentContributors contributors,
@ -320,9 +320,9 @@ class ConfigDataEnvironment { @@ -320,9 +320,9 @@ class ConfigDataEnvironment {
}
private void applyToEnvironment(ConfigDataEnvironmentContributors contributors,
ConfigDataActivationContext activationContext) {
ConfigDataActivationContext activationContext, Set<ConfigDataLocation> loadedLocations) {
checkForInvalidProperties(contributors);
checkMandatoryLocations(contributors, activationContext);
checkMandatoryLocations(contributors, activationContext, loadedLocations);
MutablePropertySources propertySources = this.environment.getPropertySources();
this.logger.trace("Applying config data environment contributions");
for (ConfigDataEnvironmentContributor contributor : contributors) {
@ -357,7 +357,7 @@ class ConfigDataEnvironment { @@ -357,7 +357,7 @@ class ConfigDataEnvironment {
}
private void checkMandatoryLocations(ConfigDataEnvironmentContributors contributors,
ConfigDataActivationContext activationContext) {
ConfigDataActivationContext activationContext, Set<ConfigDataLocation> loadedLocations) {
Set<ConfigDataLocation> mandatoryLocations = new LinkedHashSet<>();
for (ConfigDataEnvironmentContributor contributor : contributors) {
if (contributor.isActive(activationContext)) {
@ -369,6 +369,7 @@ class ConfigDataEnvironment { @@ -369,6 +369,7 @@ class ConfigDataEnvironment {
mandatoryLocations.remove(contributor.getLocation());
}
}
mandatoryLocations.removeAll(loadedLocations);
if (!mandatoryLocations.isEmpty()) {
for (ConfigDataLocation mandatoryLocation : mandatoryLocations) {
this.notFoundAction.handle(this.logger, new ConfigDataLocationNotFoundException(mandatoryLocation));

13
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataImporter.java

@ -49,6 +49,8 @@ class ConfigDataImporter { @@ -49,6 +49,8 @@ class ConfigDataImporter {
private final Set<ConfigDataResource> loaded = new HashSet<>();
private final Set<ConfigDataLocation> loadedLocations = new HashSet<>();
/**
* Create a new {@link ConfigDataImporter} instance.
* @param logFactory the log factory
@ -113,10 +115,15 @@ class ConfigDataImporter { @@ -113,10 +115,15 @@ class ConfigDataImporter {
ConfigDataResolutionResult candidate = candidates.get(i);
ConfigDataLocation location = candidate.getLocation();
ConfigDataResource resource = candidate.getResource();
if (this.loaded.add(resource)) {
if (this.loaded.contains(resource)) {
this.loadedLocations.add(location);
}
else {
try {
ConfigData loaded = this.loaders.load(loaderContext, resource);
if (loaded != null) {
this.loaded.add(resource);
this.loadedLocations.add(location);
result.put(candidate, loaded);
}
}
@ -139,4 +146,8 @@ class ConfigDataImporter { @@ -139,4 +146,8 @@ class ConfigDataImporter {
return (!location.isOptional()) ? this.notFoundAction : ConfigDataNotFoundAction.IGNORE;
}
Set<ConfigDataLocation> getLoadedLocations() {
return this.loadedLocations;
}
}

8
spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentPostProcessorIntegrationTests.java

@ -604,6 +604,14 @@ class ConfigDataEnvironmentPostProcessorIntegrationTests { @@ -604,6 +604,14 @@ class ConfigDataEnvironmentPostProcessorIntegrationTests {
assertThat(context.getEnvironment().getProperty("my.value")).isEqualTo("iwasimported-dev");
}
@Test
void runWhenImportWithProfileVariantAndDirectProfileImportOrdersPropertySourcesCorrectly() {
this.application.setAdditionalProfiles("dev");
ConfigurableApplicationContext context = this.application.run(
"--spring.config.location=classpath:application-import-with-profile-variant-and-direct-profile-import.properties");
assertThat(context.getEnvironment().getProperty("my.value")).isEqualTo("iwasimported-dev");
}
@Test
void runWhenHasPropertyInProfileDocumentThrowsException() {
assertThatExceptionOfType(BindException.class).isThrownBy(() -> this.application.run(

2
spring-boot-project/spring-boot/src/test/resources/application-import-with-profile-variant-and-direct-profile-import-dev.properties

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
spring.config.import=classpath:application-import-with-profile-variant-imported-dev.properties
my.value=notimported-dev

2
spring-boot-project/spring-boot/src/test/resources/application-import-with-profile-variant-and-direct-profile-import.properties

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
spring.config.import=classpath:application-import-with-profile-variant-imported.properties
my.value=notimported
Loading…
Cancel
Save