Browse Source

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
pull/10235/merge
Stephane Nicoll 8 years ago
parent
commit
eb045f1da1
  1. 50
      spring-boot-actuator/src/main/java/org/springframework/boot/actuate/env/EnvironmentEndpoint.java
  2. 2
      spring-boot-actuator/src/test/java/org/springframework/boot/actuate/env/EnvironmentEndpointTests.java
  3. 2
      spring-boot/src/main/java/org/springframework/boot/context/properties/bind/PropertySourcesPlaceholdersResolver.java

50
spring-boot-actuator/src/main/java/org/springframework/boot/actuate/env/EnvironmentEndpoint.java vendored

@ -31,19 +31,20 @@ import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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);
}
}

2
spring-boot-actuator/src/test/java/org/springframework/boot/actuate/env/EnvironmentEndpointTests.java vendored

@ -76,6 +76,8 @@ public class EnvironmentEndpointTests { @@ -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

2
spring-boot/src/main/java/org/springframework/boot/context/properties/bind/PropertySourcesPlaceholdersResolver.java

@ -63,7 +63,7 @@ public class PropertySourcesPlaceholdersResolver implements PlaceholdersResolver @@ -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);

Loading…
Cancel
Save