Allow endpoints to be mapped to /
This commit removes the restriction that was added in 4a61e45 to
prevent / from being used as the management context path when the
management context was not using a different port
The management context path can now be set to / irrespective of the
configuration of the management port. To avoid a possible clash
with the application's welcome page or similar, the links "endpoint"
that is mapping to the management context path is disabled when
the management context path is /.
As part of allowing / to be used as the management context path again,
the handling of endpoint mappings and the creation of paths for
individual operations has been consolidated into a new EndpointMapping
class that is used across the three (MVC, WebFlux, and Jersey)
implementations.
See gh-9898
This commit is contained in:
@@ -82,7 +82,6 @@ public class ManagementContextAutoConfiguration {
|
||||
@Override
|
||||
public void afterSingletonsInstantiated() {
|
||||
verifySslConfiguration();
|
||||
verifyContextPathConfiguration();
|
||||
if (this.environment instanceof ConfigurableEnvironment) {
|
||||
addLocalManagementPortPropertyAlias(
|
||||
(ConfigurableEnvironment) this.environment);
|
||||
@@ -97,15 +96,6 @@ public class ManagementContextAutoConfiguration {
|
||||
+ "server is not listening on a separate port");
|
||||
}
|
||||
|
||||
private void verifyContextPathConfiguration() {
|
||||
String contextPath = this.environment.getProperty("management.context-path");
|
||||
if ("".equals(contextPath) || "/".equals(contextPath)) {
|
||||
throw new IllegalStateException("A management context path of '"
|
||||
+ contextPath + "' requires the management server to be "
|
||||
+ "listening on a separate port");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an alias for 'local.management.port' that actually resolves using
|
||||
* 'local.server.port'.
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.endpoint.web.WebEndpointOperation;
|
||||
import org.springframework.boot.endpoint.web.jersey.JerseyEndpointResourceFactory;
|
||||
import org.springframework.boot.endpoint.web.mvc.WebEndpointServletHandlerMapping;
|
||||
@@ -66,7 +67,8 @@ class WebEndpointInfrastructureManagementContextConfiguration {
|
||||
ManagementServerProperties managementServerProperties) {
|
||||
return (resourceConfig) -> resourceConfig.registerResources(new HashSet<>(
|
||||
new JerseyEndpointResourceFactory().createEndpointResources(
|
||||
managementServerProperties.getContextPath(),
|
||||
new EndpointMapping(
|
||||
managementServerProperties.getContextPath()),
|
||||
provider.getEndpoints())));
|
||||
}
|
||||
|
||||
@@ -93,8 +95,8 @@ class WebEndpointInfrastructureManagementContextConfiguration {
|
||||
CorsEndpointProperties corsProperties,
|
||||
ManagementServerProperties managementServerProperties) {
|
||||
WebEndpointServletHandlerMapping handlerMapping = new WebEndpointServletHandlerMapping(
|
||||
managementServerProperties.getContextPath(), provider.getEndpoints(),
|
||||
getCorsConfiguration(corsProperties));
|
||||
new EndpointMapping(managementServerProperties.getContextPath()),
|
||||
provider.getEndpoints(), getCorsConfiguration(corsProperties));
|
||||
for (WebEndpointHandlerMappingCustomizer customizer : this.mappingCustomizers) {
|
||||
customizer.customize(handlerMapping);
|
||||
}
|
||||
@@ -137,7 +139,8 @@ class WebEndpointInfrastructureManagementContextConfiguration {
|
||||
EndpointProvider<WebEndpointOperation> provider,
|
||||
ManagementServerProperties managementServerProperties) {
|
||||
return new WebEndpointReactiveHandlerMapping(
|
||||
managementServerProperties.getContextPath(), provider.getEndpoints());
|
||||
new EndpointMapping(managementServerProperties.getContextPath()),
|
||||
provider.getEndpoints());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.cloud.CloudPlatform;
|
||||
import org.springframework.boot.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.endpoint.web.WebEndpointOperation;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -69,8 +70,9 @@ public class CloudFoundryActuatorAutoConfiguration {
|
||||
EndpointProvider<WebEndpointOperation> provider, Environment environment,
|
||||
RestTemplateBuilder builder) {
|
||||
return new CloudFoundryWebEndpointServletHandlerMapping(
|
||||
"/cloudfoundryapplication", provider.getEndpoints(),
|
||||
getCorsConfiguration(), getSecurityInterceptor(builder, environment));
|
||||
new EndpointMapping("/cloudfoundryapplication"),
|
||||
provider.getEndpoints(), getCorsConfiguration(),
|
||||
getSecurityInterceptor(builder, environment));
|
||||
}
|
||||
|
||||
private CloudFoundrySecurityInterceptor getSecurityInterceptor(
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.springframework.boot.endpoint.EndpointInfo;
|
||||
import org.springframework.boot.endpoint.OperationInvoker;
|
||||
import org.springframework.boot.endpoint.ParameterMappingException;
|
||||
import org.springframework.boot.endpoint.web.EndpointLinksResolver;
|
||||
import org.springframework.boot.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.endpoint.web.Link;
|
||||
import org.springframework.boot.endpoint.web.WebEndpointOperation;
|
||||
import org.springframework.boot.endpoint.web.WebEndpointResponse;
|
||||
@@ -72,11 +73,11 @@ class CloudFoundryWebEndpointServletHandlerMapping
|
||||
|
||||
private final EndpointLinksResolver endpointLinksResolver = new EndpointLinksResolver();
|
||||
|
||||
CloudFoundryWebEndpointServletHandlerMapping(String endpointPath,
|
||||
CloudFoundryWebEndpointServletHandlerMapping(EndpointMapping endpointMapping,
|
||||
Collection<EndpointInfo<WebEndpointOperation>> webEndpoints,
|
||||
CorsConfiguration corsConfiguration,
|
||||
CloudFoundrySecurityInterceptor securityInterceptor) {
|
||||
super(endpointPath, webEndpoints, corsConfiguration);
|
||||
super(endpointMapping, webEndpoints, corsConfiguration);
|
||||
this.securityInterceptor = securityInterceptor;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ public class CloudFoundryActuatorAutoConfigurationTests {
|
||||
@Test
|
||||
public void cloudFoundryPlatformActive() throws Exception {
|
||||
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping();
|
||||
assertThat(handlerMapping.getEndpointPath())
|
||||
assertThat(handlerMapping.getEndpointMapping().getPath())
|
||||
.isEqualTo("/cloudfoundryapplication");
|
||||
CorsConfiguration corsConfiguration = (CorsConfiguration) ReflectionTestUtils
|
||||
.getField(handlerMapping, "corsConfiguration");
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.boot.endpoint.OperationParameterMapper;
|
||||
import org.springframework.boot.endpoint.ReadOperation;
|
||||
import org.springframework.boot.endpoint.Selector;
|
||||
import org.springframework.boot.endpoint.WriteOperation;
|
||||
import org.springframework.boot.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.endpoint.web.WebAnnotationEndpointDiscoverer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
@@ -196,7 +197,8 @@ public class CloudFoundryMvcWebEndpointIntegrationTests {
|
||||
CorsConfiguration corsConfiguration = new CorsConfiguration();
|
||||
corsConfiguration.setAllowedOrigins(Arrays.asList("http://example.com"));
|
||||
corsConfiguration.setAllowedMethods(Arrays.asList("GET", "POST"));
|
||||
return new CloudFoundryWebEndpointServletHandlerMapping("/cfApplication",
|
||||
return new CloudFoundryWebEndpointServletHandlerMapping(
|
||||
new EndpointMapping("/cfApplication"),
|
||||
webEndpointDiscoverer.discoverEndpoints(), corsConfiguration,
|
||||
interceptor);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.endpoint.EndpointInfo;
|
||||
import org.springframework.boot.endpoint.OperationType;
|
||||
import org.springframework.boot.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.endpoint.web.OperationRequestPredicate;
|
||||
import org.springframework.boot.endpoint.web.WebEndpointHttpMethod;
|
||||
import org.springframework.boot.endpoint.web.WebEndpointOperation;
|
||||
@@ -138,7 +139,8 @@ public class RequestMappingEndpointTests {
|
||||
WebEndpointOperation operation = new WebEndpointOperation(OperationType.READ,
|
||||
(arguments) -> "Invoked", true, requestPredicate, "test");
|
||||
WebEndpointServletHandlerMapping mapping = new WebEndpointServletHandlerMapping(
|
||||
"application", Collections.singleton(new EndpointInfo<>("test", true,
|
||||
new EndpointMapping("application"),
|
||||
Collections.singleton(new EndpointInfo<>("test", true,
|
||||
Collections.singleton(operation))));
|
||||
mapping.setApplicationContext(new StaticApplicationContext());
|
||||
mapping.afterPropertiesSet();
|
||||
|
||||
Reference in New Issue
Block a user