Commit eb045f1d authored by Stephane Nicoll's avatar Stephane Nicoll

Fix value of property in PropertySource descriptor

Prior to this commit, if a key was present in multiple PropertySources,
all descriptors shared the same common value. This commit makes sure
that each PropertySource descriptor shows the value it defines rather
than the one that is promoted in the Environment.

Closes gh-10428
parent f52c081e
......@@ -31,19 +31,20 @@ import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector;
import org.springframework.boot.actuate.env.EnvironmentEndpoint.EnvironmentDescriptor.PropertySourceDescriptor;
import org.springframework.boot.actuate.env.EnvironmentEndpoint.EnvironmentDescriptor.PropertySourceDescriptor.PropertyValueDescriptor;
import org.springframework.boot.context.properties.bind.PlaceholdersResolver;
import org.springframework.boot.context.properties.bind.PropertySourcesPlaceholdersResolver;
import org.springframework.boot.origin.OriginLookup;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertyResolver;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.PropertySources;
import org.springframework.core.env.PropertySourcesPropertyResolver;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.http.HttpStatus;
import org.springframework.util.PropertyPlaceholderHelper;
import org.springframework.util.StringUtils;
import org.springframework.util.SystemPropertyUtils;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
......@@ -85,7 +86,7 @@ public class EnvironmentEndpoint {
private EnvironmentDescriptor getEnvironmentDescriptor(
Predicate<String> propertyNamePredicate) {
PropertyResolver resolver = getResolver();
PlaceholdersResolver resolver = getResolver();
List<PropertySourceDescriptor> propertySources = new ArrayList<>();
getPropertySourcesAsMap().forEach((sourceName, source) -> {
if (source instanceof EnumerablePropertySource) {
......@@ -99,7 +100,7 @@ public class EnvironmentEndpoint {
}
private PropertySourceDescriptor describeSource(String sourceName,
EnumerablePropertySource<?> source, PropertyResolver resolver,
EnumerablePropertySource<?> source, PlaceholdersResolver resolver,
Predicate<String> namePredicate) {
Map<String, PropertyValueDescriptor> properties = new LinkedHashMap<>();
Stream.of(source.getPropertyNames()).filter(namePredicate).forEach(
......@@ -108,19 +109,17 @@ public class EnvironmentEndpoint {
}
private PropertyValueDescriptor describeValueOf(String name,
EnumerablePropertySource<?> source, PropertyResolver resolver) {
Object resolved = resolver.getProperty(name, Object.class);
EnumerablePropertySource<?> source, PlaceholdersResolver resolver) {
Object resolved = resolver.resolvePlaceholders(source.getProperty(name));
@SuppressWarnings("unchecked")
String origin = (source instanceof OriginLookup)
? ((OriginLookup<Object>) source).getOrigin(name).toString() : null;
return new PropertyValueDescriptor(sanitize(name, resolved), origin);
}
private PropertyResolver getResolver() {
PlaceholderSanitizingPropertyResolver resolver = new PlaceholderSanitizingPropertyResolver(
private PlaceholdersResolver getResolver() {
return new PropertySourcesPlaceholdersSanitizingResolver(
getPropertySources(), this.sanitizer);
resolver.setIgnoreUnresolvableNestedPlaceholders(true);
return resolver;
}
private Map<String, PropertySource<?>> getPropertySourcesAsMap() {
......@@ -160,29 +159,28 @@ public class EnvironmentEndpoint {
}
/**
* {@link PropertySourcesPropertyResolver} that sanitizes sensitive placeholders if
* present.
* {@link PropertySourcesPlaceholdersResolver} that sanitizes sensitive placeholders
* if present.
*/
private class PlaceholderSanitizingPropertyResolver
extends PropertySourcesPropertyResolver {
private static class PropertySourcesPlaceholdersSanitizingResolver
extends PropertySourcesPlaceholdersResolver {
private final Sanitizer sanitizer;
/**
* Create a new resolver against the given property sources.
* @param propertySources the set of {@link PropertySource} objects to use
* @param sanitizer the sanitizer used to sanitize sensitive values
*/
PlaceholderSanitizingPropertyResolver(PropertySources propertySources,
Sanitizer sanitizer) {
super(propertySources);
public PropertySourcesPlaceholdersSanitizingResolver(
Iterable<PropertySource<?>> sources, Sanitizer sanitizer) {
super(sources, new PropertyPlaceholderHelper(
SystemPropertyUtils.PLACEHOLDER_PREFIX,
SystemPropertyUtils.PLACEHOLDER_SUFFIX,
SystemPropertyUtils.VALUE_SEPARATOR, true));
this.sanitizer = sanitizer;
}
@Override
protected String getPropertyAsRawString(String key) {
String value = super.getPropertyAsRawString(key);
return (String) this.sanitizer.sanitize(key, value);
protected String resolvePlaceholder(String placeholder) {
String value = super.resolvePlaceholder(placeholder);
return (value != null ?
(String) this.sanitizer.sanitize(placeholder, value) : null);
}
}
......
......@@ -76,6 +76,8 @@ public class EnvironmentEndpointTests {
.environment(null);
assertThat(getSource("composite:one", env).getProperties().get("foo").getValue())
.isEqualTo("bar");
assertThat(getSource("composite:two", env).getProperties().get("foo").getValue())
.isEqualTo("spam");
}
@Test
......
......@@ -63,7 +63,7 @@ public class PropertySourcesPlaceholdersResolver implements PlaceholdersResolver
return value;
}
private String resolvePlaceholder(String placeholder) {
protected String resolvePlaceholder(String placeholder) {
if (this.sources != null) {
for (PropertySource<?> source : this.sources) {
Object value = source.getProperty(placeholder);
......
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