From d7f300812243db5828fb49dc4f8f30f545f94424 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 14 Sep 2017 13:19:28 +0200 Subject: [PATCH] Move configuration of EnvironmentEndpoint See gh-10263 --- .../EnvironmentEndpointAutoConfiguration.java | 17 ++++++- .../env/EnvironmentEndpointProperties.java | 45 +++++++++++++++++++ ...itional-spring-configuration-metadata.json | 3 -- ...ronmentEndpointAutoConfigurationTests.java | 40 ++++++++++++++++- .../boot/actuate/env/EnvironmentEndpoint.java | 8 ++-- .../actuate/env/EnvironmentEndpointTests.java | 17 ------- 6 files changed, 102 insertions(+), 28 deletions(-) create mode 100644 spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointProperties.java diff --git a/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointAutoConfiguration.java b/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointAutoConfiguration.java index 24735272fc1..cb7aaae0a23 100644 --- a/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointAutoConfiguration.java +++ b/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointAutoConfiguration.java @@ -20,6 +20,7 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.condition.Conditi import org.springframework.boot.actuate.env.EnvironmentEndpoint; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; @@ -28,16 +29,30 @@ import org.springframework.core.env.Environment; * {@link EnableAutoConfiguration Auto-configuration} for the {@link EnvironmentEndpoint}. * * @author Phillip Webb + * @author Stephane Nicoll * @since 2.0.0 */ @Configuration +@EnableConfigurationProperties(EnvironmentEndpointProperties.class) public class EnvironmentEndpointAutoConfiguration { + private final EnvironmentEndpointProperties properties; + + public EnvironmentEndpointAutoConfiguration( + EnvironmentEndpointProperties properties) { + this.properties = properties; + } + @Bean @ConditionalOnMissingBean @ConditionalOnEnabledEndpoint public EnvironmentEndpoint environmentEndpoint(Environment environment) { - return new EnvironmentEndpoint(environment); + EnvironmentEndpoint endpoint = new EnvironmentEndpoint(environment); + String[] keysToSanitize = this.properties.getKeysToSanitize(); + if (keysToSanitize != null) { + endpoint.setKeysToSanitize(keysToSanitize); + } + return endpoint; } } diff --git a/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointProperties.java b/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointProperties.java new file mode 100644 index 00000000000..3acbce2d787 --- /dev/null +++ b/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointProperties.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012-2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.env; + +import org.springframework.boot.actuate.env.EnvironmentEndpoint; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Configuration properties for {@link EnvironmentEndpoint}. + * + * @author Stephane Nicoll + * @since 2.0.0 + */ +@ConfigurationProperties("endpoints.env") +public class EnvironmentEndpointProperties { + + /** + * Keys that should be sanitized. Keys can be simple strings that the property ends + * with or regex expressions. + */ + private String[] keysToSanitize; + + public String[] getKeysToSanitize() { + return this.keysToSanitize; + } + + public void setKeysToSanitize(String[] keysToSanitize) { + this.keysToSanitize = keysToSanitize; + } + +} diff --git a/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 0dce4c32687..33ba4002f30 100644 --- a/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -30,9 +30,6 @@ }, { "name": "endpoints.env.keys-to-sanitize", - "type": "java.lang.String[]", - "sourceType": "org.springframework.boot.actuate.env.EnvironmentEndpoint", - "description": "Keys that should be sanitized. Keys can be simple strings that the property ends with or regex expressions.", "defaultValue": [ "password", "secret", diff --git a/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointAutoConfigurationTests.java b/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointAutoConfigurationTests.java index 156989e0ac8..e6d8c3b1b31 100644 --- a/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointAutoConfigurationTests.java +++ b/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointAutoConfigurationTests.java @@ -16,11 +16,18 @@ package org.springframework.boot.actuate.autoconfigure.env; +import java.util.Map; + import org.junit.Test; import org.springframework.boot.actuate.env.EnvironmentEndpoint; +import org.springframework.boot.actuate.env.EnvironmentEndpoint.EnvironmentDescriptor; +import org.springframework.boot.actuate.env.EnvironmentEndpoint.EnvironmentDescriptor.PropertySourceDescriptor; +import org.springframework.boot.actuate.env.EnvironmentEndpoint.EnvironmentDescriptor.PropertySourceDescriptor.PropertyValueDescriptor; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.context.runner.ContextConsumer; import static org.assertj.core.api.Assertions.assertThat; @@ -37,8 +44,8 @@ public class EnvironmentEndpointAutoConfigurationTests { @Test public void runShouldHaveEndpointBean() { - this.contextRunner.run((context) -> assertThat(context) - .hasSingleBean(EnvironmentEndpoint.class)); + this.contextRunner.withSystemProperties("dbPassword=123456", "apiKey=123456") + .run(validateSystemProperties("******", "******")); } @Test @@ -49,4 +56,33 @@ public class EnvironmentEndpointAutoConfigurationTests { .doesNotHaveBean(EnvironmentEndpoint.class)); } + + @Test + public void keysToSanitizeCanBeConfiguredViaTheEnvironment() throws Exception { + this.contextRunner.withSystemProperties("dbPassword=123456", "apiKey=123456") + .withPropertyValues("endpoints.env.keys-to-sanitize=.*pass.*") + .run(validateSystemProperties("******", "123456")); + } + + private ContextConsumer validateSystemProperties( + String dbPassword, String apiKey) { + return context -> { + assertThat(context).hasSingleBean(EnvironmentEndpoint.class); + EnvironmentEndpoint endpoint = context.getBean(EnvironmentEndpoint.class); + EnvironmentDescriptor env = endpoint.environment(null); + Map systemProperties = getSource( + "systemProperties", env).getProperties(); + assertThat(systemProperties.get("dbPassword").getValue()) + .isEqualTo(dbPassword); + assertThat(systemProperties.get("apiKey").getValue()).isEqualTo(apiKey); + }; + } + + private PropertySourceDescriptor getSource(String name, + EnvironmentDescriptor descriptor) { + return descriptor.getPropertySources().stream() + .filter((source) -> name.equals(source.getName())).findFirst().get(); + } + + } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/env/EnvironmentEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/env/EnvironmentEndpoint.java index 6e470a9dec8..c7f67fc869b 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/env/EnvironmentEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/env/EnvironmentEndpoint.java @@ -31,7 +31,6 @@ 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.ConfigurationProperties; import org.springframework.boot.origin.OriginLookup; import org.springframework.core.env.CompositePropertySource; import org.springframework.core.env.ConfigurableEnvironment; @@ -57,7 +56,6 @@ import org.springframework.web.bind.annotation.ResponseStatus; * @since 2.0.0 */ @Endpoint(id = "env") -@ConfigurationProperties("endpoints.env") public class EnvironmentEndpoint { private final Sanitizer sanitizer = new Sanitizer(); @@ -192,7 +190,7 @@ public class EnvironmentEndpoint { /** * A description of an {@link Environment}. */ - static final class EnvironmentDescriptor { + public static final class EnvironmentDescriptor { private final List activeProfiles; @@ -215,7 +213,7 @@ public class EnvironmentEndpoint { /** * A description of a {@link PropertySource}. */ - static final class PropertySourceDescriptor { + public static final class PropertySourceDescriptor { private final String name; @@ -238,7 +236,7 @@ public class EnvironmentEndpoint { /** * A description of a property's value, including its origin if available. */ - static final class PropertyValueDescriptor { + public static final class PropertyValueDescriptor { private final Object value; diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/env/EnvironmentEndpointTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/env/EnvironmentEndpointTests.java index 58a68dea168..50a496e7b57 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/env/EnvironmentEndpointTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/env/EnvironmentEndpointTests.java @@ -27,7 +27,6 @@ import org.springframework.boot.actuate.env.EnvironmentEndpoint.EnvironmentDescr 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.EnableConfigurationProperties; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -152,22 +151,6 @@ public class EnvironmentEndpointTests { clearSystemProperties("dbPassword", "apiKey"); } - @Test - public void keysToSanitizeCanBeConfiguredViaTheEnvironment() throws Exception { - ApplicationContextRunner tester = new ApplicationContextRunner() - .withSystemProperties("dbPassword=123456", "apiKey=123456") - .withPropertyValues("endpoints.env.keys-to-sanitize=.*pass.*") - .withUserConfiguration(Config.class); - tester.run((context) -> { - EnvironmentEndpoint endpoint = context.getBean(EnvironmentEndpoint.class); - EnvironmentDescriptor env = endpoint.environment(null); - Map systemProperties = getSource( - "systemProperties", env).getProperties(); - assertThat(systemProperties.get("dbPassword").getValue()).isEqualTo("******"); - assertThat(systemProperties.get("apiKey").getValue()).isEqualTo("123456"); - }); - } - @Test public void propertyWithPlaceholderResolved() { StandardEnvironment environment = new StandardEnvironment();