Merge branch '2.4.x'

Closes gh-24793
pull/24817/head
Phillip Webb 4 years ago
commit 48e00fc7f4

@ -34,7 +34,6 @@ import org.springframework.boot.context.properties.bind.BindException;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.bind.PlaceholdersResolver;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
import org.springframework.boot.logging.DeferredLogFactory;
import org.springframework.core.env.ConfigurableEnvironment;
@ -98,9 +97,6 @@ class ConfigDataEnvironment {
private static final ConfigDataLocation[] EMPTY_LOCATIONS = new ConfigDataLocation[0];
private static final ConfigurationPropertyName INCLUDE_PROFILES = ConfigurationPropertyName
.of(Profiles.INCLUDE_PROFILES_PROPERTY_NAME);
private static final Bindable<ConfigDataLocation[]> CONFIG_DATA_LOCATION_ARRAY = Bindable
.of(ConfigDataLocation[].class);
@ -293,9 +289,9 @@ class ConfigDataEnvironment {
continue;
}
Binder binder = new Binder(Collections.singleton(source), placeholdersResolver);
binder.bind(INCLUDE_PROFILES, STRING_LIST).ifBound((includes) -> {
binder.bind(Profiles.INCLUDE_PROFILES, STRING_LIST).ifBound((includes) -> {
if (!contributor.isActive(activationContext)) {
InactiveConfigDataAccessException.throwIfPropertyFound(contributor, INCLUDE_PROFILES);
InactiveConfigDataAccessException.throwIfPropertyFound(contributor, Profiles.INCLUDE_PROFILES);
}
result.addAll(includes);
});

@ -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.
@ -55,6 +55,8 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
private final ConfigDataResource resource;
private final boolean profileSpecific;
private final PropertySource<?> propertySource;
private final ConfigurationPropertySource configurationPropertySource;
@ -72,6 +74,7 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
* @param kind the contributor kind
* @param location the location of this contributor
* @param resource the resource that contributed the data or {@code null}
* @param profileSpecific if the contributor is from a profile specific import
* @param propertySource the property source for the data or {@code null}
* @param configurationPropertySource the configuration property source for the data
* or {@code null}
@ -80,12 +83,13 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
* @param children the children of this contributor at each {@link ImportPhase}
*/
ConfigDataEnvironmentContributor(Kind kind, ConfigDataLocation location, ConfigDataResource resource,
PropertySource<?> propertySource, ConfigurationPropertySource configurationPropertySource,
ConfigDataProperties properties, boolean ignoreImports,
Map<ImportPhase, List<ConfigDataEnvironmentContributor>> children) {
boolean profileSpecific, PropertySource<?> propertySource,
ConfigurationPropertySource configurationPropertySource, ConfigDataProperties properties,
boolean ignoreImports, Map<ImportPhase, List<ConfigDataEnvironmentContributor>> children) {
this.kind = kind;
this.location = location;
this.resource = resource;
this.profileSpecific = profileSpecific;
this.properties = properties;
this.propertySource = propertySource;
this.configurationPropertySource = configurationPropertySource;
@ -122,6 +126,14 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
return this.resource;
}
/**
* Return if the contributor is from a profile specific import.
* @return if the contributor is profile specific
*/
boolean isProfileSpecific() {
return this.profileSpecific;
}
/**
* Return the property source for this contributor.
* @return the property source or {@code null}
@ -201,7 +213,8 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
properties = properties.withoutImports();
}
return new ConfigDataEnvironmentContributor(Kind.BOUND_IMPORT, this.location, this.resource,
this.propertySource, this.configurationPropertySource, properties, this.ignoreImports, null);
this.profileSpecific, this.propertySource, this.configurationPropertySource, properties,
this.ignoreImports, null);
}
/**
@ -215,8 +228,9 @@ 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.location, this.resource, this.propertySource,
this.configurationPropertySource, this.properties, this.ignoreImports, updatedChildren);
return new ConfigDataEnvironmentContributor(this.kind, this.location, this.resource, this.profileSpecific,
this.propertySource, this.configurationPropertySource, this.properties, this.ignoreImports,
updatedChildren);
}
/**
@ -240,8 +254,9 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
}
updatedChildren.put(importPhase, Collections.unmodifiableList(updatedContributors));
});
return new ConfigDataEnvironmentContributor(this.kind, this.location, this.resource, this.propertySource,
this.configurationPropertySource, this.properties, this.ignoreImports, updatedChildren);
return new ConfigDataEnvironmentContributor(this.kind, this.location, this.resource, this.profileSpecific,
this.propertySource, this.configurationPropertySource, this.properties, this.ignoreImports,
updatedChildren);
}
/**
@ -252,7 +267,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, null, false, children);
return new ConfigDataEnvironmentContributor(Kind.ROOT, null, null, false, null, null, null, false, children);
}
/**
@ -265,8 +280,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, null, properties, false,
null);
return new ConfigDataEnvironmentContributor(Kind.INITIAL_IMPORT, null, null, false, null, null, properties,
false, null);
}
/**
@ -277,7 +292,7 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
* @return a new {@link ConfigDataEnvironmentContributor} instance
*/
static ConfigDataEnvironmentContributor ofExisting(PropertySource<?> propertySource) {
return new ConfigDataEnvironmentContributor(Kind.EXISTING, null, null, propertySource,
return new ConfigDataEnvironmentContributor(Kind.EXISTING, null, null, false, propertySource,
ConfigurationPropertySource.from(propertySource), null, false, null);
}
@ -287,26 +302,29 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
* import further contributors later.
* @param location the location of this contributor
* @param resource the config data resource
* @param profileSpecific if the contributor is from a profile specific import
* @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(ConfigDataLocation location, ConfigDataResource resource,
ConfigData configData, int propertySourceIndex) {
boolean profileSpecific, 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, location, resource, propertySource,
configurationPropertySource, null, ignoreImports, null);
return new ConfigDataEnvironmentContributor(Kind.UNBOUND_IMPORT, location, resource, profileSpecific,
propertySource, configurationPropertySource, null, ignoreImports, null);
}
/**
* Factory method to create an {@link Kind#EMPTY_LOCATION empty location} contributor.
* @param location the location of this contributor
* @param profileSpecific if the contributor is from a profile specific import
* @return a new {@link ConfigDataEnvironmentContributor} instance
*/
static ConfigDataEnvironmentContributor ofEmptyLocation(ConfigDataLocation location) {
return new ConfigDataEnvironmentContributor(Kind.EMPTY_LOCATION, location, null, null, null, null, true, null);
static ConfigDataEnvironmentContributor ofEmptyLocation(ConfigDataLocation location, boolean profileSpecific) {
return new ConfigDataEnvironmentContributor(Kind.EMPTY_LOCATION, location, null, profileSpecific, null, null,
null, true, null);
}
/**

@ -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.
@ -163,12 +163,14 @@ class ConfigDataEnvironmentContributors implements Iterable<ConfigDataEnvironmen
imported.forEach((resolutionResult, data) -> {
ConfigDataLocation location = resolutionResult.getLocation();
ConfigDataResource resource = resolutionResult.getResource();
boolean profileSpecific = resolutionResult.isProfileSpecific();
if (data.getPropertySources().isEmpty()) {
contributors.add(ConfigDataEnvironmentContributor.ofEmptyLocation(location));
contributors.add(ConfigDataEnvironmentContributor.ofEmptyLocation(location, profileSpecific));
}
else {
for (int i = data.getPropertySources().size() - 1; i >= 0; i--) {
contributors.add(ConfigDataEnvironmentContributor.ofUnboundImport(location, resource, data, i));
contributors.add(ConfigDataEnvironmentContributor.ofUnboundImport(location, resource,
profileSpecific, data, i));
}
}
});

@ -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.
@ -111,21 +111,21 @@ class ConfigDataLocationResolvers {
private List<ConfigDataResolutionResult> resolve(ConfigDataLocationResolver<?> resolver,
ConfigDataLocationResolverContext context, ConfigDataLocation location, Profiles profiles) {
List<ConfigDataResolutionResult> resolved = resolve(location, () -> resolver.resolve(context, location));
List<ConfigDataResolutionResult> resolved = resolve(location, false, () -> resolver.resolve(context, location));
if (profiles == null) {
return resolved;
}
List<ConfigDataResolutionResult> profileSpecific = resolve(location,
List<ConfigDataResolutionResult> profileSpecific = resolve(location, true,
() -> resolver.resolveProfileSpecific(context, location, profiles));
return merge(resolved, profileSpecific);
}
private List<ConfigDataResolutionResult> resolve(ConfigDataLocation location,
private List<ConfigDataResolutionResult> resolve(ConfigDataLocation location, boolean profileSpecific,
Supplier<List<? extends ConfigDataResource>> resolveAction) {
List<ConfigDataResource> resources = nonNullList(resolveAction.get());
List<ConfigDataResolutionResult> resolved = new ArrayList<>(resources.size());
for (ConfigDataResource resource : resources) {
resolved.add(new ConfigDataResolutionResult(location, resource));
resolved.add(new ConfigDataResolutionResult(location, resource, profileSpecific));
}
return resolved;
}

@ -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.
@ -94,7 +94,7 @@ class ConfigDataProperties {
ConfigDataProperties withLegacyProfiles(String[] legacyProfiles, ConfigurationProperty property) {
if (this.activate != null && !ObjectUtils.isEmpty(this.activate.onProfile)) {
throw new InvalidConfigDataPropertyException(property, NAME.append("activate.on-profile"), null);
throw new InvalidConfigDataPropertyException(property, false, NAME.append("activate.on-profile"), null);
}
return new ConfigDataProperties(this.imports, new Activate(this.activate.onCloudPlatform, legacyProfiles));
}

@ -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.
@ -28,9 +28,12 @@ class ConfigDataResolutionResult {
private final ConfigDataResource resource;
ConfigDataResolutionResult(ConfigDataLocation location, ConfigDataResource resource) {
private final boolean profileSpecific;
ConfigDataResolutionResult(ConfigDataLocation location, ConfigDataResource resource, boolean profileSpecific) {
this.location = location;
this.resource = resource;
this.profileSpecific = profileSpecific;
}
ConfigDataLocation getLocation() {
@ -41,4 +44,8 @@ class ConfigDataResolutionResult {
return this.resource;
}
boolean isProfileSpecific() {
return this.profileSpecific;
}
}

@ -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.
@ -18,13 +18,16 @@ package org.springframework.boot.context.config;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.springframework.boot.context.properties.source.ConfigurationProperty;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
import org.springframework.core.env.AbstractEnvironment;
/**
* Exception thrown if an invalid property is found when processing config data.
@ -35,12 +38,23 @@ import org.springframework.boot.context.properties.source.ConfigurationPropertyS
*/
public class InvalidConfigDataPropertyException extends ConfigDataException {
private static final Map<ConfigurationPropertyName, ConfigurationPropertyName> WARNING;
private static final Map<ConfigurationPropertyName, ConfigurationPropertyName> WARNINGS;
static {
Map<ConfigurationPropertyName, ConfigurationPropertyName> warning = new LinkedHashMap<>();
warning.put(ConfigurationPropertyName.of("spring.profiles"),
Map<ConfigurationPropertyName, ConfigurationPropertyName> warnings = new LinkedHashMap<>();
warnings.put(ConfigurationPropertyName.of("spring.profiles"),
ConfigurationPropertyName.of("spring.config.activate.on-profile"));
WARNING = Collections.unmodifiableMap(warning);
WARNINGS = Collections.unmodifiableMap(warnings);
}
private static final Set<ConfigurationPropertyName> PROFILE_SPECIFIC_ERRORS;
static {
Set<ConfigurationPropertyName> errors = new LinkedHashSet<>();
errors.add(Profiles.INCLUDE_PROFILES);
errors.add(ConfigurationPropertyName.of(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME));
errors.add(ConfigurationPropertyName.of(AbstractEnvironment.DEFAULT_PROFILES_PROPERTY_NAME));
errors.add(ConfigurationPropertyName.of("spring.config.activate.on-profile"));
errors.add(ConfigurationPropertyName.of("spring.profiles"));
PROFILE_SPECIFIC_ERRORS = Collections.unmodifiableSet(errors);
}
private final ConfigurationProperty property;
@ -49,9 +63,9 @@ public class InvalidConfigDataPropertyException extends ConfigDataException {
private final ConfigDataResource location;
InvalidConfigDataPropertyException(ConfigurationProperty property, ConfigurationPropertyName replacement,
ConfigDataResource location) {
super(getMessage(property, replacement, location), null);
InvalidConfigDataPropertyException(ConfigurationProperty property, boolean profileSpecific,
ConfigurationPropertyName replacement, ConfigDataResource location) {
super(getMessage(property, profileSpecific, replacement, location), null);
this.property = property;
this.replacement = replacement;
this.location = location;
@ -94,17 +108,25 @@ public class InvalidConfigDataPropertyException extends ConfigDataException {
static void throwOrWarn(Log logger, ConfigDataEnvironmentContributor contributor) {
ConfigurationPropertySource propertySource = contributor.getConfigurationPropertySource();
if (propertySource != null) {
WARNING.forEach((invalid, replacement) -> {
ConfigurationProperty property = propertySource.getConfigurationProperty(invalid);
WARNINGS.forEach((name, replacement) -> {
ConfigurationProperty property = propertySource.getConfigurationProperty(name);
if (property != null) {
logger.warn(getMessage(property, false, replacement, contributor.getResource()));
}
});
if (contributor.isProfileSpecific()) {
PROFILE_SPECIFIC_ERRORS.forEach((name) -> {
ConfigurationProperty property = propertySource.getConfigurationProperty(name);
if (property != null) {
logger.warn(getMessage(property, replacement, contributor.getResource()));
throw new InvalidConfigDataPropertyException(property, true, null, contributor.getResource());
}
});
}
}
}
private static String getMessage(ConfigurationProperty property, ConfigurationPropertyName replacement,
ConfigDataResource location) {
private static String getMessage(ConfigurationProperty property, boolean profileSpecific,
ConfigurationPropertyName replacement, ConfigDataResource location) {
StringBuilder message = new StringBuilder("Property '");
message.append(property.getName());
if (location != null) {
@ -112,6 +134,9 @@ public class InvalidConfigDataPropertyException extends ConfigDataException {
message.append(location);
}
message.append("' is invalid");
if (profileSpecific) {
message.append(" in a profile specific resource");
}
if (replacement != null) {
message.append(" and should be replaced with '");
message.append(replacement);

@ -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.
@ -30,6 +30,7 @@ import java.util.function.Supplier;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
import org.springframework.core.ResolvableType;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.core.env.Environment;
@ -54,6 +55,9 @@ public class Profiles implements Iterable<String> {
*/
public static final String INCLUDE_PROFILES_PROPERTY_NAME = "spring.profiles.include";
static final ConfigurationPropertyName INCLUDE_PROFILES = ConfigurationPropertyName
.of(Profiles.INCLUDE_PROFILES_PROPERTY_NAME);
private static final Bindable<MultiValueMap<String, String>> STRING_STRINGS_MAP = Bindable
.of(ResolvableType.forClassWithGenerics(MultiValueMap.class, String.class, String.class));

@ -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.
@ -122,7 +122,7 @@ class ConfigDataEnvironmentContributorPlaceholdersResolverTests {
private final boolean active;
protected TestConfigDataEnvironmentContributor(PropertySource<?> propertySource, boolean active) {
super(Kind.ROOT, null, null, propertySource, null, null, false, null);
super(Kind.ROOT, null, null, false, propertySource, null, null, false, null);
this.active = active;
}

@ -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.
@ -84,7 +84,7 @@ class ConfigDataEnvironmentContributorTests {
ConfigData configData = new ConfigData(Collections.singleton(new MockPropertySource()));
ConfigDataResource resource = mock(ConfigDataResource.class);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(TEST_LOCATION,
resource, configData, 0);
resource, false, configData, 0);
assertThat(contributor.getResource()).isSameAs(resource);
}
@ -101,7 +101,7 @@ class ConfigDataEnvironmentContributorTests {
propertySource.setProperty("spring", "boot");
ConfigData configData = new ConfigData(Collections.singleton(propertySource));
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(null, null,
configData, 0);
false, configData, 0);
assertThat(contributor.getConfigurationPropertySource()
.getConfigurationProperty(ConfigurationPropertyName.of("spring")).getValue()).isEqualTo("boot");
}
@ -284,7 +284,7 @@ class ConfigDataEnvironmentContributorTests {
propertySource.setProperty("spring.config.import", "test");
ConfigData configData = new ConfigData(Collections.singleton(propertySource));
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(TEST_LOCATION,
resource, configData, 0);
resource, false, configData, 0);
assertThat(contributor.getKind()).isEqualTo(Kind.UNBOUND_IMPORT);
assertThat(contributor.getResource()).isSameAs(resource);
assertThat(contributor.getImports()).isEmpty();
@ -342,7 +342,7 @@ class ConfigDataEnvironmentContributorTests {
private ConfigDataEnvironmentContributor createBoundContributor(ConfigDataResource resource, ConfigData configData,
int propertySourceIndex) {
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(TEST_LOCATION,
resource, configData, propertySourceIndex);
resource, false, configData, propertySourceIndex);
Binder binder = new Binder(contributor.getConfigurationPropertySource());
return contributor.withBoundProperties(binder);
}

@ -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.
@ -117,7 +117,7 @@ class ConfigDataEnvironmentContributorsTests {
List<ConfigDataLocation> locations = Arrays.asList(LOCATION_1);
MockPropertySource propertySource = new MockPropertySource();
Map<ConfigDataResolutionResult, ConfigData> imported = new LinkedHashMap<>();
imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a")),
imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a"), false),
new ConfigData(Arrays.asList(propertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations)))
.willReturn(imported);
@ -140,14 +140,14 @@ class ConfigDataEnvironmentContributorsTests {
MockPropertySource initialPropertySource = new MockPropertySource();
initialPropertySource.setProperty("spring.config.import", "location2");
Map<ConfigDataResolutionResult, ConfigData> initialImported = new LinkedHashMap<>();
initialImported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a")),
initialImported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a"), false),
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<ConfigDataResolutionResult, ConfigData> secondImported = new LinkedHashMap<>();
secondImported.put(new ConfigDataResolutionResult(LOCATION_2, new TestConfigDataResource("b")),
secondImported.put(new ConfigDataResolutionResult(LOCATION_2, new TestConfigDataResource("b"), false),
new ConfigData(Arrays.asList(secondPropertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(secondLocations)))
.willReturn(secondImported);
@ -174,7 +174,7 @@ class ConfigDataEnvironmentContributorsTests {
List<ConfigDataLocation> locations = Arrays.asList(LOCATION_1);
MockPropertySource propertySource = new MockPropertySource();
Map<ConfigDataResolutionResult, ConfigData> imported = new LinkedHashMap<>();
imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a'")),
imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a'"), false),
new ConfigData(Arrays.asList(propertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations)))
.willReturn(imported);
@ -194,14 +194,14 @@ class ConfigDataEnvironmentContributorsTests {
MockPropertySource initialPropertySource = new MockPropertySource();
initialPropertySource.setProperty("spring.config.import", "location2");
Map<ConfigDataResolutionResult, ConfigData> initialImported = new LinkedHashMap<>();
initialImported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a")),
initialImported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a"), false),
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<ConfigDataResolutionResult, ConfigData> secondImported = new LinkedHashMap<>();
secondImported.put(new ConfigDataResolutionResult(LOCATION_2, new TestConfigDataResource("b")),
secondImported.put(new ConfigDataResolutionResult(LOCATION_2, new TestConfigDataResource("b"), false),
new ConfigData(Arrays.asList(secondPropertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(secondLocations)))
.willReturn(secondImported);
@ -224,7 +224,7 @@ class ConfigDataEnvironmentContributorsTests {
List<ConfigDataLocation> locations = Arrays.asList(LOCATION_1);
MockPropertySource propertySource = new MockPropertySource();
Map<ConfigDataResolutionResult, ConfigData> imported = new LinkedHashMap<>();
imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a'")),
imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a'"), false),
new ConfigData(Arrays.asList(propertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations)))
.willReturn(imported);
@ -247,7 +247,7 @@ class ConfigDataEnvironmentContributorsTests {
List<ConfigDataLocation> locations = Arrays.asList(LOCATION_1);
MockPropertySource propertySource = new MockPropertySource();
Map<ConfigDataResolutionResult, ConfigData> imported = new LinkedHashMap<>();
imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a'")),
imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a'"), false),
new ConfigData(Arrays.asList(propertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations)))
.willReturn(imported);
@ -386,7 +386,7 @@ class ConfigDataEnvironmentContributorsTests {
private ConfigDataEnvironmentContributor createBoundImportContributor(ConfigData configData,
int propertySourceIndex) {
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(null, null,
configData, propertySourceIndex);
false, configData, propertySourceIndex);
Binder binder = new Binder(contributor.getConfigurationPropertySource());
return contributor.withBoundProperties(binder);
}

@ -636,8 +636,8 @@ class ConfigDataEnvironmentPostProcessorIntegrationTests {
@Test
void runWhenHasIncludedProfilesWithProfileSpecificFileThrowsException() {
assertThatExceptionOfType(InactiveConfigDataAccessException.class).isThrownBy(() -> this.application
.run("--spring.config.name=application-include-profiles-in-profile-specific-document"));
assertThatExceptionOfType(InvalidConfigDataPropertyException.class).isThrownBy(() -> this.application
.run("--spring.config.name=application-include-profiles-in-profile-specific-file"));
}
@Test

@ -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.
@ -81,9 +81,9 @@ class ConfigDataImporterTests {
ConfigData configData1 = new ConfigData(Collections.singleton(new MockPropertySource()));
ConfigData configData2 = new ConfigData(Collections.singleton(new MockPropertySource()));
given(this.resolvers.resolve(this.locationResolverContext, location1, this.profiles))
.willReturn(Collections.singletonList(new ConfigDataResolutionResult(location1, resource1)));
.willReturn(Collections.singletonList(new ConfigDataResolutionResult(location1, resource1, false)));
given(this.resolvers.resolve(this.locationResolverContext, location2, this.profiles))
.willReturn(Collections.singletonList(new ConfigDataResolutionResult(location2, resource2)));
.willReturn(Collections.singletonList(new ConfigDataResolutionResult(location2, resource2, false)));
given(this.loaders.load(this.loaderContext, resource1)).willReturn(configData1);
given(this.loaders.load(this.loaderContext, resource2)).willReturn(configData2);
ConfigDataImporter importer = new ConfigDataImporter(this.logFactory, ConfigDataNotFoundAction.FAIL,
@ -107,11 +107,11 @@ class ConfigDataImporterTests {
ConfigData configData2 = new ConfigData(Collections.singleton(new MockPropertySource()));
ConfigData configData3 = new ConfigData(Collections.singleton(new MockPropertySource()));
given(this.resolvers.resolve(this.locationResolverContext, location1, this.profiles))
.willReturn(Collections.singletonList(new ConfigDataResolutionResult(location1, resource1)));
.willReturn(Collections.singletonList(new ConfigDataResolutionResult(location1, resource1, false)));
given(this.resolvers.resolve(this.locationResolverContext, location2, this.profiles))
.willReturn(Collections.singletonList(new ConfigDataResolutionResult(location2, resource2)));
.willReturn(Collections.singletonList(new ConfigDataResolutionResult(location2, resource2, false)));
given(this.resolvers.resolve(this.locationResolverContext, location3, this.profiles))
.willReturn(Collections.singletonList(new ConfigDataResolutionResult(location3, resource3)));
.willReturn(Collections.singletonList(new ConfigDataResolutionResult(location3, resource3, false)));
given(this.loaders.load(this.loaderContext, resource1)).willReturn(configData1);
given(this.loaders.load(this.loaderContext, resource2)).willReturn(configData2);
given(this.loaders.load(this.loaderContext, resource3)).willReturn(configData3);

@ -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.
@ -20,8 +20,10 @@ import org.apache.commons.logging.Log;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.boot.context.config.ConfigDataEnvironmentContributor.Kind;
import org.springframework.boot.context.properties.source.ConfigurationProperty;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
import org.springframework.boot.origin.MockOrigin;
import org.springframework.mock.env.MockPropertySource;
@ -50,46 +52,54 @@ class InvalidConfigDataPropertyExceptionTests {
@Test
void createHasCorrectMessage() {
assertThat(new InvalidConfigDataPropertyException(this.property, this.replacement, this.resource)).hasMessage(
assertThat(new InvalidConfigDataPropertyException(this.property, false, this.replacement, this.resource))
.hasMessage(
"Property 'invalid' imported from location 'test' is invalid and should be replaced with 'replacement' [origin: origin]");
}
@Test
void createWhenNoLocationHasCorrectMessage() {
assertThat(new InvalidConfigDataPropertyException(this.property, this.replacement, null))
assertThat(new InvalidConfigDataPropertyException(this.property, false, this.replacement, null))
.hasMessage("Property 'invalid' is invalid and should be replaced with 'replacement' [origin: origin]");
}
@Test
void createWhenNoReplacementHasCorrectMessage() {
assertThat(new InvalidConfigDataPropertyException(this.property, null, this.resource))
assertThat(new InvalidConfigDataPropertyException(this.property, false, null, this.resource))
.hasMessage("Property 'invalid' imported from location 'test' is invalid [origin: origin]");
}
@Test
void createWhenNoOriginHasCorrectMessage() {
ConfigurationProperty property = new ConfigurationProperty(this.invalid, "bad", null);
assertThat(new InvalidConfigDataPropertyException(property, this.replacement, this.resource)).hasMessage(
assertThat(new InvalidConfigDataPropertyException(property, false, this.replacement, this.resource)).hasMessage(
"Property 'invalid' imported from location 'test' is invalid and should be replaced with 'replacement'");
}
@Test
void createWhenProfileSpecificHasCorrectMessage() {
ConfigurationProperty property = new ConfigurationProperty(this.invalid, "bad", null);
assertThat(new InvalidConfigDataPropertyException(property, true, null, this.resource)).hasMessage(
"Property 'invalid' imported from location 'test' is invalid in a profile specific resource");
}
@Test
void getPropertyReturnsProperty() {
InvalidConfigDataPropertyException exception = new InvalidConfigDataPropertyException(this.property,
InvalidConfigDataPropertyException exception = new InvalidConfigDataPropertyException(this.property, false,
this.replacement, this.resource);
assertThat(exception.getProperty()).isEqualTo(this.property);
}
@Test
void getLocationReturnsLocation() {
InvalidConfigDataPropertyException exception = new InvalidConfigDataPropertyException(this.property,
InvalidConfigDataPropertyException exception = new InvalidConfigDataPropertyException(this.property, false,
this.replacement, this.resource);
assertThat(exception.getLocation()).isEqualTo(this.resource);
}
@Test
void getReplacementReturnsReplacement() {
InvalidConfigDataPropertyException exception = new InvalidConfigDataPropertyException(this.property,
InvalidConfigDataPropertyException exception = new InvalidConfigDataPropertyException(this.property, false,
this.replacement, this.resource);
assertThat(exception.getReplacement()).isEqualTo(this.replacement);
}
@ -106,6 +116,25 @@ class InvalidConfigDataPropertyExceptionTests {
+ "'spring.config.activate.on-profile'");
}
@Test
void throwOrWarnWhenWhenHasInvalidProfileSpecificPropertyThrowsException() {
throwOrWarnWhenWhenHasInvalidProfileSpecificPropertyThrowsException("spring.profiles.include");
throwOrWarnWhenWhenHasInvalidProfileSpecificPropertyThrowsException("spring.profiles.active");
throwOrWarnWhenWhenHasInvalidProfileSpecificPropertyThrowsException("spring.profiles.default");
throwOrWarnWhenWhenHasInvalidProfileSpecificPropertyThrowsException("spring.config.activate.on-profile");
throwOrWarnWhenWhenHasInvalidProfileSpecificPropertyThrowsException("spring.profiles");
}
private void throwOrWarnWhenWhenHasInvalidProfileSpecificPropertyThrowsException(String name) {
MockPropertySource propertySource = new MockPropertySource();
propertySource.setProperty(name, "a");
ConfigDataEnvironmentContributor contributor = new ConfigDataEnvironmentContributor(Kind.BOUND_IMPORT, null,
null, true, propertySource, ConfigurationPropertySource.from(propertySource), null, false, null);
assertThatExceptionOfType(InvalidConfigDataPropertyException.class)
.isThrownBy(() -> InvalidConfigDataPropertyException.throwOrWarn(this.logger, contributor))
.withMessageStartingWith("Property '" + name + "' is invalid in a profile specific resource");
}
@Test
void throwOrWarnWhenHasNoInvalidPropertyDoesNothing() {
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor

Loading…
Cancel
Save