Rework auto-configure report
Update the auto-configuration report to improve log formatting and to separate the internal report data-structure from the JSON friendly endpoint data-structure.
This commit is contained in:
@@ -40,11 +40,11 @@ import org.springframework.boot.actuate.metrics.InMemoryMetricRepository;
|
||||
import org.springframework.boot.actuate.metrics.MetricRepository;
|
||||
import org.springframework.boot.actuate.trace.InMemoryTraceRepository;
|
||||
import org.springframework.boot.actuate.trace.TraceRepository;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationReport;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.report.AutoConfigurationReport;
|
||||
import org.springframework.boot.bind.PropertiesConfigurationFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -57,7 +57,7 @@ import org.springframework.http.MediaType;
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for common management
|
||||
* {@link Endpoint}s.
|
||||
*
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @author Greg Turnquist
|
||||
|
||||
@@ -16,29 +16,114 @@
|
||||
|
||||
package org.springframework.boot.actuate.endpoint;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.report.AutoConfigurationReport;
|
||||
import org.springframework.boot.actuate.endpoint.AutoConfigurationReportEndpoint.Report;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationReport;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationReport.ConditionAndOutcome;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationReport.ConditionAndOutcomes;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Condition;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
|
||||
/**
|
||||
* Endpoint to serve up autoconfiguration report if actuator is on the classpath.
|
||||
* {@link Endpoint} to expose the {@link AutoConfigurationReport}.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@ConfigurationProperties(name = "endpoints.autoconfigurationreport", ignoreUnknownFields = false)
|
||||
public class AutoConfigurationReportEndpoint extends
|
||||
AbstractEndpoint<AutoConfigurationReport> {
|
||||
public class AutoConfigurationReportEndpoint extends AbstractEndpoint<Report> {
|
||||
|
||||
@Autowired
|
||||
private AutoConfigurationReport autoConfigurationReport;
|
||||
|
||||
public AutoConfigurationReportEndpoint() {
|
||||
super("/auto");
|
||||
super("/autoconfigurationreport");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AutoConfigurationReport invoke() {
|
||||
return this.autoConfigurationReport;
|
||||
public Report invoke() {
|
||||
return new Report(this.autoConfigurationReport);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapts {@link AutoConfigurationReport} to a JSON friendly structure.
|
||||
*/
|
||||
@JsonPropertyOrder({ "positiveMatches", "negativeMatches" })
|
||||
public static class Report {
|
||||
|
||||
private MultiValueMap<String, MessageAndCondition> positiveMatches;
|
||||
|
||||
private MultiValueMap<String, MessageAndCondition> negativeMatches;
|
||||
|
||||
public Report(AutoConfigurationReport report) {
|
||||
this.positiveMatches = new LinkedMultiValueMap<String, MessageAndCondition>();
|
||||
this.negativeMatches = new LinkedMultiValueMap<String, MessageAndCondition>();
|
||||
for (Map.Entry<String, ConditionAndOutcomes> entry : report
|
||||
.getConditionAndOutcomesBySource().entrySet()) {
|
||||
dunno(entry.getValue().isFullMatch() ? this.positiveMatches
|
||||
: this.negativeMatches, entry.getKey(), entry.getValue());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void dunno(MultiValueMap<String, MessageAndCondition> map, String source,
|
||||
ConditionAndOutcomes conditionAndOutcomes) {
|
||||
String name = ClassUtils.getShortName(source);
|
||||
for (ConditionAndOutcome conditionAndOutcome : conditionAndOutcomes) {
|
||||
map.add(name, new MessageAndCondition(conditionAndOutcome));
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, List<MessageAndCondition>> getPositiveMatches() {
|
||||
return this.positiveMatches;
|
||||
}
|
||||
|
||||
public Map<String, List<MessageAndCondition>> getNegativeMatches() {
|
||||
return this.negativeMatches;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapts {@link ConditionAndOutcome} to a JSON friendly structure.
|
||||
*/
|
||||
@JsonPropertyOrder({ "condition", "message" })
|
||||
public static class MessageAndCondition {
|
||||
|
||||
private final String condition;
|
||||
|
||||
private final String message;
|
||||
|
||||
public MessageAndCondition(ConditionAndOutcome conditionAndOutcome) {
|
||||
Condition condition = conditionAndOutcome.getCondition();
|
||||
ConditionOutcome outcome = conditionAndOutcome.getOutcome();
|
||||
this.condition = ClassUtils.getShortName(condition.getClass());
|
||||
if (StringUtils.hasLength(outcome.getMessage())) {
|
||||
this.message = outcome.getMessage();
|
||||
}
|
||||
else {
|
||||
this.message = (outcome.isMatch() ? "matched" : "did not match");
|
||||
}
|
||||
}
|
||||
|
||||
public String getCondition() {
|
||||
return this.condition;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.boot.actuate.autoconfigure;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.boot.TestUtils;
|
||||
import org.springframework.boot.actuate.endpoint.AutoConfigurationReportEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.BeansEndpoint;
|
||||
@@ -29,7 +28,7 @@ import org.springframework.boot.actuate.endpoint.InfoEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.MetricsEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.TraceEndpoint;
|
||||
import org.springframework.boot.autoconfigure.report.AutoConfigurationReport;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationReport;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -66,11 +65,6 @@ public class EndpointAutoConfigurationTests {
|
||||
assertNotNull(this.context.getBean(TraceEndpoint.class));
|
||||
}
|
||||
|
||||
@Test(expected = NoSuchBeanDefinitionException.class)
|
||||
public void noAutoConfigurationAuditEndpointByDefault() {
|
||||
this.context.getBean(AutoConfigurationReportEndpoint.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void autoconfigurationAuditEndpoints() {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
|
||||
@@ -16,38 +16,62 @@
|
||||
|
||||
package org.springframework.boot.actuate.endpoint;
|
||||
|
||||
import org.springframework.boot.autoconfigure.report.AutoConfigurationReport;
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.endpoint.AutoConfigurationReportEndpoint.Report;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationReport;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Condition;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link AutoConfigurationReportEndpoint}.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class AutoConfigurationReportEndpointTests extends
|
||||
AbstractEndpointTests<AutoConfigurationReportEndpoint> {
|
||||
|
||||
public AutoConfigurationReportEndpointTests() {
|
||||
super(Config.class, AutoConfigurationReportEndpoint.class, "/auto", true,
|
||||
"endpoints.autoconfigurationreport");
|
||||
super(Config.class, AutoConfigurationReportEndpoint.class,
|
||||
"/autoconfigurationreport", true, "endpoints.autoconfigurationreport");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invoke() throws Exception {
|
||||
Report report = getEndpointBean().invoke();
|
||||
assertTrue(report.getPositiveMatches().isEmpty());
|
||||
assertTrue(report.getNegativeMatches().containsKey("a"));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
public static class Config {
|
||||
|
||||
@Bean
|
||||
public AutoConfigurationReport autoConfigurationReport() {
|
||||
return new AutoConfigurationReport();
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@PostConstruct
|
||||
public void setupAutoConfigurationReport() {
|
||||
AutoConfigurationReport report = AutoConfigurationReport.get(this.context
|
||||
.getBeanFactory());
|
||||
report.recordConditionEvaluation("a", mock(Condition.class),
|
||||
mock(ConditionOutcome.class));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AutoConfigurationReportEndpoint endpoint() {
|
||||
return new AutoConfigurationReportEndpoint();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user