From e1893f66cebcf4198aa800f2ae5c39b937d65ece Mon Sep 17 00:00:00 2001 From: Lari Hotari Date: Tue, 12 Apr 2016 21:42:29 -0400 Subject: [PATCH] Extract AbstractMvcEndpoint class Extract common functionality from Spring MVC only endpoints. See gh-5670 --- .../endpoint/mvc/AbstractMvcEndpoint.java | 113 ++++++++++++++++++ .../actuate/endpoint/mvc/DocsMvcEndpoint.java | 68 +---------- .../endpoint/mvc/HalJsonMvcEndpoint.java | 73 +---------- .../endpoint/mvc/JolokiaMvcEndpoint.java | 68 +---------- .../endpoint/mvc/LogFileMvcEndpoint.java | 66 +--------- 5 files changed, 129 insertions(+), 259 deletions(-) create mode 100644 spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/AbstractMvcEndpoint.java diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/AbstractMvcEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/AbstractMvcEndpoint.java new file mode 100644 index 0000000000..26ee8c2b7f --- /dev/null +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/AbstractMvcEndpoint.java @@ -0,0 +1,113 @@ +/* + * Copyright 2012-2016 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.mvc; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +import org.springframework.boot.actuate.endpoint.Endpoint; +import org.springframework.boot.actuate.endpoint.EndpointProperties; +import org.springframework.context.EnvironmentAware; +import org.springframework.core.env.Environment; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +/** + * Abstract base class for {@link MvcEndpoint} implementations without a backing + * {@link Endpoint}. + * + * @author Phillip Webb + * @author Lari Hotari + * @since 1.4.0 + */ +public abstract class AbstractMvcEndpoint extends WebMvcConfigurerAdapter + implements MvcEndpoint, EnvironmentAware { + + private Environment environment; + + /** + * Endpoint URL path. + */ + @NotNull + @Pattern(regexp = "/.*|^$", message = "Path must start with /") + private String path; + + /** + * Enable the endpoint. + */ + private Boolean enabled; + + /** + * Mark if the endpoint exposes sensitive information. + */ + private Boolean sensitive; + + private final boolean sensitiveDefault; + + public AbstractMvcEndpoint(String path, boolean sensitive) { + this.path = path; + this.sensitiveDefault = sensitive; + } + + public AbstractMvcEndpoint(String path, boolean sensitive, boolean enabled) { + this.path = path; + this.sensitiveDefault = sensitive; + this.enabled = enabled; + } + + @Override + public void setEnvironment(Environment environment) { + this.environment = environment; + } + + protected final Environment getEnvironment() { + return this.environment; + } + + @Override + public String getPath() { + return this.path; + } + + public void setPath(String path) { + this.path = path; + } + + public boolean isEnabled() { + return EndpointProperties.isEnabled(this.environment, this.enabled); + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + @Override + public boolean isSensitive() { + return EndpointProperties.isSensitive(this.environment, this.sensitive, + this.sensitiveDefault); + } + + public void setSensitive(Boolean sensitive) { + this.sensitive = sensitive; + } + + @Override + @SuppressWarnings("rawtypes") + public Class getEndpointType() { + return null; + } + +} diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/DocsMvcEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/DocsMvcEndpoint.java index 3873ff1b52..06b009d1cc 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/DocsMvcEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/DocsMvcEndpoint.java @@ -16,15 +16,10 @@ package org.springframework.boot.actuate.endpoint.mvc; -import org.springframework.boot.actuate.endpoint.Endpoint; -import org.springframework.boot.actuate.endpoint.EndpointProperties; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.EnvironmentAware; -import org.springframework.core.env.Environment; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; /** * {@link MvcEndpoint} to expose actuator documentation. @@ -33,95 +28,42 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter * @since 1.3.0 */ @ConfigurationProperties("endpoints.docs") -public class DocsMvcEndpoint extends WebMvcConfigurerAdapter - implements MvcEndpoint, EnvironmentAware { +public class DocsMvcEndpoint extends AbstractMvcEndpoint { private static final String DOCS_LOCATION = "classpath:/META-INF/resources/spring-boot-actuator/docs/"; - private Environment environment; - - /** - * Endpoint URL path. - */ - private String path = "/docs"; - - /** - * Enable the endpoint. - */ - private boolean enabled = true; - - /** - * Mark if the endpoint exposes sensitive information. - */ - private Boolean sensitive; - private final ManagementServletContext managementServletContext; private Curies curies = new Curies(); - @Override - public void setEnvironment(Environment environment) { - this.environment = environment; - } - public Curies getCuries() { return this.curies; } public DocsMvcEndpoint(ManagementServletContext managementServletContext) { + super("/docs", false); this.managementServletContext = managementServletContext; } @RequestMapping(value = "/", produces = MediaType.TEXT_HTML_VALUE) public String browse() { - return "forward:" + this.managementServletContext.getContextPath() + this.path + return "forward:" + this.managementServletContext.getContextPath() + getPath() + "/index.html"; } @RequestMapping(value = "", produces = MediaType.TEXT_HTML_VALUE) public String redirect() { - return "redirect:" + this.managementServletContext.getContextPath() + this.path + return "redirect:" + this.managementServletContext.getContextPath() + getPath() + "/"; } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler( - this.managementServletContext.getContextPath() + this.path + "/**") + this.managementServletContext.getContextPath() + getPath() + "/**") .addResourceLocations(DOCS_LOCATION); } - public void setPath(String path) { - this.path = path; - } - - @Override - public String getPath() { - return this.path; - } - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Override - public boolean isSensitive() { - return EndpointProperties.isSensitive(this.environment, this.sensitive, false); - } - - public void setSensitive(Boolean sensitive) { - this.sensitive = sensitive; - } - - @Override - public Class> getEndpointType() { - return null; - } - /** * Properties of the default CurieProvider (used for adding docs links). If enabled, * all unqualified rels will pick up a prefix and a curie template pointing to the diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HalJsonMvcEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HalJsonMvcEndpoint.java index 8f36f366db..5f9d3afa82 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HalJsonMvcEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HalJsonMvcEndpoint.java @@ -16,20 +16,12 @@ package org.springframework.boot.actuate.endpoint.mvc; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Pattern; - -import org.springframework.boot.actuate.endpoint.Endpoint; -import org.springframework.boot.actuate.endpoint.EndpointProperties; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.EnvironmentAware; -import org.springframework.core.env.Environment; import org.springframework.hateoas.ResourceSupport; import org.springframework.http.MediaType; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; /** * {@link MvcEndpoint} to expose HAL-formatted JSON. @@ -40,41 +32,16 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter * @since 1.3.0 */ @ConfigurationProperties("endpoints.actuator") -public class HalJsonMvcEndpoint extends WebMvcConfigurerAdapter - implements MvcEndpoint, EnvironmentAware { - - private Environment environment; - - /** - * Endpoint URL path. - */ - @NotNull - @Pattern(regexp = "^$|/.*", message = "Path must be empty or start with /") - private String path; - - /** - * Enable the endpoint. - */ - private boolean enabled = true; - - /** - * Mark if the endpoint exposes sensitive information. - */ - private Boolean sensitive; - +public class HalJsonMvcEndpoint extends AbstractMvcEndpoint { private final ManagementServletContext managementServletContext; public HalJsonMvcEndpoint(ManagementServletContext managementServletContext) { + super(getDefaultPath(managementServletContext), false); this.managementServletContext = managementServletContext; - this.path = getDefaultPath(managementServletContext); } - @Override - public void setEnvironment(Environment environment) { - this.environment = environment; - } - - private String getDefaultPath(ManagementServletContext managementServletContext) { + private static String getDefaultPath( + ManagementServletContext managementServletContext) { if (StringUtils.hasText(managementServletContext.getContextPath())) { return ""; } @@ -87,39 +54,7 @@ public class HalJsonMvcEndpoint extends WebMvcConfigurerAdapter return new ResourceSupport(); } - public void setPath(String path) { - this.path = path; - } - - @Override - public String getPath() { - return this.path; - } - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Override - public boolean isSensitive() { - return EndpointProperties.isSensitive(this.environment, this.sensitive, false); - } - - public void setSensitive(Boolean sensitive) { - this.sensitive = sensitive; - } - - @Override - public Class> getEndpointType() { - return null; - } - protected final ManagementServletContext getManagementServletContext() { return this.managementServletContext; } - } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpoint.java index d2879d6628..0ab3dd7b59 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpoint.java @@ -22,20 +22,14 @@ import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Pattern; import org.jolokia.http.AgentServlet; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; -import org.springframework.boot.actuate.endpoint.Endpoint; -import org.springframework.boot.actuate.endpoint.EndpointProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; -import org.springframework.context.EnvironmentAware; -import org.springframework.core.env.Environment; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.ServletContextAware; import org.springframework.web.servlet.ModelAndView; @@ -50,31 +44,12 @@ import org.springframework.web.util.UrlPathHelper; */ @ConfigurationProperties(prefix = "endpoints.jolokia", ignoreUnknownFields = false) @HypermediaDisabled -public class JolokiaMvcEndpoint implements MvcEndpoint, InitializingBean, - ApplicationContextAware, ServletContextAware, EnvironmentAware { - - private Environment environment; - - /** - * Endpoint URL path. - */ - @NotNull - @Pattern(regexp = "/.*", message = "Path must start with /") - private String path = "/jolokia"; - - /** - * Enable the endpoint. - */ - private boolean enabled = true; - - /** - * Mark if the endpoint exposes sensitive information. - */ - private Boolean sensitive; - +public class JolokiaMvcEndpoint extends AbstractMvcEndpoint + implements InitializingBean, ApplicationContextAware, ServletContextAware { private final ServletWrappingController controller = new ServletWrappingController(); public JolokiaMvcEndpoint() { + super("/jolokia", true); this.controller.setServletClass(AgentServlet.class); this.controller.setServletName("jolokia"); } @@ -99,43 +74,6 @@ public class JolokiaMvcEndpoint implements MvcEndpoint, InitializingBean, this.controller.setApplicationContext(context); } - @Override - public void setEnvironment(Environment environment) { - this.environment = environment; - } - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Override - public boolean isSensitive() { - return EndpointProperties.isSensitive(this.environment, this.sensitive, true); - } - - public void setSensitive(Boolean sensitive) { - this.sensitive = sensitive; - } - - @Override - public String getPath() { - return this.path; - } - - public void setPath(String path) { - this.path = path; - } - - @Override - @SuppressWarnings("rawtypes") - public Class getEndpointType() { - return null; - } - @RequestMapping("/**") public ModelAndView handle(HttpServletRequest request, HttpServletResponse response) throws Exception { diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/LogFileMvcEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/LogFileMvcEndpoint.java index 338d2a8d85..f41b6bebbf 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/LogFileMvcEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/LogFileMvcEndpoint.java @@ -22,18 +22,12 @@ import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Pattern; 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.EndpointProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.logging.LogFile; -import org.springframework.context.EnvironmentAware; -import org.springframework.core.env.Environment; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.http.HttpStatus; @@ -52,64 +46,18 @@ import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; * @since 1.3.0 */ @ConfigurationProperties(prefix = "endpoints.logfile") -public class LogFileMvcEndpoint implements MvcEndpoint, EnvironmentAware { +public class LogFileMvcEndpoint extends AbstractMvcEndpoint { private static final Log logger = LogFactory.getLog(LogFileMvcEndpoint.class); - /** - * Endpoint URL path. - */ - @NotNull - @Pattern(regexp = "/.*", message = "Path must start with /") - private String path = "/logfile"; - - /** - * Enable the endpoint. - */ - private boolean enabled = true; - - /** - * Mark if the endpoint exposes sensitive information. - */ - private Boolean sensitive; - /** * External Logfile to be accessed. Can be used if the logfile is written by output * redirect and not by the logging-system itself. */ private File externalFile; - private Environment environment; - - @Override - public void setEnvironment(Environment environment) { - this.environment = environment; - } - - @Override - public String getPath() { - return this.path; - } - - public void setPath(String path) { - this.path = path; - } - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Override - public boolean isSensitive() { - return EndpointProperties.isSensitive(this.environment, this.sensitive, true); - } - - public void setSensitive(Boolean sensitive) { - this.sensitive = sensitive; + public LogFileMvcEndpoint() { + super("/logfile", true); } public File getExternalFile() { @@ -120,12 +68,6 @@ public class LogFileMvcEndpoint implements MvcEndpoint, EnvironmentAware { this.externalFile = externalFile; } - @Override - @SuppressWarnings("rawtypes") - public Class getEndpointType() { - return null; - } - @RequestMapping(method = { RequestMethod.GET, RequestMethod.HEAD }) public void invoke(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { @@ -147,7 +89,7 @@ public class LogFileMvcEndpoint implements MvcEndpoint, EnvironmentAware { if (this.externalFile != null) { return new FileSystemResource(this.externalFile); } - LogFile logFile = LogFile.get(this.environment); + LogFile logFile = LogFile.get(getEnvironment()); if (logFile == null) { logger.debug("Missing 'logging.file' or 'logging.path' properties"); return null;