Allow placeholders to be used in imports
Allow `${..}` property placeholders to be used in `spring.config.import` properties. Prior to this commit, placeholders were not resolved when binding the `ConfigDataProperty` instance. Furthermore, binding happened too early for all placeholders to be resolved correctly. The `ConfigDataEnvironmentContributor` class now has two states for imported contributors, `UNBOUND_IMPORT` has the initial unbound state and is eventually replaced with a `BOUND_IMPORT`. Closes gh-23020
This commit is contained in:
parent
00cb5bbd86
commit
758df17c7d
|
@ -235,7 +235,7 @@ class ConfigDataEnvironment {
|
|||
MutablePropertySources propertySources = this.environment.getPropertySources();
|
||||
this.logger.trace("Applying config data environment contributions");
|
||||
for (ConfigDataEnvironmentContributor contributor : contributors) {
|
||||
if (contributor.getKind() == ConfigDataEnvironmentContributor.Kind.IMPORTED
|
||||
if (contributor.getKind() == ConfigDataEnvironmentContributor.Kind.BOUND_IMPORT
|
||||
&& contributor.getPropertySource() != null) {
|
||||
if (!contributor.isActive(activationContext)) {
|
||||
this.logger.trace(LogMessage.format("Skipping inactive property source '%s'",
|
||||
|
|
|
@ -59,6 +59,8 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
|
|||
|
||||
private final ConfigDataProperties properties;
|
||||
|
||||
private final boolean ignoreImports;
|
||||
|
||||
private final Map<ImportPhase, List<ConfigDataEnvironmentContributor>> children;
|
||||
|
||||
private final Kind kind;
|
||||
|
@ -71,16 +73,18 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
|
|||
* @param configurationPropertySource the configuration property source for the data
|
||||
* or {@code null}
|
||||
* @param properties the config data properties or {@code null}
|
||||
* @param ignoreImports if import properties should be ignored
|
||||
* @param children the children of this contributor at each {@link ImportPhase}
|
||||
*/
|
||||
ConfigDataEnvironmentContributor(Kind kind, ConfigDataLocation location, PropertySource<?> propertySource,
|
||||
ConfigurationPropertySource configurationPropertySource, ConfigDataProperties properties,
|
||||
Map<ImportPhase, List<ConfigDataEnvironmentContributor>> children) {
|
||||
boolean ignoreImports, Map<ImportPhase, List<ConfigDataEnvironmentContributor>> children) {
|
||||
this.kind = kind;
|
||||
this.location = location;
|
||||
this.properties = properties;
|
||||
this.propertySource = propertySource;
|
||||
this.configurationPropertySource = configurationPropertySource;
|
||||
this.ignoreImports = ignoreImports;
|
||||
this.children = (children != null) ? children : Collections.emptyMap();
|
||||
}
|
||||
|
||||
|
@ -175,6 +179,16 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
|
|||
return new ContributorIterator();
|
||||
}
|
||||
|
||||
ConfigDataEnvironmentContributor withBoundProperties(Binder binder) {
|
||||
UseLegacyConfigProcessingException.throwIfRequested(binder);
|
||||
ConfigDataProperties properties = ConfigDataProperties.get(binder);
|
||||
if (this.ignoreImports) {
|
||||
properties = properties.withoutImports();
|
||||
}
|
||||
return new ConfigDataEnvironmentContributor(Kind.BOUND_IMPORT, this.location, this.propertySource,
|
||||
this.configurationPropertySource, properties, this.ignoreImports, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link ConfigDataEnvironmentContributor} instance with a new set of
|
||||
* children for the given phase.
|
||||
|
@ -187,7 +201,7 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
|
|||
Map<ImportPhase, List<ConfigDataEnvironmentContributor>> updatedChildren = new LinkedHashMap<>(this.children);
|
||||
updatedChildren.put(importPhase, children);
|
||||
return new ConfigDataEnvironmentContributor(this.kind, this.location, this.propertySource,
|
||||
this.configurationPropertySource, this.properties, updatedChildren);
|
||||
this.configurationPropertySource, this.properties, this.ignoreImports, updatedChildren);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -212,7 +226,7 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
|
|||
updatedChildren.put(importPhase, Collections.unmodifiableList(updatedContributors));
|
||||
});
|
||||
return new ConfigDataEnvironmentContributor(this.kind, this.location, this.propertySource,
|
||||
this.configurationPropertySource, this.properties, updatedChildren);
|
||||
this.configurationPropertySource, this.properties, this.ignoreImports, updatedChildren);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -223,20 +237,20 @@ 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, children);
|
||||
return new ConfigDataEnvironmentContributor(Kind.ROOT, null, null, null, null, false, children);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a {@link Kind#INITIAL_IMPORT initial import} contributor.
|
||||
* This contributor is used to trigger initial imports of additional contributors. It
|
||||
* does not contribute any properties itself.
|
||||
* @param importLocation the initial import location
|
||||
* @param importLocation the initial import location (with placeholder resolved)
|
||||
* @return a new {@link ConfigDataEnvironmentContributor} instance
|
||||
*/
|
||||
static ConfigDataEnvironmentContributor ofInitialImport(String importLocation) {
|
||||
List<String> imports = Collections.singletonList(importLocation);
|
||||
ConfigDataProperties properties = new ConfigDataProperties(imports, null);
|
||||
return new ConfigDataEnvironmentContributor(Kind.INITIAL_IMPORT, null, null, null, properties, null);
|
||||
return new ConfigDataEnvironmentContributor(Kind.INITIAL_IMPORT, null, null, null, properties, false, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -248,31 +262,25 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
|
|||
*/
|
||||
static ConfigDataEnvironmentContributor ofExisting(PropertySource<?> propertySource) {
|
||||
return new ConfigDataEnvironmentContributor(Kind.EXISTING, null, propertySource,
|
||||
ConfigurationPropertySource.from(propertySource), null, null);
|
||||
ConfigurationPropertySource.from(propertySource), null, false, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a {@link Kind#IMPORTED imported} contributor. This
|
||||
* contributor has been actively imported from another contributor and may itself
|
||||
* 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 location the location of imported config data
|
||||
* @param configData the config data
|
||||
* @param propertySourceIndex the index of the property source that should be used
|
||||
* @param activationContext the current activation context
|
||||
* @return a new {@link ConfigDataEnvironmentContributor} instance
|
||||
*/
|
||||
static ConfigDataEnvironmentContributor ofImported(ConfigDataLocation location, ConfigData configData,
|
||||
int propertySourceIndex, ConfigDataActivationContext activationContext) {
|
||||
static ConfigDataEnvironmentContributor ofUnboundImport(ConfigDataLocation location, ConfigData configData,
|
||||
int propertySourceIndex) {
|
||||
PropertySource<?> propertySource = configData.getPropertySources().get(propertySourceIndex);
|
||||
ConfigurationPropertySource configurationPropertySource = ConfigurationPropertySource.from(propertySource);
|
||||
Binder binder = new Binder(configurationPropertySource);
|
||||
UseLegacyConfigProcessingException.throwIfRequested(binder);
|
||||
ConfigDataProperties properties = ConfigDataProperties.get(binder);
|
||||
if (configData.getOptions().contains(ConfigData.Option.IGNORE_IMPORTS)) {
|
||||
properties = properties.withoutImports();
|
||||
}
|
||||
return new ConfigDataEnvironmentContributor(Kind.IMPORTED, location, propertySource,
|
||||
configurationPropertySource, properties, null);
|
||||
boolean ignoreImports = configData.getOptions().contains(ConfigData.Option.IGNORE_IMPORTS);
|
||||
return new ConfigDataEnvironmentContributor(Kind.UNBOUND_IMPORT, location, propertySource,
|
||||
configurationPropertySource, null, ignoreImports, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -296,9 +304,16 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
|
|||
EXISTING,
|
||||
|
||||
/**
|
||||
* A contributor with {@link ConfigData} imported from another contributor.
|
||||
* A contributor with {@link ConfigData} imported from another contributor but not
|
||||
* yet bound.
|
||||
*/
|
||||
IMPORTED;
|
||||
UNBOUND_IMPORT,
|
||||
|
||||
/**
|
||||
* A contributor with {@link ConfigData} imported from another contributor that
|
||||
* has been.
|
||||
*/
|
||||
BOUND_IMPORT;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import java.util.stream.Stream;
|
|||
import org.apache.commons.logging.Log;
|
||||
|
||||
import org.springframework.boot.context.config.ConfigDataEnvironmentContributor.ImportPhase;
|
||||
import org.springframework.boot.context.config.ConfigDataEnvironmentContributor.Kind;
|
||||
import org.springframework.boot.context.properties.bind.BindContext;
|
||||
import org.springframework.boot.context.properties.bind.BindHandler;
|
||||
import org.springframework.boot.context.properties.bind.Bindable;
|
||||
|
@ -91,27 +92,38 @@ class ConfigDataEnvironmentContributors implements Iterable<ConfigDataEnvironmen
|
|||
this.logger.trace(LogMessage.format("Processing imports for phase %s. %s", importPhase,
|
||||
(activationContext != null) ? activationContext : "no activation context"));
|
||||
ConfigDataEnvironmentContributors result = this;
|
||||
int processedCount = 0;
|
||||
int processed = 0;
|
||||
while (true) {
|
||||
ConfigDataEnvironmentContributor unprocessed = getFirstUnprocessed(result, activationContext, importPhase);
|
||||
if (unprocessed == null) {
|
||||
this.logger.trace(LogMessage.format("Processed imports for of %d contributors", processedCount));
|
||||
ConfigDataEnvironmentContributor contributor = getNextToProcess(result, activationContext, importPhase);
|
||||
if (contributor == null) {
|
||||
this.logger.trace(LogMessage.format("Processed imports for of %d contributors", processed));
|
||||
return result;
|
||||
}
|
||||
if (contributor.getKind() == Kind.UNBOUND_IMPORT) {
|
||||
Iterable<ConfigurationPropertySource> sources = Collections
|
||||
.singleton(contributor.getConfigurationPropertySource());
|
||||
PlaceholdersResolver placeholdersResolver = new ConfigDataEnvironmentContributorPlaceholdersResolver(
|
||||
result, activationContext, true);
|
||||
Binder binder = new Binder(sources, placeholdersResolver, null, null, null);
|
||||
ConfigDataEnvironmentContributor bound = contributor.withBoundProperties(binder);
|
||||
result = new ConfigDataEnvironmentContributors(this.logger, this.bootstrapRegistry,
|
||||
result.getRoot().withReplacement(contributor, bound));
|
||||
continue;
|
||||
}
|
||||
ConfigDataLocationResolverContext locationResolverContext = new ContributorConfigDataLocationResolverContext(
|
||||
result, unprocessed, activationContext);
|
||||
result, contributor, activationContext);
|
||||
ConfigDataLoaderContext loaderContext = new ContributorDataLoaderContext(this);
|
||||
List<String> imports = unprocessed.getImports();
|
||||
List<String> imports = contributor.getImports();
|
||||
this.logger.trace(LogMessage.format("Processing imports %s", imports));
|
||||
Map<ConfigDataLocation, ConfigData> imported = importer.resolveAndLoad(activationContext,
|
||||
locationResolverContext, loaderContext, imports);
|
||||
this.logger.trace(LogMessage.of(() -> imported.isEmpty() ? "Nothing imported" : "Imported "
|
||||
+ imported.size() + " location " + ((imported.size() != 1) ? "s" : "") + imported.keySet()));
|
||||
ConfigDataEnvironmentContributor processed = unprocessed.withChildren(importPhase,
|
||||
asContributors(activationContext, imported));
|
||||
ConfigDataEnvironmentContributor contributorAndChildren = contributor.withChildren(importPhase,
|
||||
asContributors(imported));
|
||||
result = new ConfigDataEnvironmentContributors(this.logger, this.bootstrapRegistry,
|
||||
result.getRoot().withReplacement(unprocessed, processed));
|
||||
processedCount++;
|
||||
result.getRoot().withReplacement(contributor, contributorAndChildren));
|
||||
processed++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,22 +131,27 @@ class ConfigDataEnvironmentContributors implements Iterable<ConfigDataEnvironmen
|
|||
return this.bootstrapRegistry;
|
||||
}
|
||||
|
||||
private ConfigDataEnvironmentContributor getFirstUnprocessed(ConfigDataEnvironmentContributors contributors,
|
||||
private ConfigDataEnvironmentContributor getNextToProcess(ConfigDataEnvironmentContributors contributors,
|
||||
ConfigDataActivationContext activationContext, ImportPhase importPhase) {
|
||||
for (ConfigDataEnvironmentContributor contributor : contributors.getRoot()) {
|
||||
if (contributor.isActive(activationContext) && contributor.hasUnprocessedImports(importPhase)) {
|
||||
if (contributor.getKind() == Kind.UNBOUND_IMPORT
|
||||
|| isActiveWithUnprocessedImports(activationContext, importPhase, contributor)) {
|
||||
return contributor;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<ConfigDataEnvironmentContributor> asContributors(ConfigDataActivationContext activationContext,
|
||||
Map<ConfigDataLocation, ConfigData> imported) {
|
||||
private boolean isActiveWithUnprocessedImports(ConfigDataActivationContext activationContext,
|
||||
ImportPhase importPhase, ConfigDataEnvironmentContributor contributor) {
|
||||
return contributor.isActive(activationContext) && contributor.hasUnprocessedImports(importPhase);
|
||||
}
|
||||
|
||||
private List<ConfigDataEnvironmentContributor> asContributors(Map<ConfigDataLocation, ConfigData> imported) {
|
||||
List<ConfigDataEnvironmentContributor> contributors = new ArrayList<>(imported.size() * 5);
|
||||
imported.forEach((location, data) -> {
|
||||
for (int i = data.getPropertySources().size() - 1; i >= 0; i--) {
|
||||
contributors.add(ConfigDataEnvironmentContributor.ofImported(location, data, i, activationContext));
|
||||
contributors.add(ConfigDataEnvironmentContributor.ofUnboundImport(location, data, i));
|
||||
}
|
||||
});
|
||||
return Collections.unmodifiableList(contributors);
|
||||
|
@ -155,14 +172,18 @@ class ConfigDataEnvironmentContributors implements Iterable<ConfigDataEnvironmen
|
|||
* @return a binder instance
|
||||
*/
|
||||
Binder getBinder(ConfigDataActivationContext activationContext, BinderOption... options) {
|
||||
return getBinder(activationContext, ObjectUtils.isEmpty(options) ? EnumSet.noneOf(BinderOption.class)
|
||||
: EnumSet.copyOf(Arrays.asList(options)));
|
||||
return getBinder(activationContext, asBinderOptionsSet(options));
|
||||
}
|
||||
|
||||
private Set<BinderOption> asBinderOptionsSet(BinderOption... options) {
|
||||
return ObjectUtils.isEmpty(options) ? EnumSet.noneOf(BinderOption.class)
|
||||
: EnumSet.copyOf(Arrays.asList(options));
|
||||
}
|
||||
|
||||
private Binder getBinder(ConfigDataActivationContext activationContext, Set<BinderOption> options) {
|
||||
boolean failOnInactiveSource = options.contains(BinderOption.FAIL_ON_BIND_TO_INACTIVE_SOURCE);
|
||||
Iterable<ConfigurationPropertySource> sources = () -> getBinderSources(activationContext,
|
||||
!failOnInactiveSource);
|
||||
!options.contains(BinderOption.FAIL_ON_BIND_TO_INACTIVE_SOURCE));
|
||||
PlaceholdersResolver placeholdersResolver = new ConfigDataEnvironmentContributorPlaceholdersResolver(this.root,
|
||||
activationContext, failOnInactiveSource);
|
||||
BindHandler bindHandler = !failOnInactiveSource ? null : new InactiveSourceChecker(activationContext);
|
||||
|
|
|
@ -122,7 +122,7 @@ class ConfigDataEnvironmentContributorPlaceholdersResolverTests {
|
|||
private final boolean active;
|
||||
|
||||
protected TestConfigDataEnvironmentContributor(PropertySource<?> propertySource, boolean active) {
|
||||
super(Kind.ROOT, null, propertySource, null, null, null);
|
||||
super(Kind.ROOT, null, propertySource, null, null, false, null);
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.junit.jupiter.api.Test;
|
|||
import org.springframework.boot.cloud.CloudPlatform;
|
||||
import org.springframework.boot.context.config.ConfigDataEnvironmentContributor.ImportPhase;
|
||||
import org.springframework.boot.context.config.ConfigDataEnvironmentContributor.Kind;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
|
||||
import org.springframework.mock.env.MockPropertySource;
|
||||
|
||||
|
@ -63,8 +64,7 @@ class ConfigDataEnvironmentContributorTests {
|
|||
MockPropertySource propertySource = new MockPropertySource();
|
||||
propertySource.setProperty("spring.config.activate.on-cloud-platform", "kubernetes");
|
||||
ConfigData configData = new ConfigData(Collections.singleton(propertySource));
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofImported(null, configData, 0,
|
||||
this.activationContext);
|
||||
ConfigDataEnvironmentContributor contributor = createBoundContributor(null, configData, 0);
|
||||
assertThat(contributor.isActive(this.activationContext)).isTrue();
|
||||
}
|
||||
|
||||
|
@ -73,8 +73,7 @@ class ConfigDataEnvironmentContributorTests {
|
|||
MockPropertySource propertySource = new MockPropertySource();
|
||||
propertySource.setProperty("spring.config.activate.on-cloud-platform", "heroku");
|
||||
ConfigData configData = new ConfigData(Collections.singleton(propertySource));
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofImported(null, configData, 0,
|
||||
this.activationContext);
|
||||
ConfigDataEnvironmentContributor contributor = createBoundContributor(null, configData, 0);
|
||||
assertThat(contributor.isActive(this.activationContext)).isFalse();
|
||||
}
|
||||
|
||||
|
@ -82,8 +81,8 @@ class ConfigDataEnvironmentContributorTests {
|
|||
void getLocationReturnsLocation() {
|
||||
ConfigData configData = new ConfigData(Collections.singleton(new MockPropertySource()));
|
||||
ConfigDataLocation location = mock(ConfigDataLocation.class);
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofImported(location, configData,
|
||||
0, this.activationContext);
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(location,
|
||||
configData, 0);
|
||||
assertThat(contributor.getLocation()).isSameAs(location);
|
||||
}
|
||||
|
||||
|
@ -99,8 +98,8 @@ class ConfigDataEnvironmentContributorTests {
|
|||
MockPropertySource propertySource = new MockPropertySource();
|
||||
propertySource.setProperty("spring", "boot");
|
||||
ConfigData configData = new ConfigData(Collections.singleton(propertySource));
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofImported(null, configData, 0,
|
||||
this.activationContext);
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(null,
|
||||
configData, 0);
|
||||
assertThat(contributor.getConfigurationPropertySource()
|
||||
.getConfigurationProperty(ConfigurationPropertyName.of("spring")).getValue()).isEqualTo("boot");
|
||||
}
|
||||
|
@ -108,8 +107,7 @@ class ConfigDataEnvironmentContributorTests {
|
|||
@Test
|
||||
void getImportsWhenPropertiesIsNullReturnsEmptyList() {
|
||||
ConfigData configData = new ConfigData(Collections.singleton(new MockPropertySource()));
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofImported(null, configData, 0,
|
||||
this.activationContext);
|
||||
ConfigDataEnvironmentContributor contributor = createBoundContributor(null, configData, 0);
|
||||
assertThat(contributor.getImports()).isEmpty();
|
||||
}
|
||||
|
||||
|
@ -118,16 +116,14 @@ class ConfigDataEnvironmentContributorTests {
|
|||
MockPropertySource propertySource = new MockPropertySource();
|
||||
propertySource.setProperty("spring.config.import", "spring,boot");
|
||||
ConfigData configData = new ConfigData(Collections.singleton(propertySource));
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofImported(null, configData, 0,
|
||||
this.activationContext);
|
||||
ConfigDataEnvironmentContributor contributor = createBoundContributor(null, configData, 0);
|
||||
assertThat(contributor.getImports()).containsExactly("spring", "boot");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasUnprocessedImportsWhenNoImportsReturnsFalse() {
|
||||
ConfigData configData = new ConfigData(Collections.singleton(new MockPropertySource()));
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofImported(null, configData, 0,
|
||||
this.activationContext);
|
||||
ConfigDataEnvironmentContributor contributor = createBoundContributor(null, configData, 0);
|
||||
assertThat(contributor.hasUnprocessedImports(ImportPhase.BEFORE_PROFILE_ACTIVATION)).isFalse();
|
||||
}
|
||||
|
||||
|
@ -136,8 +132,7 @@ class ConfigDataEnvironmentContributorTests {
|
|||
MockPropertySource propertySource = new MockPropertySource();
|
||||
propertySource.setProperty("spring.config.import", "springboot");
|
||||
ConfigData configData = new ConfigData(Collections.singleton(propertySource));
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofImported(null, configData, 0,
|
||||
this.activationContext);
|
||||
ConfigDataEnvironmentContributor contributor = createBoundContributor(null, configData, 0);
|
||||
assertThat(contributor.hasUnprocessedImports(ImportPhase.BEFORE_PROFILE_ACTIVATION)).isTrue();
|
||||
}
|
||||
|
||||
|
@ -146,11 +141,9 @@ class ConfigDataEnvironmentContributorTests {
|
|||
MockPropertySource propertySource = new MockPropertySource();
|
||||
propertySource.setProperty("spring.config.import", "springboot");
|
||||
ConfigData configData = new ConfigData(Collections.singleton(propertySource));
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofImported(null, configData, 0,
|
||||
this.activationContext);
|
||||
ConfigDataEnvironmentContributor contributor = createBoundContributor(null, configData, 0);
|
||||
ConfigData childConfigData = new ConfigData(Collections.singleton(new MockPropertySource()));
|
||||
ConfigDataEnvironmentContributor childContributor = ConfigDataEnvironmentContributor.ofImported(null,
|
||||
childConfigData, 0, this.activationContext);
|
||||
ConfigDataEnvironmentContributor childContributor = createBoundContributor(null, childConfigData, 0);
|
||||
ConfigDataEnvironmentContributor withChildren = contributor.withChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION,
|
||||
Collections.singletonList(childContributor));
|
||||
assertThat(withChildren.hasUnprocessedImports(ImportPhase.BEFORE_PROFILE_ACTIVATION)).isFalse();
|
||||
|
@ -160,8 +153,7 @@ class ConfigDataEnvironmentContributorTests {
|
|||
@Test
|
||||
void getChildrenWhenHasNoChildrenReturnsEmptyList() {
|
||||
ConfigData configData = new ConfigData(Collections.singleton(new MockPropertySource()));
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofImported(null, configData, 0,
|
||||
this.activationContext);
|
||||
ConfigDataEnvironmentContributor contributor = createBoundContributor(null, configData, 0);
|
||||
assertThat(contributor.getChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION)).isEmpty();
|
||||
assertThat(contributor.getChildren(ImportPhase.AFTER_PROFILE_ACTIVATION)).isEmpty();
|
||||
}
|
||||
|
@ -171,11 +163,9 @@ class ConfigDataEnvironmentContributorTests {
|
|||
MockPropertySource propertySource = new MockPropertySource();
|
||||
propertySource.setProperty("spring.config.import", "springboot");
|
||||
ConfigData configData = new ConfigData(Collections.singleton(propertySource));
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofImported(null, configData, 0,
|
||||
this.activationContext);
|
||||
ConfigDataEnvironmentContributor contributor = createBoundContributor(null, configData, 0);
|
||||
ConfigData childConfigData = new ConfigData(Collections.singleton(new MockPropertySource()));
|
||||
ConfigDataEnvironmentContributor childContributor = ConfigDataEnvironmentContributor.ofImported(null,
|
||||
childConfigData, 0, this.activationContext);
|
||||
ConfigDataEnvironmentContributor childContributor = createBoundContributor(null, childConfigData, 0);
|
||||
ConfigDataEnvironmentContributor withChildren = contributor.withChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION,
|
||||
Collections.singletonList(childContributor));
|
||||
assertThat(withChildren.getChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION)).containsExactly(childContributor);
|
||||
|
@ -184,35 +174,36 @@ class ConfigDataEnvironmentContributorTests {
|
|||
|
||||
@Test
|
||||
void streamReturnsStream() {
|
||||
ConfigDataEnvironmentContributor contributor = createContributor("a");
|
||||
ConfigDataEnvironmentContributor contributor = createBoundContributor("a");
|
||||
Stream<String> stream = contributor.stream().map(this::getLocationName);
|
||||
assertThat(stream).containsExactly("a");
|
||||
}
|
||||
|
||||
@Test
|
||||
void iteratorWhenSingleContributorReturnsSingletonIterator() {
|
||||
ConfigDataEnvironmentContributor contributor = createContributor("a");
|
||||
ConfigDataEnvironmentContributor contributor = createBoundContributor("a");
|
||||
assertThat(asLocationsList(contributor.iterator())).containsExactly("a");
|
||||
}
|
||||
|
||||
@Test
|
||||
void iteratorWhenTypicalStructureReturnsCorrectlyOrderedIterator() {
|
||||
ConfigDataEnvironmentContributor fileApplication = createContributor("file:application.properties");
|
||||
ConfigDataEnvironmentContributor fileProfile = createContributor("file:application-profile.properties");
|
||||
ConfigDataEnvironmentContributor fileImports = createContributor("file:./");
|
||||
ConfigDataEnvironmentContributor fileApplication = createBoundContributor("file:application.properties");
|
||||
ConfigDataEnvironmentContributor fileProfile = createBoundContributor("file:application-profile.properties");
|
||||
ConfigDataEnvironmentContributor fileImports = createBoundContributor("file:./");
|
||||
fileImports = fileImports.withChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION,
|
||||
Collections.singletonList(fileApplication));
|
||||
fileImports = fileImports.withChildren(ImportPhase.AFTER_PROFILE_ACTIVATION,
|
||||
Collections.singletonList(fileProfile));
|
||||
ConfigDataEnvironmentContributor classpathApplication = createContributor("classpath:application.properties");
|
||||
ConfigDataEnvironmentContributor classpathProfile = createContributor(
|
||||
ConfigDataEnvironmentContributor classpathApplication = createBoundContributor(
|
||||
"classpath:application.properties");
|
||||
ConfigDataEnvironmentContributor classpathProfile = createBoundContributor(
|
||||
"classpath:application-profile.properties");
|
||||
ConfigDataEnvironmentContributor classpathImports = createContributor("classpath:/");
|
||||
ConfigDataEnvironmentContributor classpathImports = createBoundContributor("classpath:/");
|
||||
classpathImports = classpathImports.withChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION,
|
||||
Arrays.asList(classpathApplication));
|
||||
classpathImports = classpathImports.withChildren(ImportPhase.AFTER_PROFILE_ACTIVATION,
|
||||
Arrays.asList(classpathProfile));
|
||||
ConfigDataEnvironmentContributor root = createContributor("root");
|
||||
ConfigDataEnvironmentContributor root = createBoundContributor("root");
|
||||
root = root.withChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION, Arrays.asList(fileImports, classpathImports));
|
||||
assertThat(asLocationsList(root.iterator())).containsExactly("file:application-profile.properties",
|
||||
"file:application.properties", "file:./", "classpath:application-profile.properties",
|
||||
|
@ -221,8 +212,8 @@ class ConfigDataEnvironmentContributorTests {
|
|||
|
||||
@Test
|
||||
void withChildrenReturnsNewInstanceWithChildren() {
|
||||
ConfigDataEnvironmentContributor root = createContributor("root");
|
||||
ConfigDataEnvironmentContributor child = createContributor("child");
|
||||
ConfigDataEnvironmentContributor root = createBoundContributor("root");
|
||||
ConfigDataEnvironmentContributor child = createBoundContributor("child");
|
||||
ConfigDataEnvironmentContributor withChildren = root.withChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION,
|
||||
Collections.singletonList(child));
|
||||
assertThat(root.getChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION)).isEmpty();
|
||||
|
@ -231,12 +222,12 @@ class ConfigDataEnvironmentContributorTests {
|
|||
|
||||
@Test
|
||||
void withReplacementReplacesChild() {
|
||||
ConfigDataEnvironmentContributor root = createContributor("root");
|
||||
ConfigDataEnvironmentContributor child = createContributor("child");
|
||||
ConfigDataEnvironmentContributor grandchild = createContributor("grandchild");
|
||||
ConfigDataEnvironmentContributor root = createBoundContributor("root");
|
||||
ConfigDataEnvironmentContributor child = createBoundContributor("child");
|
||||
ConfigDataEnvironmentContributor grandchild = createBoundContributor("grandchild");
|
||||
child = child.withChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION, Collections.singletonList(grandchild));
|
||||
root = root.withChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION, Collections.singletonList(child));
|
||||
ConfigDataEnvironmentContributor updated = createContributor("updated");
|
||||
ConfigDataEnvironmentContributor updated = createBoundContributor("updated");
|
||||
ConfigDataEnvironmentContributor withReplacement = root.withReplacement(grandchild, updated);
|
||||
assertThat(asLocationsList(root.iterator())).containsExactly("grandchild", "child", "root");
|
||||
assertThat(asLocationsList(withReplacement.iterator())).containsExactly("updated", "child", "root");
|
||||
|
@ -244,8 +235,8 @@ class ConfigDataEnvironmentContributorTests {
|
|||
|
||||
@Test
|
||||
void ofCreatesRootContributor() {
|
||||
ConfigDataEnvironmentContributor one = createContributor("one");
|
||||
ConfigDataEnvironmentContributor two = createContributor("two");
|
||||
ConfigDataEnvironmentContributor one = createBoundContributor("one");
|
||||
ConfigDataEnvironmentContributor two = createBoundContributor("two");
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.of(Arrays.asList(one, two));
|
||||
assertThat(contributor.getKind()).isEqualTo(Kind.ROOT);
|
||||
assertThat(contributor.getLocation()).isNull();
|
||||
|
@ -284,31 +275,14 @@ class ConfigDataEnvironmentContributorTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void ofImportedCreatesImportedContributor() {
|
||||
void ofUnboundImportCreatesImportedContributor() {
|
||||
TestLocation location = new TestLocation("test");
|
||||
MockPropertySource propertySource = new MockPropertySource();
|
||||
propertySource.setProperty("spring.config.import", "test");
|
||||
ConfigData configData = new ConfigData(Collections.singleton(propertySource));
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofImported(location, configData,
|
||||
0, this.activationContext);
|
||||
assertThat(contributor.getKind()).isEqualTo(Kind.IMPORTED);
|
||||
assertThat(contributor.getLocation()).isSameAs(location);
|
||||
assertThat(contributor.getImports()).containsExactly("test");
|
||||
assertThat(contributor.isActive(this.activationContext)).isTrue();
|
||||
assertThat(contributor.getPropertySource()).isEqualTo(propertySource);
|
||||
assertThat(contributor.getConfigurationPropertySource()).isNotNull();
|
||||
assertThat(contributor.getChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofImportedWhenConfigDataHasIgnoreImportsOptionsCreatesImportedContributorWithoutImports() {
|
||||
TestLocation location = new TestLocation("test");
|
||||
MockPropertySource propertySource = new MockPropertySource();
|
||||
propertySource.setProperty("spring.config.import", "test");
|
||||
ConfigData configData = new ConfigData(Collections.singleton(propertySource), ConfigData.Option.IGNORE_IMPORTS);
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofImported(location, configData,
|
||||
0, this.activationContext);
|
||||
assertThat(contributor.getKind()).isEqualTo(Kind.IMPORTED);
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(location,
|
||||
configData, 0);
|
||||
assertThat(contributor.getKind()).isEqualTo(Kind.UNBOUND_IMPORT);
|
||||
assertThat(contributor.getLocation()).isSameAs(location);
|
||||
assertThat(contributor.getImports()).isEmpty();
|
||||
assertThat(contributor.isActive(this.activationContext)).isTrue();
|
||||
|
@ -318,17 +292,56 @@ class ConfigDataEnvironmentContributorTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void ofImportedWhenHasUseLegacyPropertyThrowsException() {
|
||||
void bindCreatesImportedContributor() {
|
||||
TestLocation location = new TestLocation("test");
|
||||
MockPropertySource propertySource = new MockPropertySource();
|
||||
propertySource.setProperty("spring.config.use-legacy-processing", "true");
|
||||
assertThatExceptionOfType(UseLegacyConfigProcessingException.class)
|
||||
.isThrownBy(() -> ConfigDataEnvironmentContributor.ofImported(null,
|
||||
new ConfigData(Collections.singleton(propertySource)), 0, this.activationContext));
|
||||
propertySource.setProperty("spring.config.import", "test");
|
||||
ConfigData configData = new ConfigData(Collections.singleton(propertySource));
|
||||
ConfigDataEnvironmentContributor contributor = createBoundContributor(location, configData, 0);
|
||||
assertThat(contributor.getKind()).isEqualTo(Kind.BOUND_IMPORT);
|
||||
assertThat(contributor.getLocation()).isSameAs(location);
|
||||
assertThat(contributor.getImports()).containsExactly("test");
|
||||
assertThat(contributor.isActive(this.activationContext)).isTrue();
|
||||
assertThat(contributor.getPropertySource()).isEqualTo(propertySource);
|
||||
assertThat(contributor.getConfigurationPropertySource()).isNotNull();
|
||||
assertThat(contributor.getChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION)).isEmpty();
|
||||
}
|
||||
|
||||
private ConfigDataEnvironmentContributor createContributor(String location) {
|
||||
return ConfigDataEnvironmentContributor.ofImported(new TestLocation(location),
|
||||
new ConfigData(Collections.singleton(new MockPropertySource())), 0, this.activationContext);
|
||||
@Test
|
||||
void bindWhenConfigDataHasIgnoreImportsOptionsCreatesImportedContributorWithoutImports() {
|
||||
TestLocation location = new TestLocation("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);
|
||||
assertThat(contributor.getKind()).isEqualTo(Kind.BOUND_IMPORT);
|
||||
assertThat(contributor.getLocation()).isSameAs(location);
|
||||
assertThat(contributor.getImports()).isEmpty();
|
||||
assertThat(contributor.isActive(this.activationContext)).isTrue();
|
||||
assertThat(contributor.getPropertySource()).isEqualTo(propertySource);
|
||||
assertThat(contributor.getConfigurationPropertySource()).isNotNull();
|
||||
assertThat(contributor.getChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void bindWhenHasUseLegacyPropertyThrowsException() {
|
||||
MockPropertySource propertySource = new MockPropertySource();
|
||||
propertySource.setProperty("spring.config.use-legacy-processing", "true");
|
||||
assertThatExceptionOfType(UseLegacyConfigProcessingException.class).isThrownBy(
|
||||
() -> createBoundContributor(null, new ConfigData(Collections.singleton(propertySource)), 0));
|
||||
}
|
||||
|
||||
private ConfigDataEnvironmentContributor createBoundContributor(String location) {
|
||||
return createBoundContributor(new TestLocation(location),
|
||||
new ConfigData(Collections.singleton(new MockPropertySource())), 0);
|
||||
}
|
||||
|
||||
private ConfigDataEnvironmentContributor createBoundContributor(ConfigDataLocation location, ConfigData configData,
|
||||
int propertySourceIndex) {
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(location,
|
||||
configData, propertySourceIndex);
|
||||
Binder binder = new Binder(contributor.getConfigurationPropertySource());
|
||||
return contributor.withBoundProperties(binder);
|
||||
}
|
||||
|
||||
private List<String> asLocationsList(Iterator<ConfigDataEnvironmentContributor> iterator) {
|
||||
|
|
|
@ -268,10 +268,8 @@ class ConfigDataEnvironmentContributorsTests {
|
|||
MockPropertySource secondPropertySource = new MockPropertySource();
|
||||
secondPropertySource.setProperty("test", "two");
|
||||
ConfigData configData = new ConfigData(Arrays.asList(firstPropertySource, secondPropertySource));
|
||||
ConfigDataEnvironmentContributor firstContributor = ConfigDataEnvironmentContributor.ofImported(null,
|
||||
configData, 0, this.activationContext);
|
||||
ConfigDataEnvironmentContributor secondContributor = ConfigDataEnvironmentContributor.ofImported(null,
|
||||
configData, 1, this.activationContext);
|
||||
ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0);
|
||||
ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1);
|
||||
ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
|
||||
this.bootstrapRegistry, Arrays.asList(firstContributor, secondContributor));
|
||||
Binder binder = contributors.getBinder(this.activationContext);
|
||||
|
@ -286,10 +284,8 @@ class ConfigDataEnvironmentContributorsTests {
|
|||
MockPropertySource secondPropertySource = new MockPropertySource();
|
||||
secondPropertySource.setProperty("test", "two");
|
||||
ConfigData configData = new ConfigData(Arrays.asList(firstPropertySource, secondPropertySource));
|
||||
ConfigDataEnvironmentContributor firstContributor = ConfigDataEnvironmentContributor.ofImported(null,
|
||||
configData, 0, this.activationContext);
|
||||
ConfigDataEnvironmentContributor secondContributor = ConfigDataEnvironmentContributor.ofImported(null,
|
||||
configData, 1, this.activationContext);
|
||||
ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0);
|
||||
ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1);
|
||||
ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
|
||||
this.bootstrapRegistry, Arrays.asList(firstContributor, secondContributor));
|
||||
Binder binder = contributors.getBinder(this.activationContext);
|
||||
|
@ -317,10 +313,8 @@ class ConfigDataEnvironmentContributorsTests {
|
|||
secondPropertySource.setProperty("other", "two");
|
||||
secondPropertySource.setProperty("test", "${other}");
|
||||
ConfigData configData = new ConfigData(Arrays.asList(firstPropertySource, secondPropertySource));
|
||||
ConfigDataEnvironmentContributor firstContributor = ConfigDataEnvironmentContributor.ofImported(null,
|
||||
configData, 0, this.activationContext);
|
||||
ConfigDataEnvironmentContributor secondContributor = ConfigDataEnvironmentContributor.ofImported(null,
|
||||
configData, 1, this.activationContext);
|
||||
ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0);
|
||||
ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1);
|
||||
ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
|
||||
this.bootstrapRegistry, Arrays.asList(firstContributor, secondContributor));
|
||||
Binder binder = contributors.getBinder(this.activationContext);
|
||||
|
@ -335,10 +329,8 @@ class ConfigDataEnvironmentContributorsTests {
|
|||
MockPropertySource secondPropertySource = new MockPropertySource();
|
||||
secondPropertySource.setProperty("test", "two");
|
||||
ConfigData configData = new ConfigData(Arrays.asList(firstPropertySource, secondPropertySource));
|
||||
ConfigDataEnvironmentContributor firstContributor = ConfigDataEnvironmentContributor.ofImported(null,
|
||||
configData, 0, this.activationContext);
|
||||
ConfigDataEnvironmentContributor secondContributor = ConfigDataEnvironmentContributor.ofImported(null,
|
||||
configData, 1, this.activationContext);
|
||||
ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0);
|
||||
ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1);
|
||||
ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
|
||||
this.bootstrapRegistry, Arrays.asList(firstContributor, secondContributor));
|
||||
Binder binder = contributors.getBinder(this.activationContext, BinderOption.FAIL_ON_BIND_TO_INACTIVE_SOURCE);
|
||||
|
@ -354,10 +346,8 @@ class ConfigDataEnvironmentContributorsTests {
|
|||
secondPropertySource.setProperty("spring.config.activate.on-profile", "production");
|
||||
secondPropertySource.setProperty("test", "two");
|
||||
ConfigData configData = new ConfigData(Arrays.asList(firstPropertySource, secondPropertySource));
|
||||
ConfigDataEnvironmentContributor firstContributor = ConfigDataEnvironmentContributor.ofImported(null,
|
||||
configData, 0, this.activationContext);
|
||||
ConfigDataEnvironmentContributor secondContributor = ConfigDataEnvironmentContributor.ofImported(null,
|
||||
configData, 1, this.activationContext);
|
||||
ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0);
|
||||
ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1);
|
||||
ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
|
||||
this.bootstrapRegistry, Arrays.asList(firstContributor, secondContributor));
|
||||
Binder binder = contributors.getBinder(this.activationContext, BinderOption.FAIL_ON_BIND_TO_INACTIVE_SOURCE);
|
||||
|
@ -374,10 +364,8 @@ class ConfigDataEnvironmentContributorsTests {
|
|||
secondPropertySource.setProperty("test", "${other}");
|
||||
secondPropertySource.setProperty("other", "one");
|
||||
ConfigData configData = new ConfigData(Arrays.asList(firstPropertySource, secondPropertySource));
|
||||
ConfigDataEnvironmentContributor firstContributor = ConfigDataEnvironmentContributor.ofImported(null,
|
||||
configData, 0, this.activationContext);
|
||||
ConfigDataEnvironmentContributor secondContributor = ConfigDataEnvironmentContributor.ofImported(null,
|
||||
configData, 1, this.activationContext);
|
||||
ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0);
|
||||
ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1);
|
||||
ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
|
||||
this.bootstrapRegistry, Arrays.asList(firstContributor, secondContributor));
|
||||
Binder binder = contributors.getBinder(this.activationContext, BinderOption.FAIL_ON_BIND_TO_INACTIVE_SOURCE);
|
||||
|
@ -385,6 +373,14 @@ class ConfigDataEnvironmentContributorsTests {
|
|||
.satisfies((ex) -> assertThat(ex.getCause()).isInstanceOf(InactiveConfigDataAccessException.class));
|
||||
}
|
||||
|
||||
private ConfigDataEnvironmentContributor createBoundImportContributor(ConfigData configData,
|
||||
int propertySourceIndex) {
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(null,
|
||||
configData, propertySourceIndex);
|
||||
Binder binder = new Binder(contributor.getConfigurationPropertySource());
|
||||
return contributor.withBoundProperties(binder);
|
||||
}
|
||||
|
||||
private static class TestConfigDataLocation extends ConfigDataLocation {
|
||||
|
||||
private final String value;
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.junit.jupiter.api.Test;
|
|||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.context.properties.bind.BindException;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
|
@ -514,6 +515,27 @@ class ConfigDataEnvironmentPostProcessorIntegrationTests {
|
|||
() -> this.application.run("--spring.config.location=classpath:invalidproperty.properties"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void runWhenImportUsesPlaceholder() {
|
||||
ConfigurableApplicationContext context = this.application
|
||||
.run("--spring.config.location=classpath:application-import-with-placeholder.properties");
|
||||
assertThat(context.getEnvironment().getProperty("my.value")).isEqualTo("iwasimported");
|
||||
}
|
||||
|
||||
@Test
|
||||
void runWhenImportFromEarlierDocumentUsesPlaceholder() {
|
||||
ConfigurableApplicationContext context = this.application
|
||||
.run("--spring.config.location=classpath:application-import-with-placeholder-in-document.properties");
|
||||
assertThat(context.getEnvironment().getProperty("my.value")).isEqualTo("iwasimported");
|
||||
}
|
||||
|
||||
@Test
|
||||
void runWhenHasPropertyInProfileDocumentThrowsException() {
|
||||
assertThatExceptionOfType(BindException.class).isThrownBy(() -> this.application.run(
|
||||
"--spring.config.location=classpath:application-import-with-placeholder-in-profile-document.properties"))
|
||||
.withCauseInstanceOf(InactiveConfigDataAccessException.class);
|
||||
}
|
||||
|
||||
private Condition<ConfigurableEnvironment> matchingPropertySource(final String sourceName) {
|
||||
return new Condition<ConfigurableEnvironment>("environment containing property source " + sourceName) {
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
my.value=iwasimported
|
|
@ -0,0 +1,3 @@
|
|||
my.import=application-import-with-placeholder-imported
|
||||
#---
|
||||
spring.config.import=classpath:${my.import}.properties
|
|
@ -0,0 +1,6 @@
|
|||
my.import=application-import-with-placeholder-imported
|
||||
#---
|
||||
spring.config.import=classpath:${my.import}.properties
|
||||
#---
|
||||
my.import=badbadbad
|
||||
spring.config.activate.on-profile=missing
|
|
@ -0,0 +1,2 @@
|
|||
my.import=application-import-with-placeholder-imported
|
||||
spring.config.import=classpath:${my.import}.properties
|
Loading…
Reference in New Issue