From 7f1ff968a117df4eaa737e862e572838d3c7face Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Tue, 11 Oct 2016 15:00:58 -0700 Subject: [PATCH] Support NamedMvcEndpoints Introduce a new NamedMvcEndpoint interface which can be used when an MvcEndpoint also has a logical name. Existing MvcEndpoints have been reworked to implement the NamedMvcEndpoint interface. Fixes gh-7156 --- .../mvc/AbstractEndpointMvcAdapter.java | 7 ++- .../mvc/AbstractNamedMvcEndpoint.java | 52 +++++++++++++++++++ .../actuate/endpoint/mvc/DocsMvcEndpoint.java | 4 +- .../endpoint/mvc/HalJsonMvcEndpoint.java | 4 +- .../endpoint/mvc/HeapdumpMvcEndpoint.java | 4 +- .../endpoint/mvc/JolokiaMvcEndpoint.java | 4 +- .../endpoint/mvc/LogFileMvcEndpoint.java | 4 +- .../actuate/endpoint/mvc/MvcEndpoint.java | 1 + .../endpoint/mvc/NamedMvcEndpoint.java | 37 +++++++++++++ 9 files changed, 106 insertions(+), 11 deletions(-) create mode 100644 spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/AbstractNamedMvcEndpoint.java create mode 100644 spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/NamedMvcEndpoint.java diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/AbstractEndpointMvcAdapter.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/AbstractEndpointMvcAdapter.java index a90587d58f8..1415a63e282 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/AbstractEndpointMvcAdapter.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/AbstractEndpointMvcAdapter.java @@ -30,7 +30,7 @@ import org.springframework.util.Assert; * @since 1.3.0 */ public abstract class AbstractEndpointMvcAdapter> - implements MvcEndpoint { + implements NamedMvcEndpoint { private final E delegate; @@ -60,6 +60,11 @@ public abstract class AbstractEndpointMvcAdapter> return this.delegate; } + @Override + public String getName() { + return this.delegate.getId(); + } + @Override public String getPath() { return (this.path != null ? this.path : "/" + this.delegate.getId()); diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/AbstractNamedMvcEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/AbstractNamedMvcEndpoint.java new file mode 100644 index 00000000000..2c791133574 --- /dev/null +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/AbstractNamedMvcEndpoint.java @@ -0,0 +1,52 @@ +/* + * 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 org.springframework.boot.actuate.endpoint.Endpoint; +import org.springframework.util.Assert; + +/** + * Abstract base class for {@link NamedMvcEndpoint} implementations without a backing + * {@link Endpoint}. + * + * @author Madhura Bhave + * @since 1.5.0 + */ +public class AbstractNamedMvcEndpoint extends AbstractMvcEndpoint + implements NamedMvcEndpoint { + + private final String name; + + public AbstractNamedMvcEndpoint(String name, String path, boolean sensitive) { + super(path, sensitive); + Assert.hasLength(name, "Name must not be empty"); + this.name = name; + } + + public AbstractNamedMvcEndpoint(String name, String path, boolean sensitive, + boolean enabled) { + super(path, sensitive, enabled); + Assert.hasLength(name, "Name must not be empty"); + this.name = name; + } + + @Override + public String getName() { + return this.name; + } + +} 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 06b009d1ccf..2d8261b161f 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 @@ -28,7 +28,7 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry * @since 1.3.0 */ @ConfigurationProperties("endpoints.docs") -public class DocsMvcEndpoint extends AbstractMvcEndpoint { +public class DocsMvcEndpoint extends AbstractNamedMvcEndpoint { private static final String DOCS_LOCATION = "classpath:/META-INF/resources/spring-boot-actuator/docs/"; @@ -41,7 +41,7 @@ public class DocsMvcEndpoint extends AbstractMvcEndpoint { } public DocsMvcEndpoint(ManagementServletContext managementServletContext) { - super("/docs", false); + super("docs", "/docs", false); this.managementServletContext = managementServletContext; } 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 ec0b46185da..bb1bcd4648d 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 @@ -32,12 +32,12 @@ import org.springframework.web.bind.annotation.ResponseBody; * @since 1.3.0 */ @ConfigurationProperties("endpoints.actuator") -public class HalJsonMvcEndpoint extends AbstractMvcEndpoint { +public class HalJsonMvcEndpoint extends AbstractNamedMvcEndpoint { private final ManagementServletContext managementServletContext; public HalJsonMvcEndpoint(ManagementServletContext managementServletContext) { - super(getDefaultPath(managementServletContext), false); + super("actuator", getDefaultPath(managementServletContext), false); this.managementServletContext = managementServletContext; } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HeapdumpMvcEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HeapdumpMvcEndpoint.java index f0ca61e6986..210ed279abb 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HeapdumpMvcEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HeapdumpMvcEndpoint.java @@ -56,7 +56,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; */ @ConfigurationProperties("endpoints.heapdump") @HypermediaDisabled -public class HeapdumpMvcEndpoint extends AbstractMvcEndpoint { +public class HeapdumpMvcEndpoint extends AbstractNamedMvcEndpoint { private final long timeout; @@ -69,7 +69,7 @@ public class HeapdumpMvcEndpoint extends AbstractMvcEndpoint { } protected HeapdumpMvcEndpoint(long timeout) { - super("/heapdump", true); + super("heapdump", "/heapdump", true); this.timeout = timeout; } 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 0ab3dd7b59b..811d8e5cac5 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 @@ -44,12 +44,12 @@ import org.springframework.web.util.UrlPathHelper; */ @ConfigurationProperties(prefix = "endpoints.jolokia", ignoreUnknownFields = false) @HypermediaDisabled -public class JolokiaMvcEndpoint extends AbstractMvcEndpoint +public class JolokiaMvcEndpoint extends AbstractNamedMvcEndpoint implements InitializingBean, ApplicationContextAware, ServletContextAware { private final ServletWrappingController controller = new ServletWrappingController(); public JolokiaMvcEndpoint() { - super("/jolokia", true); + super("jolokia", "/jolokia", true); this.controller.setServletClass(AgentServlet.class); this.controller.setServletName("jolokia"); } 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 b25a55f5521..95738bac5fb 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 @@ -46,7 +46,7 @@ import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; * @since 1.3.0 */ @ConfigurationProperties(prefix = "endpoints.logfile") -public class LogFileMvcEndpoint extends AbstractMvcEndpoint { +public class LogFileMvcEndpoint extends AbstractNamedMvcEndpoint { private static final Log logger = LogFactory.getLog(LogFileMvcEndpoint.class); @@ -57,7 +57,7 @@ public class LogFileMvcEndpoint extends AbstractMvcEndpoint { private File externalFile; public LogFileMvcEndpoint() { - super("/logfile", true); + super("logfile", "/logfile", true); } public File getExternalFile() { diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/MvcEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/MvcEndpoint.java index 2bb30de71c1..4255a8e0f10 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/MvcEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/MvcEndpoint.java @@ -31,6 +31,7 @@ import org.springframework.http.ResponseEntity; * {@link EndpointHandlerMapping}). * * @author Dave Syer + * @see NamedMvcEndpoint */ public interface MvcEndpoint { diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/NamedMvcEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/NamedMvcEndpoint.java new file mode 100644 index 00000000000..87e9a591881 --- /dev/null +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/NamedMvcEndpoint.java @@ -0,0 +1,37 @@ +/* + * 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; + +/** + * A {@link MvcEndpoint} that also includes a logical name. Unlike {@link #getPath() + * endpoints paths}, it should not be possible for a user to change the endpoint name. + * Names provide a consistent way to reference an endpoint, for example they may be used + * as the {@literal 'rel'} attribute in a HAL response. + * + * @author Madhura Bhave + * @since 1.5.0 + */ +public interface NamedMvcEndpoint extends MvcEndpoint { + + /** + * Return the logical name of the endpoint. Names should be non-null, non-empty, + * alpha-numeric values. + * @return the logical name of the endpoint + */ + String getName(); + +}