From 2c67e06b47d4c04c5e0122eae1615749c72a9c78 Mon Sep 17 00:00:00 2001 From: Christian Dupuis Date: Fri, 29 Nov 2013 14:57:29 +0100 Subject: [PATCH] Move enablement of endpoints into AbstractEndpoint --- .../actuate/endpoint/AbstractEndpoint.java | 25 +++++++++++++++++-- .../AutoConfigurationReportEndpoint.java | 2 +- .../boot/actuate/endpoint/BeansEndpoint.java | 2 +- .../boot/actuate/endpoint/DumpEndpoint.java | 2 +- .../actuate/endpoint/EnvironmentEndpoint.java | 2 +- .../boot/actuate/endpoint/HealthEndpoint.java | 4 +-- .../boot/actuate/endpoint/InfoEndpoint.java | 4 +-- .../actuate/endpoint/JolokiaEndpoint.java | 11 +------- .../actuate/endpoint/MetricsEndpoint.java | 2 +- .../actuate/endpoint/ShutdownEndpoint.java | 18 ++----------- .../boot/actuate/endpoint/TraceEndpoint.java | 2 +- .../endpoint/mvc/EndpointHandlerAdapter.java | 12 ++++++++- .../EndpointWebMvcAutoConfigurationTests.java | 4 +-- .../mvc/EndpointHandlerMappingTests.java | 2 +- 14 files changed, 50 insertions(+), 42 deletions(-) diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/AbstractEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/AbstractEndpoint.java index 9807927b69..dff785b980 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/AbstractEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/AbstractEndpoint.java @@ -47,13 +47,24 @@ public abstract class AbstractEndpoint implements Endpoint { private boolean sensitive; + private boolean enabled = true; + public AbstractEndpoint(String path) { - this(path, true); + this(path, true, true); } - public AbstractEndpoint(String path, boolean sensitive) { + public AbstractEndpoint(String path, boolean sensitive, boolean enabled) { this.path = path; this.sensitive = sensitive; + this.enabled = enabled; + } + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; } @Override @@ -83,4 +94,14 @@ public abstract class AbstractEndpoint implements Endpoint { public HttpMethod[] methods() { return GET_HTTP_METHOD; } + + @Override + public final T invoke() { + if (this.enabled) { + return doInvoke(); + } + throw new EndpointDisabledException(); + } + + protected abstract T doInvoke(); } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/AutoConfigurationReportEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/AutoConfigurationReportEndpoint.java index 967373fc2b..a6445182ee 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/AutoConfigurationReportEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/AutoConfigurationReportEndpoint.java @@ -52,7 +52,7 @@ public class AutoConfigurationReportEndpoint extends AbstractEndpoint { } @Override - public Report invoke() { + protected Report doInvoke() { return new Report(this.autoConfigurationReport); } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/BeansEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/BeansEndpoint.java index 81108bb769..6ee2000f30 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/BeansEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/BeansEndpoint.java @@ -56,7 +56,7 @@ public class BeansEndpoint extends AbstractEndpoint implements } @Override - public String invoke() { + protected String doInvoke() { return this.liveBeansView.getSnapshotAsJson(); } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/DumpEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/DumpEndpoint.java index 7ac1744b9f..15fbc55e27 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/DumpEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/DumpEndpoint.java @@ -39,7 +39,7 @@ public class DumpEndpoint extends AbstractEndpoint> { } @Override - public List invoke() { + protected List doInvoke() { return Arrays.asList(ManagementFactory.getThreadMXBean().dumpAllThreads(true, true)); } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/EnvironmentEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/EnvironmentEndpoint.java index f841dbfb54..1e0e8d600b 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/EnvironmentEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/EnvironmentEndpoint.java @@ -47,7 +47,7 @@ public class EnvironmentEndpoint extends AbstractEndpoint> i } @Override - public Map invoke() { + protected Map doInvoke() { Map result = new LinkedHashMap(); result.put("profiles", this.environment.getActiveProfiles()); for (PropertySource source : getPropertySources()) { diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/HealthEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/HealthEndpoint.java index a1b9885fa9..9863bc6243 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/HealthEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/HealthEndpoint.java @@ -36,13 +36,13 @@ public class HealthEndpoint extends AbstractEndpoint { * @param indicator the health indicator */ public HealthEndpoint(HealthIndicator indicator) { - super("/health", false); + super("/health", false, true); Assert.notNull(indicator, "Indicator must not be null"); this.indicator = indicator; } @Override - public T invoke() { + protected T doInvoke() { return this.indicator.health(); } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/InfoEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/InfoEndpoint.java index 6e57e214fc..06ae714086 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/InfoEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/InfoEndpoint.java @@ -39,13 +39,13 @@ public class InfoEndpoint extends AbstractEndpoint> { * @param info the info to expose */ public InfoEndpoint(Map info) { - super("/info", false); + super("/info", false, true); Assert.notNull(info, "Info must not be null"); this.info = info; } @Override - public Map invoke() { + protected Map doInvoke() { Map info = new LinkedHashMap(this.info); info.putAll(getAdditionalInfo()); return info; diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/JolokiaEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/JolokiaEndpoint.java index d9e1eed62c..fbdc991c27 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/JolokiaEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/JolokiaEndpoint.java @@ -28,14 +28,12 @@ import org.springframework.http.HttpMethod; @ConfigurationProperties(name = "endpoints.jolokia", ignoreUnknownFields = false) public class JolokiaEndpoint extends AbstractEndpoint { - private boolean enabled = true; - public JolokiaEndpoint() { super("/jolokia"); } @Override - public String invoke() { + protected String doInvoke() { return null; } @@ -44,11 +42,4 @@ public class JolokiaEndpoint extends AbstractEndpoint { return NO_HTTP_METHOD; } - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/MetricsEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/MetricsEndpoint.java index fff41f266c..47f8234655 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/MetricsEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/MetricsEndpoint.java @@ -45,7 +45,7 @@ public class MetricsEndpoint extends AbstractEndpoint> { } @Override - public Map invoke() { + protected Map doInvoke() { Map result = new LinkedHashMap(); for (Metric metric : this.metrics.metrics()) { result.put(metric.getName(), metric.getValue()); diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ShutdownEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ShutdownEndpoint.java index d74075da2b..fc7be0a833 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ShutdownEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ShutdownEndpoint.java @@ -38,22 +38,15 @@ public class ShutdownEndpoint extends AbstractEndpoint> impl private ConfigurableApplicationContext context; - private boolean enabled = false; - /** * Create a new {@link ShutdownEndpoint} instance. */ public ShutdownEndpoint() { - super("/shutdown"); + super("/shutdown", true, false); } @Override - public Map invoke() { - - if (!this.enabled) { - return Collections. singletonMap("message", - "Shutdown not enabled, sorry."); - } + protected Map doInvoke() { if (this.context == null) { return Collections. singletonMap("message", @@ -89,11 +82,4 @@ public class ShutdownEndpoint extends AbstractEndpoint> impl return POST_HTTP_METHOD; } - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/TraceEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/TraceEndpoint.java index 02e51567bb..d21f4acd0b 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/TraceEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/TraceEndpoint.java @@ -45,7 +45,7 @@ public class TraceEndpoint extends AbstractEndpoint> { } @Override - public List invoke() { + protected List doInvoke() { return this.repository.findAll(); } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EndpointHandlerAdapter.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EndpointHandlerAdapter.java index fd87e531bc..2b7e2bb33c 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EndpointHandlerAdapter.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EndpointHandlerAdapter.java @@ -29,6 +29,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.actuate.endpoint.Endpoint; +import org.springframework.boot.actuate.endpoint.EndpointDisabledException; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; @@ -40,6 +41,7 @@ import org.springframework.web.servlet.HandlerAdapter; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; import org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor; +import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException; import com.fasterxml.jackson.databind.SerializationFeature; @@ -88,7 +90,15 @@ public final class EndpointHandlerAdapter implements HandlerAdapter { private void handle(HttpServletRequest request, HttpServletResponse response, Endpoint endpoint) throws Exception { - Object result = endpoint.invoke(); + Object result = null; + try { + result = endpoint.invoke(); + } + catch (EndpointDisabledException e) { + // Disabled endpoints should get mapped to a HTTP 404 + throw new NoSuchRequestHandlingMethodException(request); + } + Class resultClass = result.getClass(); List mediaTypes = getMediaTypes(request, endpoint, resultClass); diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java index 8961f15cc7..80a439e32c 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java @@ -195,9 +195,9 @@ public class EndpointWebMvcAutoConfigurationTests { @Bean public Endpoint testEndpoint() { - return new AbstractEndpoint("/endpoint", false) { + return new AbstractEndpoint("/endpoint", false, true) { @Override - public String invoke() { + public String doInvoke() { return "endpointoutput"; } }; diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/EndpointHandlerMappingTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/EndpointHandlerMappingTests.java index 3e65373486..05311da42f 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/EndpointHandlerMappingTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/EndpointHandlerMappingTests.java @@ -105,7 +105,7 @@ public class EndpointHandlerMappingTests { } @Override - public Object invoke() { + public Object doInvoke() { return null; }