All MVC endpoint paths to be separately customized from the id
This change applies only to "standard" MVC endpoints (not the extended
ones like /env and /jolokia which already have this feature). Allows
users to supply an endpoints.{name}.path.
Fixes gh-2790
This commit is contained in:
parent
434d46f583
commit
972557851a
|
|
@ -32,6 +32,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||
public class EndpointMvcAdapter implements MvcEndpoint {
|
||||
|
||||
private final Endpoint<?> delegate;
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* Create a new {@link EndpointMvcAdapter}.
|
||||
|
|
@ -58,7 +59,17 @@ public class EndpointMvcAdapter implements MvcEndpoint {
|
|||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return "/" + this.delegate.getId();
|
||||
return this.path != null ? this.path : "/" + this.delegate.getId();
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
if (!path.startsWith("/")) {
|
||||
path = "/" + path;
|
||||
}
|
||||
while (path.endsWith("/")) {
|
||||
path = path.substring(0, path.length() - 1);
|
||||
}
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ public class HealthMvcEndpoint implements MvcEndpoint, EnvironmentAware {
|
|||
|
||||
private Health cached;
|
||||
|
||||
private String path;
|
||||
|
||||
public HealthMvcEndpoint(HealthEndpoint delegate) {
|
||||
this(delegate, true);
|
||||
}
|
||||
|
|
@ -125,8 +127,9 @@ public class HealthMvcEndpoint implements MvcEndpoint, EnvironmentAware {
|
|||
public Object invoke(Principal principal) {
|
||||
if (!this.delegate.isEnabled()) {
|
||||
// Shouldn't happen because the request mapping should not be registered
|
||||
return new ResponseEntity<Map<String, String>>(Collections.singletonMap(
|
||||
"message", "This endpoint is disabled"), HttpStatus.NOT_FOUND);
|
||||
return new ResponseEntity<Map<String, String>>(
|
||||
Collections.singletonMap("message", "This endpoint is disabled"),
|
||||
HttpStatus.NOT_FOUND);
|
||||
}
|
||||
Health health = getHealth(principal);
|
||||
HttpStatus status = getStatus(health);
|
||||
|
|
@ -174,8 +177,8 @@ public class HealthMvcEndpoint implements MvcEndpoint, EnvironmentAware {
|
|||
}
|
||||
|
||||
private boolean isSecure(Principal principal) {
|
||||
return (principal != null && !principal.getClass().getName()
|
||||
.contains("Anonymous"));
|
||||
return (principal != null
|
||||
&& !principal.getClass().getName().contains("Anonymous"));
|
||||
}
|
||||
|
||||
private boolean isUnrestricted() {
|
||||
|
|
@ -185,7 +188,17 @@ public class HealthMvcEndpoint implements MvcEndpoint, EnvironmentAware {
|
|||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return "/" + this.delegate.getId();
|
||||
return this.path != null ? this.path : "/" + this.delegate.getId();
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
if (!path.startsWith("/")) {
|
||||
path = "/" + path;
|
||||
}
|
||||
while (path.endsWith("/")) {
|
||||
path = path.substring(0, path.length() - 1);
|
||||
}
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -58,11 +58,18 @@ public class MvcEndpoints implements ApplicationContextAware, InitializingBean {
|
|||
this.endpoints.addAll(existing);
|
||||
this.customTypes = findEndpointClasses(existing);
|
||||
@SuppressWarnings("rawtypes")
|
||||
Collection<Endpoint> delegates = BeanFactoryUtils.beansOfTypeIncludingAncestors(
|
||||
this.applicationContext, Endpoint.class).values();
|
||||
Collection<Endpoint> delegates = BeanFactoryUtils
|
||||
.beansOfTypeIncludingAncestors(this.applicationContext, Endpoint.class)
|
||||
.values();
|
||||
for (Endpoint<?> endpoint : delegates) {
|
||||
if (isGenericEndpoint(endpoint.getClass()) && endpoint.isEnabled()) {
|
||||
this.endpoints.add(new EndpointMvcAdapter(endpoint));
|
||||
EndpointMvcAdapter adapter = new EndpointMvcAdapter(endpoint);
|
||||
String path = this.applicationContext.getEnvironment()
|
||||
.getProperty("endpoints." + endpoint.getId() + ".path");
|
||||
if (path != null) {
|
||||
adapter.setPath(path);
|
||||
}
|
||||
this.endpoints.add(adapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.springframework.boot.actuate.endpoint.mvc;
|
|||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
|
@ -62,6 +63,19 @@ public class MvcEndpointsTests {
|
|||
assertEquals(1, this.endpoints.getEndpoints().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changesPath() throws Exception {
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
"endpoints.test.path=/foo/bar/");
|
||||
this.context.getDefaultListableBeanFactory().registerSingleton("endpoint",
|
||||
new TestEndpoint());
|
||||
this.endpoints.setApplicationContext(this.context);
|
||||
this.endpoints.afterPropertiesSet();
|
||||
assertEquals(1, this.endpoints.getEndpoints().size());
|
||||
assertEquals("/foo/bar",
|
||||
this.endpoints.getEndpoints().iterator().next().getPath());
|
||||
}
|
||||
|
||||
protected static class TestEndpoint extends AbstractEndpoint<String> {
|
||||
|
||||
public TestEndpoint() {
|
||||
|
|
|
|||
|
|
@ -166,8 +166,6 @@ For example, the following will disable _all_ endpoints except for `info`:
|
|||
endpoints.info.enabled=true
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[production-ready-endpoint-hypermedia]]
|
||||
=== Hypermedia for actuator MVC endpoints
|
||||
If http://projects.spring.io/spring-hateoas[Spring HATEOAS] is on the classpath (e.g.
|
||||
|
|
@ -502,7 +500,7 @@ you should carefully consider which endpoints you enable. See
|
|||
|
||||
|
||||
[[production-ready-customizing-management-server-context-path]]
|
||||
=== Customizing the management server context path
|
||||
=== Customizing the management endpoint paths
|
||||
Sometimes it is useful to group all management endpoints under a single path. For example,
|
||||
your application might already use `/info` for another purpose. You can use the
|
||||
`management.context-path` property to set a prefix for your management endpoint:
|
||||
|
|
@ -515,6 +513,23 @@ your application might already use `/info` for another purpose. You can use the
|
|||
The `application.properties` example above will change the endpoint from `/{id}` to
|
||||
`/manage/{id}` (e.g. `/manage/info`).
|
||||
|
||||
You can also change the "id" of an endpoint (using
|
||||
`endpoints.{name}.id`) which then changes the default resource path
|
||||
for the MVC endpoint. Legal endpoint ids are composed only of
|
||||
alphanumeric characters (because they can be exposed in a number of
|
||||
places, including JMX object names, where special characters are
|
||||
forbidden). The MVC path can be changed separately by configuring
|
||||
`endpoints.{name}.path`, and there is no validation on those values
|
||||
(so you can use anything that is legel in a URL path). For example, to
|
||||
change the location of the `/health` endpoint to `/ping/me` you can
|
||||
set `endpoints.health.path=/ping/me`.
|
||||
|
||||
TIP: If you provide a custom `MvcEndpoint` remember to include a
|
||||
settable `path` property, and default it to `/{id}` if you want your
|
||||
code to behave like the standard MVC endpoints. (Take a look at the
|
||||
`HealthMvcEndpoint` to see how you might do that.) If your custom
|
||||
endpoint is an `Endpoint` (not an `MvcEndpoint`) then Spring Boot will
|
||||
take care of the path for you.
|
||||
|
||||
|
||||
[[production-ready-customizing-management-server-port]]
|
||||
|
|
|
|||
Loading…
Reference in New Issue