diff --git a/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointAutoConfiguration.java b/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointAutoConfiguration.java index cb2789864f..416cd0be9b 100644 --- a/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointAutoConfiguration.java +++ b/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointAutoConfiguration.java @@ -20,6 +20,7 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.condition.Conditi import org.springframework.boot.actuate.context.properties.ConfigurationPropertiesReportEndpoint; 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; @@ -28,16 +29,30 @@ import org.springframework.context.annotation.Configuration; * {@link ConfigurationPropertiesReportEndpoint}. * * @author Phillip Webb + * @author Stephane Nicoll * @since 2.0.0 */ @Configuration +@EnableConfigurationProperties(ConfigurationPropertiesReportEndpointProperties.class) public class ConfigurationPropertiesReportEndpointAutoConfiguration { + private final ConfigurationPropertiesReportEndpointProperties properties; + + public ConfigurationPropertiesReportEndpointAutoConfiguration( + ConfigurationPropertiesReportEndpointProperties properties) { + this.properties = properties; + } + @Bean @ConditionalOnMissingBean @ConditionalOnEnabledEndpoint public ConfigurationPropertiesReportEndpoint configurationPropertiesReportEndpoint() { - return new ConfigurationPropertiesReportEndpoint(); + ConfigurationPropertiesReportEndpoint endpoint = new ConfigurationPropertiesReportEndpoint(); + 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/context/properties/ConfigurationPropertiesReportEndpointProperties.java b/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointProperties.java new file mode 100644 index 0000000000..457831d4f4 --- /dev/null +++ b/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointProperties.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.context.properties; + +import org.springframework.boot.actuate.context.properties.ConfigurationPropertiesReportEndpoint; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Configuration properties for {@link ConfigurationPropertiesReportEndpoint}. + * + * @author Stephane Nicoll + * @since 2.0.0 + */ +@ConfigurationProperties("endpoints.configprops") +public class ConfigurationPropertiesReportEndpointProperties { + + /** + * 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 c476443ca8..0dce4c3268 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 @@ -1,9 +1,6 @@ {"properties": [ { "name": "endpoints.configprops.keys-to-sanitize", - "type": "java.lang.String[]", - "sourceType": "org.springframework.boot.actuate.context.properties.ConfigurationPropertiesReportEndpoint", - "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/context/properties/ConfigurationPropertiesReportEndpointAutoConfigurationTests.java b/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointAutoConfigurationTests.java index 48a3cf7836..823773e2d6 100644 --- a/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointAutoConfigurationTests.java +++ b/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointAutoConfigurationTests.java @@ -16,11 +16,20 @@ package org.springframework.boot.actuate.autoconfigure.context.properties; +import java.util.Map; + import org.junit.Test; import org.springframework.boot.actuate.context.properties.ConfigurationPropertiesReportEndpoint; +import org.springframework.boot.actuate.context.properties.ConfigurationPropertiesReportEndpoint.ConfigurationPropertiesDescriptor; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +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 org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import static org.assertj.core.api.Assertions.assertThat; @@ -37,8 +46,8 @@ public class ConfigurationPropertiesReportEndpointAutoConfigurationTests { @Test public void runShouldHaveEndpointBean() { - this.contextRunner.run((context) -> assertThat(context) - .hasSingleBean(ConfigurationPropertiesReportEndpoint.class)); + this.contextRunner.withUserConfiguration(Config.class) + .run(validateTestProperties("******", "654321")); } @Test @@ -49,4 +58,64 @@ public class ConfigurationPropertiesReportEndpointAutoConfigurationTests { .doesNotHaveBean(ConfigurationPropertiesReportEndpoint.class)); } + @Test + public void keysToSanitizeCanBeConfiguredViaTheEnvironment() throws Exception { + this.contextRunner.withUserConfiguration(Config.class) + .withPropertyValues("endpoints.configprops.keys-to-sanitize: .*pass.*, property") + .run(validateTestProperties("******", "******")); + } + + private ContextConsumer validateTestProperties(String dbPassword, + String myTestProperty) { + return context -> { + assertThat(context).hasSingleBean( + ConfigurationPropertiesReportEndpoint.class); + ConfigurationPropertiesReportEndpoint endpoint = context + .getBean(ConfigurationPropertiesReportEndpoint.class); + ConfigurationPropertiesDescriptor properties = endpoint + .configurationProperties(); + Map nestedProperties = properties.getBeans() + .get("testProperties").getProperties(); + assertThat(nestedProperties).isNotNull(); + assertThat(nestedProperties.get("dbPassword")).isEqualTo(dbPassword); + assertThat(nestedProperties.get("myTestProperty")).isEqualTo(myTestProperty); + }; + } + + @Configuration + @EnableConfigurationProperties + public static class Config { + + @Bean + public TestProperties testProperties() { + return new TestProperties(); + } + + } + + @ConfigurationProperties("test") + private static class TestProperties { + + private String dbPassword = "123456"; + + private String myTestProperty = "654321"; + + public String getDbPassword() { + return this.dbPassword; + } + + public void setDbPassword(String dbPassword) { + this.dbPassword = dbPassword; + } + + public String getMyTestProperty() { + return this.myTestProperty; + } + + public void setMyTestProperty(String myTestProperty) { + this.myTestProperty = myTestProperty; + } + + } + } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java index 4d7a5ae04a..fdaf881c51 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java @@ -66,7 +66,6 @@ import org.springframework.util.StringUtils; * @since 2.0.0 */ @Endpoint(id = "configprops") -@ConfigurationProperties("endpoints.configprops") public class ConfigurationPropertiesReportEndpoint implements ApplicationContextAware { private static final String CGLIB_FILTER_ID = "cglibFilter"; diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointParentTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointParentTests.java index dcd5c1e2d4..590de45af1 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointParentTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointParentTests.java @@ -48,7 +48,7 @@ public class ConfigurationPropertiesReportEndpointParentTests { ConfigurationPropertiesDescriptor result = endpoint .configurationProperties(); assertThat(result.getBeans().keySet()) - .containsExactlyInAnyOrder("endpoint", "someProperties"); + .containsExactlyInAnyOrder("someProperties"); assertThat((result.getParent().getBeans().keySet())) .containsExactly("testProperties"); }); @@ -68,7 +68,7 @@ public class ConfigurationPropertiesReportEndpointParentTests { ConfigurationPropertiesDescriptor result = endpoint .configurationProperties(); assertThat(result.getBeans().keySet()) - .containsExactlyInAnyOrder("endpoint", "otherProperties"); + .containsExactlyInAnyOrder("otherProperties"); assertThat((result.getParent().getBeans().keySet())) .containsExactly("testProperties"); }); diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointTests.java index 972c410931..5a867ef1c6 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointTests.java @@ -100,25 +100,6 @@ public class ConfigurationPropertiesReportEndpointTests { }); } - @Test - public void keysToSanitizeCanBeConfiguredViaTheEnvironment() throws Exception { - ApplicationContextRunner tester = new ApplicationContextRunner() - .withPropertyValues( - "endpoints.configprops.keys-to-sanitize: .*pass.*, property") - .withUserConfiguration(Config.class); - tester.run((context) -> { - ConfigurationPropertiesReportEndpoint endpoint = context - .getBean(ConfigurationPropertiesReportEndpoint.class); - ConfigurationPropertiesDescriptor properties = endpoint - .configurationProperties(); - Map nestedProperties = properties.getBeans() - .get("testProperties").getProperties(); - assertThat(nestedProperties).isNotNull(); - assertThat(nestedProperties.get("dbPassword")).isEqualTo("******"); - assertThat(nestedProperties.get("myTestProperty")).isEqualTo("******"); - }); - } - @Test @SuppressWarnings("unchecked") public void keySanitizationWithCustomPatternUsingCompositeKeys() throws Exception {