diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpoint.java index b1eb293dd7..947bf8995c 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpoint.java @@ -324,9 +324,7 @@ public class ConfigurationPropertiesReportEndpoint extends private boolean isReadable(BeanDescription beanDesc, BeanPropertyWriter writer) { String parentType = beanDesc.getType().getRawClass().getName(); String type = writer.getPropertyType().getName(); - AnnotatedMethod setter = beanDesc.findMethod( - "set" + StringUtils.capitalize(writer.getName()), - new Class[] { writer.getPropertyType() }); + AnnotatedMethod setter = findSetter(beanDesc, writer); // If there's a setter, we assume it's OK to report on the value, // similarly, if there's no setter but the package names match, we assume // that its a nested class used solely for binding to config props, so it @@ -336,6 +334,19 @@ public class ConfigurationPropertiesReportEndpoint extends || ClassUtils.getPackageName(parentType).equals( ClassUtils.getPackageName(type)); } + + private AnnotatedMethod findSetter(BeanDescription beanDesc, + BeanPropertyWriter writer) { + String name = "set" + StringUtils.capitalize(writer.getName()); + Class type = writer.getPropertyType(); + AnnotatedMethod setter = beanDesc.findMethod(name, new Class[] { type }); + // The enabled property of endpoints returns a boolean primitive but is set + // using a Boolean class + if (setter == null && type.equals(Boolean.TYPE)) { + setter = beanDesc.findMethod(name, new Class[] { Boolean.class }); + } + return setter; + } } /** diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpointTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpointTests.java index 87e2cf0d05..11cf9eaae2 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpointTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpointTests.java @@ -26,6 +26,7 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -151,6 +152,17 @@ public class ConfigurationPropertiesReportEndpointTests extends assertEquals("******", nestedProperties.get("myTestProperty")); } + @Test + @SuppressWarnings("unchecked") + public void mixedBoolean() throws Exception { + ConfigurationPropertiesReportEndpoint report = getEndpointBean(); + Map properties = report.invoke(); + Map nestedProperties = (Map) ((Map) properties + .get("testProperties")).get("properties"); + System.out.println(nestedProperties); + assertThat(nestedProperties.get("mixedBoolean"), equalTo((Object) true)); + } + @Configuration @EnableConfigurationProperties public static class Parent { @@ -183,6 +195,8 @@ public class ConfigurationPropertiesReportEndpointTests extends private String myTestProperty = "654321"; + private Boolean mixedBoolean = true; + public String getDbPassword() { return this.dbPassword; } @@ -199,5 +213,13 @@ public class ConfigurationPropertiesReportEndpointTests extends this.myTestProperty = myTestProperty; } + public boolean isMixedBoolean() { + return (this.mixedBoolean == null ? false : this.mixedBoolean); + } + + public void setMixedBoolean(Boolean mixedBoolean) { + this.mixedBoolean = mixedBoolean; + } + } }