Commit 3dc03ac2 authored by Phillip Webb's avatar Phillip Webb

Refine non-optional classpath location checking

Update `StandardConfigDataLocationResolver` to no longer check if
directories exist for classpath resources. Unfortunately checking for
the parent directory of a `ClassPathResource` isn't always possible
without resorting something similar to the
`PathMatchingResourcePatternResolver` which would add a lot of
complexity to the resolver.

In order to ensure that non-optional locations are always resolved,
the `ConfigDataEnvironment` now checks that all imported locations
have been loaded.

Closes gh-24143
parent 01478a25
......@@ -297,6 +297,7 @@ class ConfigDataEnvironment {
private void applyToEnvironment(ConfigDataEnvironmentContributors contributors,
ConfigDataActivationContext activationContext) {
checkForInvalidProperties(contributors);
checkMandatoryLocations(contributors, activationContext);
MutablePropertySources propertySources = this.environment.getPropertySources();
this.logger.trace("Applying config data environment contributions");
for (ConfigDataEnvironmentContributor contributor : contributors) {
......@@ -327,4 +328,33 @@ class ConfigDataEnvironment {
}
}
private void checkMandatoryLocations(ConfigDataEnvironmentContributors contributors,
ConfigDataActivationContext activationContext) {
Set<ConfigDataLocation> mandatoryLocations = new LinkedHashSet<>();
for (ConfigDataEnvironmentContributor contributor : contributors) {
mandatoryLocations.addAll(getMandatoryImports(contributor));
}
for (ConfigDataEnvironmentContributor contributor : contributors) {
if (contributor.getLocation() != null) {
mandatoryLocations.remove(contributor.getLocation());
}
}
if (!mandatoryLocations.isEmpty()) {
for (ConfigDataLocation mandatoryLocation : mandatoryLocations) {
this.notFoundAction.handle(this.logger, new ConfigDataLocationNotFoundException(mandatoryLocation));
}
}
}
private Set<ConfigDataLocation> getMandatoryImports(ConfigDataEnvironmentContributor contributor) {
List<ConfigDataLocation> imports = contributor.getImports();
Set<ConfigDataLocation> mandatoryLocations = new LinkedHashSet<>(imports.size());
for (ConfigDataLocation location : imports) {
if (!location.isOptional()) {
mandatoryLocations.add(location);
}
}
return mandatoryLocations;
}
}
......@@ -51,6 +51,8 @@ import org.springframework.core.env.PropertySource;
*/
class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironmentContributor> {
private final ConfigDataLocation location;
private final ConfigDataResource resource;
private final PropertySource<?> propertySource;
......@@ -68,6 +70,7 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
/**
* Create a new {@link ConfigDataEnvironmentContributor} instance.
* @param kind the contributor kind
* @param location the location of this contributor
* @param resource the resource that contributed the data or {@code null}
* @param propertySource the property source for the data or {@code null}
* @param configurationPropertySource the configuration property source for the data
......@@ -76,10 +79,12 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
* @param ignoreImports if import properties should be ignored
* @param children the children of this contributor at each {@link ImportPhase}
*/
ConfigDataEnvironmentContributor(Kind kind, ConfigDataResource resource, PropertySource<?> propertySource,
ConfigurationPropertySource configurationPropertySource, ConfigDataProperties properties,
boolean ignoreImports, Map<ImportPhase, List<ConfigDataEnvironmentContributor>> children) {
ConfigDataEnvironmentContributor(Kind kind, ConfigDataLocation location, ConfigDataResource resource,
PropertySource<?> propertySource, ConfigurationPropertySource configurationPropertySource,
ConfigDataProperties properties, boolean ignoreImports,
Map<ImportPhase, List<ConfigDataEnvironmentContributor>> children) {
this.kind = kind;
this.location = location;
this.resource = resource;
this.properties = properties;
this.propertySource = propertySource;
......@@ -96,6 +101,10 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
return this.kind;
}
ConfigDataLocation getLocation() {
return this.location;
}
/**
* Return if this contributor is currently active.
* @param activationContext the activation context
......@@ -191,8 +200,8 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
if (this.ignoreImports) {
properties = properties.withoutImports();
}
return new ConfigDataEnvironmentContributor(Kind.BOUND_IMPORT, this.resource, this.propertySource,
this.configurationPropertySource, properties, this.ignoreImports, null);
return new ConfigDataEnvironmentContributor(Kind.BOUND_IMPORT, this.location, this.resource,
this.propertySource, this.configurationPropertySource, properties, this.ignoreImports, null);
}
/**
......@@ -206,7 +215,7 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
List<ConfigDataEnvironmentContributor> children) {
Map<ImportPhase, List<ConfigDataEnvironmentContributor>> updatedChildren = new LinkedHashMap<>(this.children);
updatedChildren.put(importPhase, children);
return new ConfigDataEnvironmentContributor(this.kind, this.resource, this.propertySource,
return new ConfigDataEnvironmentContributor(this.kind, this.location, this.resource, this.propertySource,
this.configurationPropertySource, this.properties, this.ignoreImports, updatedChildren);
}
......@@ -231,7 +240,7 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
}
updatedChildren.put(importPhase, Collections.unmodifiableList(updatedContributors));
});
return new ConfigDataEnvironmentContributor(this.kind, this.resource, this.propertySource,
return new ConfigDataEnvironmentContributor(this.kind, this.location, this.resource, this.propertySource,
this.configurationPropertySource, this.properties, this.ignoreImports, updatedChildren);
}
......@@ -243,7 +252,7 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
static ConfigDataEnvironmentContributor of(List<ConfigDataEnvironmentContributor> contributors) {
Map<ImportPhase, List<ConfigDataEnvironmentContributor>> children = new LinkedHashMap<>();
children.put(ImportPhase.BEFORE_PROFILE_ACTIVATION, Collections.unmodifiableList(contributors));
return new ConfigDataEnvironmentContributor(Kind.ROOT, null, null, null, null, false, children);
return new ConfigDataEnvironmentContributor(Kind.ROOT, null, null, null, null, null, false, children);
}
/**
......@@ -256,7 +265,8 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
static ConfigDataEnvironmentContributor ofInitialImport(ConfigDataLocation initialImport) {
List<ConfigDataLocation> imports = Collections.singletonList(initialImport);
ConfigDataProperties properties = new ConfigDataProperties(imports, null);
return new ConfigDataEnvironmentContributor(Kind.INITIAL_IMPORT, null, null, null, properties, false, null);
return new ConfigDataEnvironmentContributor(Kind.INITIAL_IMPORT, null, null, null, null, properties, false,
null);
}
/**
......@@ -267,7 +277,7 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
* @return a new {@link ConfigDataEnvironmentContributor} instance
*/
static ConfigDataEnvironmentContributor ofExisting(PropertySource<?> propertySource) {
return new ConfigDataEnvironmentContributor(Kind.EXISTING, null, propertySource,
return new ConfigDataEnvironmentContributor(Kind.EXISTING, null, null, propertySource,
ConfigurationPropertySource.from(propertySource), null, false, null);
}
......@@ -275,17 +285,18 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
* Factory method to create an {@link Kind#UNBOUND_IMPORT unbound import} contributor.
* This contributor has been actively imported from another contributor and may itself
* import further contributors later.
* @param resource the condig data resource
* @param location the location of this contributor
* @param resource the config data resource
* @param configData the config data
* @param propertySourceIndex the index of the property source that should be used
* @return a new {@link ConfigDataEnvironmentContributor} instance
*/
static ConfigDataEnvironmentContributor ofUnboundImport(ConfigDataResource resource, ConfigData configData,
int propertySourceIndex) {
static ConfigDataEnvironmentContributor ofUnboundImport(ConfigDataLocation location, ConfigDataResource resource,
ConfigData configData, int propertySourceIndex) {
PropertySource<?> propertySource = configData.getPropertySources().get(propertySourceIndex);
ConfigurationPropertySource configurationPropertySource = ConfigurationPropertySource.from(propertySource);
boolean ignoreImports = configData.getOptions().contains(ConfigData.Option.IGNORE_IMPORTS);
return new ConfigDataEnvironmentContributor(Kind.UNBOUND_IMPORT, resource, propertySource,
return new ConfigDataEnvironmentContributor(Kind.UNBOUND_IMPORT, location, resource, propertySource,
configurationPropertySource, null, ignoreImports, null);
}
......
......@@ -24,6 +24,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.logging.Log;
......@@ -115,10 +116,9 @@ class ConfigDataEnvironmentContributors implements Iterable<ConfigDataEnvironmen
ConfigDataLoaderContext loaderContext = new ContributorDataLoaderContext(this);
List<ConfigDataLocation> imports = contributor.getImports();
this.logger.trace(LogMessage.format("Processing imports %s", imports));
Map<ConfigDataResource, ConfigData> imported = importer.resolveAndLoad(activationContext,
Map<ConfigDataResolutionResult, ConfigData> imported = importer.resolveAndLoad(activationContext,
locationResolverContext, loaderContext, imports);
this.logger.trace(LogMessage.of(() -> imported.isEmpty() ? "Nothing imported" : "Imported "
+ imported.size() + " resource " + ((imported.size() != 1) ? "s" : "") + imported.keySet()));
this.logger.trace(LogMessage.of(() -> getImportedMessage(imported.keySet())));
ConfigDataEnvironmentContributor contributorAndChildren = contributor.withChildren(importPhase,
asContributors(imported));
result = new ConfigDataEnvironmentContributors(this.logger, this.bootstrapContext,
......@@ -127,6 +127,16 @@ class ConfigDataEnvironmentContributors implements Iterable<ConfigDataEnvironmen
}
}
private CharSequence getImportedMessage(Set<ConfigDataResolutionResult> results) {
if (results.isEmpty()) {
return "Nothing imported";
}
StringBuilder message = new StringBuilder();
message.append("Imported " + results.size() + " resource" + ((results.size() != 1) ? "s " : " "));
message.append(results.stream().map(ConfigDataResolutionResult::getResource).collect(Collectors.toList()));
return message;
}
protected final ConfigurableBootstrapContext getBootstrapContext() {
return this.bootstrapContext;
}
......@@ -147,11 +157,14 @@ class ConfigDataEnvironmentContributors implements Iterable<ConfigDataEnvironmen
return contributor.isActive(activationContext) && contributor.hasUnprocessedImports(importPhase);
}
private List<ConfigDataEnvironmentContributor> asContributors(Map<ConfigDataResource, ConfigData> imported) {
private List<ConfigDataEnvironmentContributor> asContributors(
Map<ConfigDataResolutionResult, ConfigData> imported) {
List<ConfigDataEnvironmentContributor> contributors = new ArrayList<>(imported.size() * 5);
imported.forEach((location, data) -> {
imported.forEach((resolutionResult, data) -> {
for (int i = data.getPropertySources().size() - 1; i >= 0; i--) {
contributors.add(ConfigDataEnvironmentContributor.ofUnboundImport(location, data, i));
ConfigDataLocation location = resolutionResult.getLocation();
ConfigDataResource resource = resolutionResult.getResource();
contributors.add(ConfigDataEnvironmentContributor.ofUnboundImport(location, resource, data, i));
}
});
return Collections.unmodifiableList(contributors);
......
......@@ -73,7 +73,7 @@ class ConfigDataImporter {
* @param locations the locations to resolve
* @return a map of the loaded locations and data
*/
Map<ConfigDataResource, ConfigData> resolveAndLoad(ConfigDataActivationContext activationContext,
Map<ConfigDataResolutionResult, ConfigData> resolveAndLoad(ConfigDataActivationContext activationContext,
ConfigDataLocationResolverContext locationResolverContext, ConfigDataLoaderContext loaderContext,
List<ConfigDataLocation> locations) {
try {
......@@ -106,9 +106,9 @@ class ConfigDataImporter {
}
}
private Map<ConfigDataResource, ConfigData> load(ConfigDataLoaderContext loaderContext,
private Map<ConfigDataResolutionResult, ConfigData> load(ConfigDataLoaderContext loaderContext,
List<ConfigDataResolutionResult> candidates) throws IOException {
Map<ConfigDataResource, ConfigData> result = new LinkedHashMap<>();
Map<ConfigDataResolutionResult, ConfigData> result = new LinkedHashMap<>();
for (int i = candidates.size() - 1; i >= 0; i--) {
ConfigDataResolutionResult candidate = candidates.get(i);
ConfigDataLocation location = candidate.getLocation();
......@@ -117,7 +117,7 @@ class ConfigDataImporter {
try {
ConfigData loaded = this.loaders.load(loaderContext, resource);
if (loaded != null) {
result.put(resource, loaded);
result.put(candidate, loaded);
}
}
catch (ConfigDataNotFoundException ex) {
......
......@@ -31,6 +31,7 @@ import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.env.PropertySourceLoader;
import org.springframework.core.Ordered;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.SpringFactoriesLoader;
......@@ -234,8 +235,10 @@ public class StandardConfigDataLocationResolver
private void assertDirectoryExists(StandardConfigDataReference reference) {
Resource resource = this.resourceLoader.getResource(reference.getDirectory());
StandardConfigDataResource configDataResource = new StandardConfigDataResource(reference, resource);
ConfigDataResourceNotFoundException.throwIfDoesNotExist(configDataResource, resource);
if (!(resource instanceof ClassPathResource)) {
StandardConfigDataResource configDataResource = new StandardConfigDataResource(reference, resource);
ConfigDataResourceNotFoundException.throwIfDoesNotExist(configDataResource, resource);
}
}
private List<StandardConfigDataResource> resolve(StandardConfigDataReference reference) {
......
......@@ -122,7 +122,7 @@ class ConfigDataEnvironmentContributorPlaceholdersResolverTests {
private final boolean active;
protected TestConfigDataEnvironmentContributor(PropertySource<?> propertySource, boolean active) {
super(Kind.ROOT, null, propertySource, null, null, false, null);
super(Kind.ROOT, null, null, propertySource, null, null, false, null);
this.active = active;
}
......
......@@ -83,8 +83,8 @@ class ConfigDataEnvironmentContributorTests {
void getLocationReturnsLocation() {
ConfigData configData = new ConfigData(Collections.singleton(new MockPropertySource()));
ConfigDataResource resource = mock(ConfigDataResource.class);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(resource,
configData, 0);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(TEST_LOCATION,
resource, configData, 0);
assertThat(contributor.getResource()).isSameAs(resource);
}
......@@ -100,7 +100,7 @@ class ConfigDataEnvironmentContributorTests {
MockPropertySource propertySource = new MockPropertySource();
propertySource.setProperty("spring", "boot");
ConfigData configData = new ConfigData(Collections.singleton(propertySource));
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(null,
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(null, null,
configData, 0);
assertThat(contributor.getConfigurationPropertySource()
.getConfigurationProperty(ConfigurationPropertyName.of("spring")).getValue()).isEqualTo("boot");
......@@ -279,14 +279,14 @@ class ConfigDataEnvironmentContributorTests {
@Test
void ofUnboundImportCreatesImportedContributor() {
TestResource location = new TestResource("test");
TestResource resource = new TestResource("test");
MockPropertySource propertySource = new MockPropertySource();
propertySource.setProperty("spring.config.import", "test");
ConfigData configData = new ConfigData(Collections.singleton(propertySource));
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(location,
configData, 0);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(TEST_LOCATION,
resource, configData, 0);
assertThat(contributor.getKind()).isEqualTo(Kind.UNBOUND_IMPORT);
assertThat(contributor.getResource()).isSameAs(location);
assertThat(contributor.getResource()).isSameAs(resource);
assertThat(contributor.getImports()).isEmpty();
assertThat(contributor.isActive(this.activationContext)).isTrue();
assertThat(contributor.getPropertySource()).isEqualTo(propertySource);
......@@ -296,13 +296,13 @@ class ConfigDataEnvironmentContributorTests {
@Test
void bindCreatesImportedContributor() {
TestResource location = new TestResource("test");
TestResource resource = new TestResource("test");
MockPropertySource propertySource = new MockPropertySource();
propertySource.setProperty("spring.config.import", "test");
ConfigData configData = new ConfigData(Collections.singleton(propertySource));
ConfigDataEnvironmentContributor contributor = createBoundContributor(location, configData, 0);
ConfigDataEnvironmentContributor contributor = createBoundContributor(resource, configData, 0);
assertThat(contributor.getKind()).isEqualTo(Kind.BOUND_IMPORT);
assertThat(contributor.getResource()).isSameAs(location);
assertThat(contributor.getResource()).isSameAs(resource);
assertThat(contributor.getImports()).containsExactly(TEST_LOCATION);
assertThat(contributor.isActive(this.activationContext)).isTrue();
assertThat(contributor.getPropertySource()).isEqualTo(propertySource);
......@@ -312,13 +312,13 @@ class ConfigDataEnvironmentContributorTests {
@Test
void bindWhenConfigDataHasIgnoreImportsOptionsCreatesImportedContributorWithoutImports() {
TestResource location = new TestResource("test");
TestResource resource = new TestResource("test");
MockPropertySource propertySource = new MockPropertySource();
propertySource.setProperty("spring.config.import", "test");
ConfigData configData = new ConfigData(Collections.singleton(propertySource), ConfigData.Option.IGNORE_IMPORTS);
ConfigDataEnvironmentContributor contributor = createBoundContributor(location, configData, 0);
ConfigDataEnvironmentContributor contributor = createBoundContributor(resource, configData, 0);
assertThat(contributor.getKind()).isEqualTo(Kind.BOUND_IMPORT);
assertThat(contributor.getResource()).isSameAs(location);
assertThat(contributor.getResource()).isSameAs(resource);
assertThat(contributor.getImports()).isEmpty();
assertThat(contributor.isActive(this.activationContext)).isTrue();
assertThat(contributor.getPropertySource()).isEqualTo(propertySource);
......@@ -341,8 +341,8 @@ class ConfigDataEnvironmentContributorTests {
private ConfigDataEnvironmentContributor createBoundContributor(ConfigDataResource resource, ConfigData configData,
int propertySourceIndex) {
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(resource,
configData, propertySourceIndex);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(TEST_LOCATION,
resource, configData, propertySourceIndex);
Binder binder = new Binder(contributor.getConfigurationPropertySource());
return contributor.withBoundProperties(binder);
}
......
......@@ -116,8 +116,9 @@ class ConfigDataEnvironmentContributorsTests {
this.importer = mock(ConfigDataImporter.class);
List<ConfigDataLocation> locations = Arrays.asList(LOCATION_1);
MockPropertySource propertySource = new MockPropertySource();
Map<ConfigDataResource, ConfigData> imported = new LinkedHashMap<>();
imported.put(new TestConfigDataResource("a"), new ConfigData(Arrays.asList(propertySource)));
Map<ConfigDataResolutionResult, ConfigData> imported = new LinkedHashMap<>();
imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a")),
new ConfigData(Arrays.asList(propertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations)))
.willReturn(imported);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1);
......@@ -138,14 +139,16 @@ class ConfigDataEnvironmentContributorsTests {
List<ConfigDataLocation> initialLocations = Arrays.asList(LOCATION_1);
MockPropertySource initialPropertySource = new MockPropertySource();
initialPropertySource.setProperty("spring.config.import", "location2");
Map<ConfigDataResource, ConfigData> initialImported = new LinkedHashMap<>();
initialImported.put(new TestConfigDataResource("a"), new ConfigData(Arrays.asList(initialPropertySource)));
Map<ConfigDataResolutionResult, ConfigData> initialImported = new LinkedHashMap<>();
initialImported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a")),
new ConfigData(Arrays.asList(initialPropertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(initialLocations)))
.willReturn(initialImported);
List<ConfigDataLocation> secondLocations = Arrays.asList(LOCATION_2);
MockPropertySource secondPropertySource = new MockPropertySource();
Map<ConfigDataResource, ConfigData> secondImported = new LinkedHashMap<>();
secondImported.put(new TestConfigDataResource("b"), new ConfigData(Arrays.asList(secondPropertySource)));
Map<ConfigDataResolutionResult, ConfigData> secondImported = new LinkedHashMap<>();
secondImported.put(new ConfigDataResolutionResult(LOCATION_2, new TestConfigDataResource("b")),
new ConfigData(Arrays.asList(secondPropertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(secondLocations)))
.willReturn(secondImported);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1);
......@@ -170,8 +173,9 @@ class ConfigDataEnvironmentContributorsTests {
this.importer = mock(ConfigDataImporter.class);
List<ConfigDataLocation> locations = Arrays.asList(LOCATION_1);
MockPropertySource propertySource = new MockPropertySource();
Map<ConfigDataResource, ConfigData> imported = new LinkedHashMap<>();
imported.put(new TestConfigDataResource("a'"), new ConfigData(Arrays.asList(propertySource)));
Map<ConfigDataResolutionResult, ConfigData> imported = new LinkedHashMap<>();
imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a'")),
new ConfigData(Arrays.asList(propertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations)))
.willReturn(imported);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1);
......@@ -189,14 +193,16 @@ class ConfigDataEnvironmentContributorsTests {
List<ConfigDataLocation> initialLocations = Arrays.asList(LOCATION_1);
MockPropertySource initialPropertySource = new MockPropertySource();
initialPropertySource.setProperty("spring.config.import", "location2");
Map<ConfigDataResource, ConfigData> initialImported = new LinkedHashMap<>();
initialImported.put(new TestConfigDataResource("a"), new ConfigData(Arrays.asList(initialPropertySource)));
Map<ConfigDataResolutionResult, ConfigData> initialImported = new LinkedHashMap<>();
initialImported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a")),
new ConfigData(Arrays.asList(initialPropertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(initialLocations)))
.willReturn(initialImported);
List<ConfigDataLocation> secondLocations = Arrays.asList(LOCATION_2);
MockPropertySource secondPropertySource = new MockPropertySource();
Map<ConfigDataResource, ConfigData> secondImported = new LinkedHashMap<>();
secondImported.put(new TestConfigDataResource("b"), new ConfigData(Arrays.asList(secondPropertySource)));
Map<ConfigDataResolutionResult, ConfigData> secondImported = new LinkedHashMap<>();
secondImported.put(new ConfigDataResolutionResult(LOCATION_2, new TestConfigDataResource("b")),
new ConfigData(Arrays.asList(secondPropertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(secondLocations)))
.willReturn(secondImported);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1);
......@@ -217,8 +223,9 @@ class ConfigDataEnvironmentContributorsTests {
this.importer = mock(ConfigDataImporter.class);
List<ConfigDataLocation> locations = Arrays.asList(LOCATION_1);
MockPropertySource propertySource = new MockPropertySource();
Map<ConfigDataResource, ConfigData> imported = new LinkedHashMap<>();
imported.put(new TestConfigDataResource("a'"), new ConfigData(Arrays.asList(propertySource)));
Map<ConfigDataResolutionResult, ConfigData> imported = new LinkedHashMap<>();
imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a'")),
new ConfigData(Arrays.asList(propertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations)))
.willReturn(imported);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1);
......@@ -239,8 +246,9 @@ class ConfigDataEnvironmentContributorsTests {
this.importer = mock(ConfigDataImporter.class);
List<ConfigDataLocation> locations = Arrays.asList(LOCATION_1);
MockPropertySource propertySource = new MockPropertySource();
Map<ConfigDataResource, ConfigData> imported = new LinkedHashMap<>();
imported.put(new TestConfigDataResource("a'"), new ConfigData(Arrays.asList(propertySource)));
Map<ConfigDataResolutionResult, ConfigData> imported = new LinkedHashMap<>();
imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a'")),
new ConfigData(Arrays.asList(propertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations)))
.willReturn(imported);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1);
......@@ -377,7 +385,7 @@ class ConfigDataEnvironmentContributorsTests {
private ConfigDataEnvironmentContributor createBoundImportContributor(ConfigData configData,
int propertySourceIndex) {
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(null,
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(null, null,
configData, propertySourceIndex);
Binder binder = new Binder(contributor.getConfigurationPropertySource());
return contributor.withBoundProperties(binder);
......
......@@ -33,6 +33,7 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
......@@ -55,6 +56,7 @@ import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.StringUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
......@@ -70,6 +72,9 @@ class ConfigDataEnvironmentPostProcessorIntegrationTests {
private SpringApplication application;
@TempDir
public File temp;
@BeforeEach
void setup() {
this.application = new SpringApplication(Config.class);
......@@ -516,9 +521,16 @@ class ConfigDataEnvironmentPostProcessorIntegrationTests {
}
@Test
void runWhenConfigLocationHasNonOptionalMissingDirectoryThrowsException() {
void runWhenConfigLocationHasNonOptionalMissingFileDirectoryThrowsResourceNotFoundException() {
File location = new File(this.temp, "application.unknown");
assertThatExceptionOfType(ConfigDataResourceNotFoundException.class).isThrownBy(() -> this.application
.run("--spring.config.location=" + StringUtils.cleanPath(location.getAbsolutePath()) + "/"));
}
@Test
void runWhenConfigLocationHasNonOptionalMissingClasspathDirectoryThrowsLocationNotFoundException() {
String location = "classpath:application.unknown/";
assertThatExceptionOfType(ConfigDataResourceNotFoundException.class)
assertThatExceptionOfType(ConfigDataLocationNotFoundException.class)
.isThrownBy(() -> this.application.run("--spring.config.location=" + location));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment