Prefix endpoint's path to controller endpoint mappings with no path

Previously, if a controll endpoint included a mapping with no path,
it would be mapped to the root of the application rather than the
root of the endpoint's path.

This commit updates the handler mappings for both reactive and Servlet
web applications to treat a mapping with no paths as being a mapping
with a single empty path. This ensures that a path with the endpoint's
path prepended is used for the mapping.

Closes gh-12104
pull/12106/merge
Andy Wilkinson 7 years ago
parent da5bebf574
commit 19ce68d2d8

@ -17,8 +17,10 @@
package org.springframework.boot.actuate.endpoint.web.reactive; package org.springframework.boot.actuate.endpoint.web.reactive;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -92,6 +94,10 @@ public class ControllerEndpointHandlerMapping extends RequestMappingHandlerMappi
private RequestMappingInfo withEndpointMappedPatterns( private RequestMappingInfo withEndpointMappedPatterns(
ExposableControllerEndpoint endpoint, RequestMappingInfo mapping) { ExposableControllerEndpoint endpoint, RequestMappingInfo mapping) {
Set<PathPattern> patterns = mapping.getPatternsCondition().getPatterns(); Set<PathPattern> patterns = mapping.getPatternsCondition().getPatterns();
if (patterns.isEmpty()) {
patterns = new HashSet<PathPattern>(
Arrays.asList(getPathPatternParser().parse("")));
}
PathPattern[] endpointMappedPatterns = patterns.stream() PathPattern[] endpointMappedPatterns = patterns.stream()
.map((pattern) -> getEndpointMappedPattern(endpoint, pattern)) .map((pattern) -> getEndpointMappedPattern(endpoint, pattern))
.toArray(PathPattern[]::new); .toArray(PathPattern[]::new);

@ -19,6 +19,7 @@ package org.springframework.boot.actuate.endpoint.web.servlet;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -93,6 +94,9 @@ public class ControllerEndpointHandlerMapping extends RequestMappingHandlerMappi
private RequestMappingInfo withEndpointMappedPatterns( private RequestMappingInfo withEndpointMappedPatterns(
ExposableControllerEndpoint endpoint, RequestMappingInfo mapping) { ExposableControllerEndpoint endpoint, RequestMappingInfo mapping) {
Set<String> patterns = mapping.getPatternsCondition().getPatterns(); Set<String> patterns = mapping.getPatternsCondition().getPatterns();
if (patterns.isEmpty()) {
patterns = new HashSet<>(Collections.singletonList(""));
}
String[] endpointMappedPatterns = patterns.stream() String[] endpointMappedPatterns = patterns.stream()
.map((pattern) -> getEndpointMappedPattern(endpoint, pattern)) .map((pattern) -> getEndpointMappedPattern(endpoint, pattern))
.toArray(String[]::new); .toArray(String[]::new);

@ -78,6 +78,16 @@ public class ControllerEndpointHandlerMappingTests {
assertThat(getHandler(mapping, HttpMethod.GET, "/second")).isNull(); assertThat(getHandler(mapping, HttpMethod.GET, "/second")).isNull();
} }
@Test
public void mappingWithNoPath() throws Exception {
ExposableControllerEndpoint pathless = pathlessEndpoint();
ControllerEndpointHandlerMapping mapping = createMapping("actuator", pathless);
assertThat(getHandler(mapping, HttpMethod.GET, "/actuator/pathless"))
.isEqualTo(handlerOf(pathless.getController(), "get"));
assertThat(getHandler(mapping, HttpMethod.GET, "/pathless")).isNull();
assertThat(getHandler(mapping, HttpMethod.GET, "/")).isNull();
}
@Test @Test
public void mappingNarrowedToMethod() throws Exception { public void mappingNarrowedToMethod() throws Exception {
ExposableControllerEndpoint first = firstEndpoint(); ExposableControllerEndpoint first = firstEndpoint();
@ -118,6 +128,10 @@ public class ControllerEndpointHandlerMappingTests {
return mockEndpoint("second", new SecondTestMvcEndpoint()); return mockEndpoint("second", new SecondTestMvcEndpoint());
} }
private ExposableControllerEndpoint pathlessEndpoint() {
return mockEndpoint("pathless", new PathlessControllerEndpoint());
}
private ExposableControllerEndpoint mockEndpoint(String id, Object controller) { private ExposableControllerEndpoint mockEndpoint(String id, Object controller) {
ExposableControllerEndpoint endpoint = mock(ExposableControllerEndpoint.class); ExposableControllerEndpoint endpoint = mock(ExposableControllerEndpoint.class);
given(endpoint.getId()).willReturn(id); given(endpoint.getId()).willReturn(id);
@ -146,4 +160,14 @@ public class ControllerEndpointHandlerMappingTests {
} }
@ControllerEndpoint(id = "pathless")
private static class PathlessControllerEndpoint {
@GetMapping
public String get() {
return "test";
}
}
} }

@ -84,6 +84,16 @@ public class ControllerEndpointHandlerMappingTests {
mapping.getHandler(request("POST", "/actuator/first")); mapping.getHandler(request("POST", "/actuator/first"));
} }
@Test
public void mappingWithNoPath() throws Exception {
ExposableControllerEndpoint pathless = pathlessEndpoint();
ControllerEndpointHandlerMapping mapping = createMapping("actuator", pathless);
assertThat(mapping.getHandler(request("GET", "/actuator/pathless")).getHandler())
.isEqualTo(handlerOf(pathless.getController(), "get"));
assertThat(mapping.getHandler(request("GET", "/pathless"))).isNull();
assertThat(mapping.getHandler(request("GET", "/"))).isNull();
}
private ControllerEndpointHandlerMapping createMapping(String prefix, private ControllerEndpointHandlerMapping createMapping(String prefix,
ExposableControllerEndpoint... endpoints) { ExposableControllerEndpoint... endpoints) {
ControllerEndpointHandlerMapping mapping = new ControllerEndpointHandlerMapping( ControllerEndpointHandlerMapping mapping = new ControllerEndpointHandlerMapping(
@ -110,6 +120,10 @@ public class ControllerEndpointHandlerMappingTests {
return mockEndpoint("second", new SecondTestMvcEndpoint()); return mockEndpoint("second", new SecondTestMvcEndpoint());
} }
private ExposableControllerEndpoint pathlessEndpoint() {
return mockEndpoint("pathless", new PathlessControllerEndpoint());
}
private ExposableControllerEndpoint mockEndpoint(String id, Object controller) { private ExposableControllerEndpoint mockEndpoint(String id, Object controller) {
ExposableControllerEndpoint endpoint = mock(ExposableControllerEndpoint.class); ExposableControllerEndpoint endpoint = mock(ExposableControllerEndpoint.class);
given(endpoint.getId()).willReturn(id); given(endpoint.getId()).willReturn(id);
@ -138,4 +152,14 @@ public class ControllerEndpointHandlerMappingTests {
} }
@ControllerEndpoint(id = "pathless")
private static class PathlessControllerEndpoint {
@GetMapping
public String get() {
return "test";
}
}
} }

Loading…
Cancel
Save