Polish "Fix configuration properties output for actuator"

Closes gh-9052
This commit is contained in:
Stephane Nicoll 2017-05-23 08:37:07 +02:00
parent 7d6293f79d
commit d4a0fe5ff9
2 changed files with 29 additions and 28 deletions

View File

@ -17,13 +17,13 @@
package org.springframework.boot.actuate.endpoint; package org.springframework.boot.actuate.endpoint;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.fasterxml.jackson.databind.BeanDescription; import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationConfig; import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializationFeature;
@ -58,6 +58,7 @@ import org.springframework.util.StringUtils;
* *
* @author Christian Dupuis * @author Christian Dupuis
* @author Dave Syer * @author Dave Syer
* @author Stephane Nicoll
*/ */
@ConfigurationProperties(prefix = "endpoints.configprops") @ConfigurationProperties(prefix = "endpoints.configprops")
public class ConfigurationPropertiesReportEndpoint public class ConfigurationPropertiesReportEndpoint
@ -330,17 +331,18 @@ public class ConfigurationPropertiesReportEndpoint
private boolean isReadable(BeanDescription beanDesc, BeanPropertyWriter writer) { private boolean isReadable(BeanDescription beanDesc, BeanPropertyWriter writer) {
Class<?> parentType = beanDesc.getType().getRawClass(); Class<?> parentType = beanDesc.getType().getRawClass();
JavaType type = writer.getType(); Class<?> type = writer.getType().getRawClass();
AnnotatedMethod setter = findSetter(beanDesc, writer); AnnotatedMethod setter = findSetter(beanDesc, writer);
// If there's a setter, we assume it's OK to report on the value, // 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 // 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 // that its a nested class used solely for binding to config props, so it
// should be kosher. This filter is not used if there is JSON metadata for // should be kosher. Lists and Maps are also auto-detected by default since
// the property, so it's mainly for user-defined beans. // that's what the metadata generator does. This filter is not used if there
// is JSON metadata for the property, so it's mainly for user-defined beans.
return (setter != null) return (setter != null)
|| ClassUtils.getPackageName(parentType).equals(ClassUtils.getPackageName(type.getRawClass())) || ClassUtils.getPackageName(parentType).equals(ClassUtils.getPackageName(type))
|| type.isMapLikeType() || Map.class.isAssignableFrom(type)
|| type.isCollectionLikeType(); || Collection.class.isAssignableFrom(type);
} }
private AnnotatedMethod findSetter(BeanDescription beanDesc, private AnnotatedMethod findSetter(BeanDescription beanDesc,

View File

@ -35,11 +35,13 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
/** /**
* Tests for {@link ConfigurationPropertiesReportEndpoint} serialization. * Tests for {@link ConfigurationPropertiesReportEndpoint} serialization.
* *
* @author Dave Syer * @author Dave Syer
* @author Stephane Nicoll
*/ */
public class ConfigurationPropertiesReportEndpointSerializationTests { public class ConfigurationPropertiesReportEndpointSerializationTests {
@ -199,36 +201,28 @@ public class ConfigurationPropertiesReportEndpointSerializationTests {
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void testOutputAllOnlyGetterProperties() throws Exception { public void testInitializedMapAndList() throws Exception {
this.context.register(OnlyGetterPropertiesConfig.class); this.context.register(InitializedMapAndListPropertiesConfig.class);
EnvironmentTestUtils.addEnvironment(this.context, "foo.map.entryOne:true", EnvironmentTestUtils.addEnvironment(this.context, "foo.map.entryOne:true",
"foo.list[0]:abc"); "foo.list[0]:abc");
this.context.refresh(); this.context.refresh();
ConfigurationPropertiesReportEndpoint report = this.context ConfigurationPropertiesReportEndpoint report = this.context
.getBean(ConfigurationPropertiesReportEndpoint.class); .getBean(ConfigurationPropertiesReportEndpoint.class);
Map<String, Object> properties = report.invoke(); Map<String, Object> properties = report.invoke();
assertThat(properties).containsKeys("foo");
Map<String, Object> nestedProperties = (Map<String, Object>) properties Map<String, Object> nestedProperties = (Map<String, Object>) properties
.get("foo"); .get("foo");
assertThat(nestedProperties).isNotNull(); assertThat(nestedProperties).containsOnlyKeys("prefix", "properties");
System.err.println(nestedProperties);
assertThat(nestedProperties.get("prefix")).isEqualTo("foo"); assertThat(nestedProperties.get("prefix")).isEqualTo("foo");
Map<String, Object> propertiesMap = (Map<String, Object>) nestedProperties Map<String, Object> propertiesMap = (Map<String, Object>) nestedProperties
.get("properties"); .get("properties");
assertThat(propertiesMap).isNotNull(); assertThat(propertiesMap).containsOnlyKeys("bar", "name", "map", "list");
assertThat(propertiesMap).hasSize(4);
String summary = (String) propertiesMap
.get("summary");
assertThat(summary).isNull();
Map<String, Object> map = (Map<String, Object>) propertiesMap Map<String, Object> map = (Map<String, Object>) propertiesMap
.get("map"); .get("map");
assertThat(map).isNotNull(); assertThat(map).containsOnly(entry("entryOne", true));
assertThat(map).hasSize(1);
assertThat(map.get("entryOne")).isEqualTo(true);
List<String> list = (List<String>) propertiesMap List<String> list = (List<String>) propertiesMap
.get("list"); .get("list");
assertThat(list).isNotNull(); assertThat(list).containsExactly("abc");
assertThat(list).hasSize(1);
assertThat(list.get(0)).isEqualTo("abc");
} }
@Configuration @Configuration
@ -328,12 +322,14 @@ public class ConfigurationPropertiesReportEndpointSerializationTests {
@Configuration @Configuration
@Import(Base.class) @Import(Base.class)
public static class OnlyGetterPropertiesConfig { public static class InitializedMapAndListPropertiesConfig {
@Bean @Bean
@ConfigurationProperties(prefix = "foo") @ConfigurationProperties(prefix = "foo")
public OnlyGetterProperties foo() { public InitializedMapAndListProperties foo() {
return new OnlyGetterProperties(); return new InitializedMapAndListProperties();
} }
} }
public static class Foo { public static class Foo {
@ -439,9 +435,11 @@ public class ConfigurationPropertiesReportEndpointSerializationTests {
} }
public static class OnlyGetterProperties extends Foo { public static class InitializedMapAndListProperties extends Foo {
private Map<String, Boolean> map = new HashMap<>();
private List<String> list = new ArrayList<>(); private Map<String, Boolean> map = new HashMap<String, Boolean>();
private List<String> list = new ArrayList<String>();
public Map<String, Boolean> getMap() { public Map<String, Boolean> getMap() {
return this.map; return this.map;
@ -450,6 +448,7 @@ public class ConfigurationPropertiesReportEndpointSerializationTests {
public List<String> getList() { public List<String> getList() {
return this.list; return this.list;
} }
} }
} }