From 3911ce3e2992251c211e962ddc7e57ec798c3268 Mon Sep 17 00:00:00 2001 From: Christian Dupuis Date: Fri, 31 Jan 2014 11:50:57 +0100 Subject: [PATCH] Filter out CGLIB generated bean properties from configuration properties report --- ...ConfigurationPropertiesReportEndpoint.java | 64 ++++++++++++++++++- 1 file changed, 61 insertions(+), 3 deletions(-) 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 02ff5b5fa3..a4c4ffd972 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 @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2014 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. @@ -28,6 +28,13 @@ import org.springframework.util.Assert; import org.springframework.util.StringUtils; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.introspect.Annotated; +import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; +import com.fasterxml.jackson.databind.ser.BeanPropertyWriter; +import com.fasterxml.jackson.databind.ser.PropertyWriter; +import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter; +import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider; /** * {@link Endpoint} to expose application properties from {@link ConfigurationProperties} @@ -44,6 +51,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; public class ConfigurationPropertiesReportEndpoint extends AbstractEndpoint> implements ApplicationContextAware { + private static final String CGLIB_FILTER_ID = "cglibFilter"; + private String[] keysToSanitize = new String[] { "password", "secret" }; private ApplicationContext context; @@ -72,14 +81,15 @@ public class ConfigurationPropertiesReportEndpoint extends } @SuppressWarnings("unchecked") - private Map extract(ApplicationContext context) { - + protected Map extract(ApplicationContext context) { Map result = new HashMap(); Map beans = context .getBeansWithAnnotation(ConfigurationProperties.class); // Serialize beans into map structure and sanitize values ObjectMapper mapper = new ObjectMapper(); + configureObjectMapper(mapper); + for (Map.Entry entry : beans.entrySet()) { String beanName = entry.getKey(); Object bean = entry.getValue(); @@ -97,6 +107,16 @@ public class ConfigurationPropertiesReportEndpoint extends return result; } + protected void configureObjectMapper(ObjectMapper mapper) { + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + + // configure PropertyFiler to make sure Jackson doesn't process CGLIB generated + // bean properties + mapper.setAnnotationIntrospector(new CglibAnnotationIntrospector()); + mapper.setFilters(new SimpleFilterProvider().addFilter(CGLIB_FILTER_ID, + new CglibBeanPropertyFilter())); + } + private String extractPrefix(Object bean) { ConfigurationProperties annotation = AnnotationUtils.findAnnotation( bean.getClass(), ConfigurationProperties.class); @@ -126,4 +146,42 @@ public class ConfigurationPropertiesReportEndpoint extends return object; } + /** + * Extension to {@link JacksonAnnotationIntrospector} to supporess CGLIB generated + * bean properties. + */ + private static class CglibAnnotationIntrospector extends + JacksonAnnotationIntrospector { + + @Override + public Object findFilterId(Annotated a) { + Object id = super.findFilterId(a); + if (id == null) { + id = CGLIB_FILTER_ID; + } + return id; + } + } + + /** + * {@link SimpleBeanPropertyFilter} to filter out all bean properties whose names + * start with '$$'. + */ + private static class CglibBeanPropertyFilter extends SimpleBeanPropertyFilter { + + @Override + protected boolean include(BeanPropertyWriter writer) { + return include(writer.getFullName().getSimpleName()); + } + + @Override + protected boolean include(PropertyWriter writer) { + return include(writer.getFullName().getSimpleName()); + } + + private boolean include(String name) { + return !name.startsWith("$$"); + } + } + }