From c108629311085c0a41c12ddac062d3dc552effdd Mon Sep 17 00:00:00 2001 From: HaiTao Zhang Date: Tue, 2 Jul 2019 18:18:29 -0700 Subject: [PATCH 1/2] Provide links for actuators at / when using a separate management port See gh-17418 --- ...ndpointManagementContextConfiguration.java | 8 +++- ...ndpointManagementContextConfiguration.java | 9 ++++- ...ndpointManagementContextConfiguration.java | 8 +++- .../actuate/endpoint/web/EndpointMapping.java | 14 ++++++- .../jersey/JerseyEndpointResourceFactory.java | 2 +- ...AbstractWebFluxEndpointHandlerMapping.java | 2 +- .../AbstractWebMvcEndpointHandlerMapping.java | 2 +- .../endpoint/web/EndpointMappingTests.java | 5 +++ ...entPortSampleActuatorApplicationTests.java | 37 +++++++++++++++++++ ...entPortSampleActuatorApplicationTests.java | 35 ++++++++++++++++++ ...entPortSampleActuatorApplicationTests.java | 35 ++++++++++++++++++ 11 files changed, 147 insertions(+), 10 deletions(-) create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyDifferentPortSampleActuatorApplicationTests.java create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java index 729f2141f9..0d7612f488 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java @@ -26,6 +26,7 @@ import org.glassfish.jersey.server.ResourceConfig; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; @@ -42,6 +43,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.context.annotation.Bean; +import org.springframework.core.env.Environment; /** * {@link ManagementContextConfiguration @ManagementContextConfiguration} for Jersey @@ -62,14 +64,16 @@ class JerseyWebEndpointManagementContextConfiguration { @Bean ResourceConfigCustomizer webEndpointRegistrar(WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, - WebEndpointProperties webEndpointProperties) { + WebEndpointProperties webEndpointProperties, Environment environment) { List> allEndpoints = new ArrayList<>(); allEndpoints.addAll(webEndpointsSupplier.getEndpoints()); allEndpoints.addAll(servletEndpointsSupplier.getEndpoints()); return (resourceConfig) -> { JerseyEndpointResourceFactory resourceFactory = new JerseyEndpointResourceFactory(); String basePath = webEndpointProperties.getBasePath(); - EndpointMapping endpointMapping = new EndpointMapping(basePath); + ManagementPortType type = ManagementPortType.get(environment); + Boolean samePort = type == ManagementPortType.SAME; + EndpointMapping endpointMapping = new EndpointMapping(basePath, samePort); Collection webEndpoints = Collections .unmodifiableCollection(webEndpointsSupplier.getEndpoints()); resourceConfig.registerResources(new HashSet<>(resourceFactory.createEndpointResources(endpointMapping, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java index e0ef4be2ac..8e5111571f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java @@ -23,6 +23,7 @@ import java.util.List; import org.springframework.boot.actuate.autoconfigure.endpoint.web.CorsEndpointProperties; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; @@ -40,6 +41,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; +import org.springframework.core.env.Environment; import org.springframework.http.server.reactive.HttpHandler; import org.springframework.web.reactive.DispatcherHandler; @@ -62,8 +64,11 @@ public class WebFluxEndpointManagementContextConfiguration { @ConditionalOnMissingBean public WebFluxEndpointHandlerMapping webEndpointReactiveHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, - CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties) { - EndpointMapping endpointMapping = new EndpointMapping(webEndpointProperties.getBasePath()); + CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, + Environment environment) { + ManagementPortType type = ManagementPortType.get(environment); + Boolean samePort = type == ManagementPortType.SAME; + EndpointMapping endpointMapping = new EndpointMapping(webEndpointProperties.getBasePath(), samePort); Collection endpoints = webEndpointsSupplier.getEndpoints(); List> allEndpoints = new ArrayList<>(); allEndpoints.addAll(endpoints); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java index 023d65c850..910de4927b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java @@ -23,6 +23,7 @@ import java.util.List; import org.springframework.boot.actuate.autoconfigure.endpoint.web.CorsEndpointProperties; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; @@ -41,6 +42,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; +import org.springframework.core.env.Environment; import org.springframework.web.servlet.DispatcherServlet; /** @@ -63,13 +65,15 @@ public class WebMvcEndpointManagementContextConfiguration { public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties, - WebEndpointProperties webEndpointProperties) { + WebEndpointProperties webEndpointProperties, Environment environment) { List> allEndpoints = new ArrayList<>(); Collection webEndpoints = webEndpointsSupplier.getEndpoints(); allEndpoints.addAll(webEndpoints); allEndpoints.addAll(servletEndpointsSupplier.getEndpoints()); allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints()); - EndpointMapping endpointMapping = new EndpointMapping(webEndpointProperties.getBasePath()); + ManagementPortType type = ManagementPortType.get(environment); + Boolean samePort = type == ManagementPortType.SAME; + EndpointMapping endpointMapping = new EndpointMapping(webEndpointProperties.getBasePath(), samePort); return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, webEndpointProperties.getBasePath())); diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/EndpointMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/EndpointMapping.java index c106cb4025..c70fb9e3c7 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/EndpointMapping.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/EndpointMapping.java @@ -28,12 +28,20 @@ public class EndpointMapping { private final String path; + private final Boolean samePort; + /** * Creates a new {@code EndpointMapping} using the given {@code path}. * @param path the path + * @param samePort states true or false for same port as server */ - public EndpointMapping(String path) { + public EndpointMapping(String path, Boolean samePort) { this.path = normalizePath(path); + this.samePort = samePort; + } + + public EndpointMapping(String path) { + this(path, true); } /** @@ -44,6 +52,10 @@ public class EndpointMapping { return this.path; } + public boolean isSamePort() { + return this.samePort; + } + public String createSubPath(String path) { return this.path + normalizePath(path); } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyEndpointResourceFactory.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyEndpointResourceFactory.java index 425f08c983..54ee86e7f8 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyEndpointResourceFactory.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyEndpointResourceFactory.java @@ -79,7 +79,7 @@ public class JerseyEndpointResourceFactory { List resources = new ArrayList<>(); endpoints.stream().flatMap((endpoint) -> endpoint.getOperations().stream()) .map((operation) -> createResource(endpointMapping, operation)).forEach(resources::add); - if (StringUtils.hasText(endpointMapping.getPath())) { + if (StringUtils.hasText(endpointMapping.getPath()) || !endpointMapping.isSamePort()) { Resource resource = createEndpointLinksResource(endpointMapping.getPath(), endpointMediaTypes, linksResolver); resources.add(resource); diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java index 8f1fb5128f..8e0799ee33 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java @@ -120,7 +120,7 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi registerMappingForOperation(endpoint, operation); } } - if (StringUtils.hasText(this.endpointMapping.getPath())) { + if (StringUtils.hasText(this.endpointMapping.getPath()) || !this.endpointMapping.isSamePort()) { registerLinksMapping(); } } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java index e579f19e3a..92136dde17 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java @@ -123,7 +123,7 @@ public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappin registerMappingForOperation(endpoint, operation); } } - if (StringUtils.hasText(this.endpointMapping.getPath())) { + if (StringUtils.hasText(this.endpointMapping.getPath()) || !this.endpointMapping.isSamePort()) { registerLinksMapping(); } } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/EndpointMappingTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/EndpointMappingTests.java index 243b4932a8..7075887858 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/EndpointMappingTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/EndpointMappingTests.java @@ -77,4 +77,9 @@ class EndpointMappingTests { assertThat(new EndpointMapping("/test").createSubPath("one/")).isEqualTo("/test/one"); } + @Test + void setDifferentPort() { + assertThat(new EndpointMapping("/test", false).isSamePort()).isFalse(); + } + } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java new file mode 100644 index 0000000000..a9025f0ad0 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java @@ -0,0 +1,37 @@ +package smoketest.actuator; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { "management.endpoints.web.base-path=/","management.server.port=0"}) +public class ManagementDifferentPortSampleActuatorApplicationTests { + + @LocalServerPort + private int port; + + @LocalManagementPort + private int managementPort; + + @Test + void testDifferentServerPort(){ + if(this.managementPort != this.port) { + ResponseEntity entity = new TestRestTemplate("user", getPassword()) + .getForEntity("http://localhost:" + this.managementPort + "/", String.class); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(entity.getBody()).contains("\"_links\""); + } + } + + private String getPassword(){ + return "password"; + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyDifferentPortSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyDifferentPortSampleActuatorApplicationTests.java new file mode 100644 index 0000000000..8e1577aee2 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyDifferentPortSampleActuatorApplicationTests.java @@ -0,0 +1,35 @@ +package smoketest.jersey; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {"management.server.port=0","management.endpoints.web.base-path=/"}) +public class JerseyDifferentPortSampleActuatorApplicationTests { + + @LocalManagementPort + private int managementPort; + + @LocalServerPort + private int port; + + @Test + void testDifferentServerPort(){ + if(this.managementPort != this.port) { + ResponseEntity entity = new TestRestTemplate("user", getPassword()) + .getForEntity("http://localhost:" + this.managementPort + "/", String.class); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(entity.getBody()).contains("\"_links\""); + } + } + + private String getPassword(){ + return "password"; + } +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java new file mode 100644 index 0000000000..e7fe948190 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java @@ -0,0 +1,35 @@ +package smoketest.webflux; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {"management.server.port=0","management.endpoints.web.base-path=/"}) +public class WebFluxDifferentPortSampleActuatorApplicationTests { + + @LocalManagementPort + private int managementPort; + + @LocalServerPort + private int port; + + @Test + void testDifferentServerPort(){ + if(this.managementPort != this.port) { + ResponseEntity entity = new TestRestTemplate("user", getPassword()) + .getForEntity("http://localhost:" + this.managementPort + "/", String.class); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(entity.getBody()).contains("\"_links\""); + } + } + + private String getPassword(){ + return "password"; + } +} From 39b15af5d6f3ea5d125c55d52a24f69b6e3675ae Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Wed, 3 Jul 2019 16:17:19 -0700 Subject: [PATCH 2/2] Polish "Provide links / when using a separate management port" See gh-17418 --- ...dFoundryWebFluxEndpointHandlerMapping.java | 2 +- ...undryWebEndpointServletHandlerMapping.java | 2 +- ...ndpointManagementContextConfiguration.java | 13 +++-- ...ndpointManagementContextConfiguration.java | 15 ++++-- ...ndpointManagementContextConfiguration.java | 12 +++-- ...JerseyEndpointRequestIntegrationTests.java | 2 +- .../MvcEndpointRequestIntegrationTests.java | 3 +- .../actuate/endpoint/web/EndpointMapping.java | 14 +----- .../jersey/JerseyEndpointResourceFactory.java | 5 +- ...AbstractWebFluxEndpointHandlerMapping.java | 8 +++- .../WebFluxEndpointHandlerMapping.java | 5 +- .../AbstractWebMvcEndpointHandlerMapping.java | 14 ++++-- .../servlet/WebMvcEndpointHandlerMapping.java | 5 +- .../endpoint/web/EndpointMappingTests.java | 5 -- .../JerseyWebEndpointIntegrationTests.java | 6 ++- .../WebFluxEndpointIntegrationTests.java | 6 ++- .../MvcWebEndpointIntegrationTests.java | 6 ++- ...EndpointTestInvocationContextProvider.java | 8 ++-- ...entPortSampleActuatorApplicationTests.java | 45 ++++++++++++------ ...entPortSampleActuatorApplicationTests.java | 47 +++++++++++++------ ...entPortSampleActuatorApplicationTests.java | 47 +++++++++++++------ 21 files changed, 171 insertions(+), 99 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java index 5a3307157a..0df6400d0a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java @@ -60,7 +60,7 @@ class CloudFoundryWebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointH Collection endpoints, EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration, CloudFoundrySecurityInterceptor securityInterceptor, EndpointLinksResolver linksResolver) { - super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration); + super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, true); this.linksResolver = linksResolver; this.securityInterceptor = securityInterceptor; } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java index 4f692456ed..bb2331e7bc 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java @@ -59,7 +59,7 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebMvcEndpoin Collection endpoints, EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration, CloudFoundrySecurityInterceptor securityInterceptor, EndpointLinksResolver linksResolver) { - super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration); + super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, true); this.securityInterceptor = securityInterceptor; this.linksResolver = linksResolver; } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java index 0d7612f488..42a0c9c0b9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java @@ -44,6 +44,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; +import org.springframework.util.StringUtils; /** * {@link ManagementContextConfiguration @ManagementContextConfiguration} for Jersey @@ -71,14 +72,18 @@ class JerseyWebEndpointManagementContextConfiguration { return (resourceConfig) -> { JerseyEndpointResourceFactory resourceFactory = new JerseyEndpointResourceFactory(); String basePath = webEndpointProperties.getBasePath(); - ManagementPortType type = ManagementPortType.get(environment); - Boolean samePort = type == ManagementPortType.SAME; - EndpointMapping endpointMapping = new EndpointMapping(basePath, samePort); + EndpointMapping endpointMapping = new EndpointMapping(basePath); Collection webEndpoints = Collections .unmodifiableCollection(webEndpointsSupplier.getEndpoints()); resourceConfig.registerResources(new HashSet<>(resourceFactory.createEndpointResources(endpointMapping, - webEndpoints, endpointMediaTypes, new EndpointLinksResolver(allEndpoints, basePath)))); + webEndpoints, endpointMediaTypes, new EndpointLinksResolver(allEndpoints, basePath), + shouldRegisterLinksMapping(environment, basePath)))); }; } + private boolean shouldRegisterLinksMapping(Environment environment, String basePath) { + return StringUtils.hasText(basePath) + || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT); + } + } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java index 8e5111571f..aa758ae72d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java @@ -43,6 +43,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.util.StringUtils; import org.springframework.web.reactive.DispatcherHandler; /** @@ -66,16 +67,20 @@ public class WebFluxEndpointManagementContextConfiguration { ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, Environment environment) { - ManagementPortType type = ManagementPortType.get(environment); - Boolean samePort = type == ManagementPortType.SAME; - EndpointMapping endpointMapping = new EndpointMapping(webEndpointProperties.getBasePath(), samePort); + String basePath = webEndpointProperties.getBasePath(); + EndpointMapping endpointMapping = new EndpointMapping(basePath); Collection endpoints = webEndpointsSupplier.getEndpoints(); List> allEndpoints = new ArrayList<>(); allEndpoints.addAll(endpoints); allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints()); return new WebFluxEndpointHandlerMapping(endpointMapping, endpoints, endpointMediaTypes, - corsProperties.toCorsConfiguration(), - new EndpointLinksResolver(allEndpoints, webEndpointProperties.getBasePath())); + corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), + shouldRegisterLinksMapping(environment, basePath)); + } + + private boolean shouldRegisterLinksMapping(Environment environment, String basePath) { + return StringUtils.hasText(basePath) + || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT); } @Bean diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java index 910de4927b..91064d4d5a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java @@ -43,6 +43,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; +import org.springframework.util.StringUtils; import org.springframework.web.servlet.DispatcherServlet; /** @@ -71,12 +72,13 @@ public class WebMvcEndpointManagementContextConfiguration { allEndpoints.addAll(webEndpoints); allEndpoints.addAll(servletEndpointsSupplier.getEndpoints()); allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints()); - ManagementPortType type = ManagementPortType.get(environment); - Boolean samePort = type == ManagementPortType.SAME; - EndpointMapping endpointMapping = new EndpointMapping(webEndpointProperties.getBasePath(), samePort); + String basePath = webEndpointProperties.getBasePath(); + EndpointMapping endpointMapping = new EndpointMapping(basePath); + boolean shouldRegisterLinksMapping = StringUtils.hasText(basePath) + || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT); return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, - corsProperties.toCorsConfiguration(), - new EndpointLinksResolver(allEndpoints, webEndpointProperties.getBasePath())); + corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), + shouldRegisterLinksMapping); } @Bean diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/JerseyEndpointRequestIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/JerseyEndpointRequestIntegrationTests.java index d4d6b872eb..c613fc3e51 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/JerseyEndpointRequestIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/JerseyEndpointRequestIntegrationTests.java @@ -133,7 +133,7 @@ class JerseyEndpointRequestIntegrationTests extends AbstractEndpointRequestInteg Arrays.asList(EndpointId::toString), Collections.emptyList(), Collections.emptyList()); Collection resources = new JerseyEndpointResourceFactory().createEndpointResources( new EndpointMapping("/actuator"), discoverer.getEndpoints(), endpointMediaTypes, - new EndpointLinksResolver(discoverer.getEndpoints())); + new EndpointLinksResolver(discoverer.getEndpoints()), true); config.registerResources(new HashSet<>(resources)); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/MvcEndpointRequestIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/MvcEndpointRequestIntegrationTests.java index 5e04dcd57d..0df5dc2f40 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/MvcEndpointRequestIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/MvcEndpointRequestIntegrationTests.java @@ -119,7 +119,8 @@ class MvcEndpointRequestIntegrationTests extends AbstractEndpointRequestIntegrat new ConversionServiceParameterValueMapper(), endpointMediaTypes, Arrays.asList(EndpointId::toString), Collections.emptyList(), Collections.emptyList()); return new WebMvcEndpointHandlerMapping(new EndpointMapping("/actuator"), discoverer.getEndpoints(), - endpointMediaTypes, new CorsConfiguration(), new EndpointLinksResolver(discoverer.getEndpoints())); + endpointMediaTypes, new CorsConfiguration(), new EndpointLinksResolver(discoverer.getEndpoints()), + true); } } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/EndpointMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/EndpointMapping.java index c70fb9e3c7..c106cb4025 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/EndpointMapping.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/EndpointMapping.java @@ -28,20 +28,12 @@ public class EndpointMapping { private final String path; - private final Boolean samePort; - /** * Creates a new {@code EndpointMapping} using the given {@code path}. * @param path the path - * @param samePort states true or false for same port as server */ - public EndpointMapping(String path, Boolean samePort) { - this.path = normalizePath(path); - this.samePort = samePort; - } - public EndpointMapping(String path) { - this(path, true); + this.path = normalizePath(path); } /** @@ -52,10 +44,6 @@ public class EndpointMapping { return this.path; } - public boolean isSamePort() { - return this.samePort; - } - public String createSubPath(String path) { return this.path + normalizePath(path); } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyEndpointResourceFactory.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyEndpointResourceFactory.java index 54ee86e7f8..ed6f61df95 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyEndpointResourceFactory.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyEndpointResourceFactory.java @@ -71,15 +71,16 @@ public class JerseyEndpointResourceFactory { * @param endpoints the web endpoints * @param endpointMediaTypes media types consumed and produced by the endpoints * @param linksResolver resolver for determining links to available endpoints + * @param shouldRegisterLinks should register links * @return the resources for the operations */ public Collection createEndpointResources(EndpointMapping endpointMapping, Collection endpoints, EndpointMediaTypes endpointMediaTypes, - EndpointLinksResolver linksResolver) { + EndpointLinksResolver linksResolver, boolean shouldRegisterLinks) { List resources = new ArrayList<>(); endpoints.stream().flatMap((endpoint) -> endpoint.getOperations().stream()) .map((operation) -> createResource(endpointMapping, operation)).forEach(resources::add); - if (StringUtils.hasText(endpointMapping.getPath()) || !endpointMapping.isSamePort()) { + if (shouldRegisterLinks) { Resource resource = createEndpointLinksResource(endpointMapping.getPath(), endpointMediaTypes, linksResolver); resources.add(resource); diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java index 8e0799ee33..c16e6ebb0e 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java @@ -95,6 +95,8 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi private final Method handleReadMethod = ReflectionUtils.findMethod(ReadOperationHandler.class, "handle", ServerWebExchange.class); + private final boolean shouldRegisterLinksMapping; + /** * Creates a new {@code AbstractWebFluxEndpointHandlerMapping} that provides mappings * for the operations of the given {@code webEndpoints}. @@ -102,14 +104,16 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi * @param endpoints the web endpoints * @param endpointMediaTypes media types consumed and produced by the endpoints * @param corsConfiguration the CORS configuration for the endpoints + * @param shouldRegisterLinksMapping whether the links endpoint should be registered */ public AbstractWebFluxEndpointHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, EndpointMediaTypes endpointMediaTypes, - CorsConfiguration corsConfiguration) { + CorsConfiguration corsConfiguration, boolean shouldRegisterLinksMapping) { this.endpointMapping = endpointMapping; this.endpoints = endpoints; this.endpointMediaTypes = endpointMediaTypes; this.corsConfiguration = corsConfiguration; + this.shouldRegisterLinksMapping = shouldRegisterLinksMapping; setOrder(-100); } @@ -120,7 +124,7 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi registerMappingForOperation(endpoint, operation); } } - if (StringUtils.hasText(this.endpointMapping.getPath()) || !this.endpointMapping.isSamePort()) { + if (this.shouldRegisterLinksMapping) { registerLinksMapping(); } } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMapping.java index 4b5e440bd8..2b0a7ae83f 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMapping.java @@ -53,11 +53,12 @@ public class WebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointHandle * @param endpointMediaTypes media types consumed and produced by the endpoints * @param corsConfiguration the CORS configuration for the endpoints or {@code null} * @param linksResolver resolver for determining links to available endpoints + * @param shouldRegisterLinksMapping whether the links endpoint should be registered */ public WebFluxEndpointHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration, - EndpointLinksResolver linksResolver) { - super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration); + EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping) { + super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping); this.linksResolver = linksResolver; setOrder(-100); } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java index 92136dde17..8c4783b2d0 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java @@ -81,6 +81,8 @@ public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappin private final CorsConfiguration corsConfiguration; + private final boolean shouldRegisterLinksMapping; + private final Method handleMethod = ReflectionUtils.findMethod(OperationHandler.class, "handle", HttpServletRequest.class, Map.class); @@ -92,10 +94,12 @@ public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappin * @param endpointMapping the base mapping for all endpoints * @param endpoints the web endpoints * @param endpointMediaTypes media types consumed and produced by the endpoints + * @param shouldRegisterLinksMapping whether the links endpoint should be registered */ public AbstractWebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, - Collection endpoints, EndpointMediaTypes endpointMediaTypes) { - this(endpointMapping, endpoints, endpointMediaTypes, null); + Collection endpoints, EndpointMediaTypes endpointMediaTypes, + boolean shouldRegisterLinksMapping) { + this(endpointMapping, endpoints, endpointMediaTypes, null, shouldRegisterLinksMapping); } /** @@ -105,14 +109,16 @@ public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappin * @param endpoints the web endpoints * @param endpointMediaTypes media types consumed and produced by the endpoints * @param corsConfiguration the CORS configuration for the endpoints or {@code null} + * @param shouldRegisterLinksMapping whether the links endpoint should be registered */ public AbstractWebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, EndpointMediaTypes endpointMediaTypes, - CorsConfiguration corsConfiguration) { + CorsConfiguration corsConfiguration, boolean shouldRegisterLinksMapping) { this.endpointMapping = endpointMapping; this.endpoints = endpoints; this.endpointMediaTypes = endpointMediaTypes; this.corsConfiguration = corsConfiguration; + this.shouldRegisterLinksMapping = shouldRegisterLinksMapping; setOrder(-100); } @@ -123,7 +129,7 @@ public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappin registerMappingForOperation(endpoint, operation); } } - if (StringUtils.hasText(this.endpointMapping.getPath()) || !this.endpointMapping.isSamePort()) { + if (this.shouldRegisterLinksMapping) { registerLinksMapping(); } } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java index caa86b3cf2..350c4a41e9 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java @@ -52,11 +52,12 @@ public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerM * @param endpointMediaTypes media types consumed and produced by the endpoints * @param corsConfiguration the CORS configuration for the endpoints or {@code null} * @param linksResolver resolver for determining links to available endpoints + * @param shouldRegisterLinksMapping whether the links endpoint should be registered */ public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration, - EndpointLinksResolver linksResolver) { - super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration); + EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping) { + super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping); this.linksResolver = linksResolver; setOrder(-100); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/EndpointMappingTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/EndpointMappingTests.java index 7075887858..243b4932a8 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/EndpointMappingTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/EndpointMappingTests.java @@ -77,9 +77,4 @@ class EndpointMappingTests { assertThat(new EndpointMapping("/test").createSubPath("one/")).isEqualTo("/test/one"); } - @Test - void setDifferentPort() { - assertThat(new EndpointMapping("/test", false).isSamePort()).isFalse(); - } - } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java index a3c7b90766..06bfcbebeb 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java @@ -52,6 +52,7 @@ import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper; import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.util.StringUtils; import org.springframework.web.filter.OncePerRequestFilter; /** @@ -106,9 +107,10 @@ public class JerseyWebEndpointIntegrationTests ResourceConfig resourceConfig(Environment environment, WebEndpointDiscoverer endpointDiscoverer, EndpointMediaTypes endpointMediaTypes) { ResourceConfig resourceConfig = new ResourceConfig(); + String endpointPath = environment.getProperty("endpointPath"); Collection resources = new JerseyEndpointResourceFactory().createEndpointResources( - new EndpointMapping(environment.getProperty("endpointPath")), endpointDiscoverer.getEndpoints(), - endpointMediaTypes, new EndpointLinksResolver(endpointDiscoverer.getEndpoints())); + new EndpointMapping(endpointPath), endpointDiscoverer.getEndpoints(), endpointMediaTypes, + new EndpointLinksResolver(endpointDiscoverer.getEndpoints()), StringUtils.hasText(endpointPath)); resourceConfig.registerResources(new HashSet<>(resources)); resourceConfig.register(JacksonFeature.class); resourceConfig.register(new ObjectMapperContextResolver(new ObjectMapper()), ContextResolver.class); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointIntegrationTests.java index 4b5637dab9..40bae12804 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointIntegrationTests.java @@ -41,6 +41,7 @@ import org.springframework.http.server.reactive.HttpHandler; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.ReactiveSecurityContextHolder; +import org.springframework.util.StringUtils; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.reactive.config.EnableWebFlux; import org.springframework.web.server.WebFilter; @@ -122,9 +123,10 @@ class WebFluxEndpointIntegrationTests CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.setAllowedOrigins(Arrays.asList("https://example.com")); corsConfiguration.setAllowedMethods(Arrays.asList("GET", "POST")); - return new WebFluxEndpointHandlerMapping(new EndpointMapping(environment.getProperty("endpointPath")), + String endpointPath = environment.getProperty("endpointPath"); + return new WebFluxEndpointHandlerMapping(new EndpointMapping(endpointPath), endpointDiscoverer.getEndpoints(), endpointMediaTypes, corsConfiguration, - new EndpointLinksResolver(endpointDiscoverer.getEndpoints())); + new EndpointLinksResolver(endpointDiscoverer.getEndpoints()), StringUtils.hasText(endpointPath)); } @Bean diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/MvcWebEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/MvcWebEndpointIntegrationTests.java index 84f82b400a..9ff0ed2fcb 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/MvcWebEndpointIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/MvcWebEndpointIntegrationTests.java @@ -52,6 +52,7 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper; +import org.springframework.util.StringUtils; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.servlet.handler.RequestMatchResult; @@ -145,9 +146,10 @@ class MvcWebEndpointIntegrationTests CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.setAllowedOrigins(Arrays.asList("https://example.com")); corsConfiguration.setAllowedMethods(Arrays.asList("GET", "POST")); - return new WebMvcEndpointHandlerMapping(new EndpointMapping(environment.getProperty("endpointPath")), + String endpointPath = environment.getProperty("endpointPath"); + return new WebMvcEndpointHandlerMapping(new EndpointMapping(endpointPath), endpointDiscoverer.getEndpoints(), endpointMediaTypes, corsConfiguration, - new EndpointLinksResolver(endpointDiscoverer.getEndpoints())); + new EndpointLinksResolver(endpointDiscoverer.getEndpoints()), StringUtils.hasText(endpointPath)); } } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java index 8886f5f7c5..cb62ec73ca 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java @@ -242,7 +242,7 @@ class WebEndpointTestInvocationContextProvider implements TestTemplateInvocation Collections.emptyList()); Collection resources = new JerseyEndpointResourceFactory().createEndpointResources( new EndpointMapping("/actuator"), discoverer.getEndpoints(), endpointMediaTypes, - new EndpointLinksResolver(discoverer.getEndpoints())); + new EndpointLinksResolver(discoverer.getEndpoints()), true); config.registerResources(new HashSet<>(resources)); } @@ -288,7 +288,8 @@ class WebEndpointTestInvocationContextProvider implements TestTemplateInvocation new ConversionServiceParameterValueMapper(), endpointMediaTypes, null, Collections.emptyList(), Collections.emptyList()); return new WebFluxEndpointHandlerMapping(new EndpointMapping("/actuator"), discoverer.getEndpoints(), - endpointMediaTypes, new CorsConfiguration(), new EndpointLinksResolver(discoverer.getEndpoints())); + endpointMediaTypes, new CorsConfiguration(), new EndpointLinksResolver(discoverer.getEndpoints()), + true); } } @@ -317,7 +318,8 @@ class WebEndpointTestInvocationContextProvider implements TestTemplateInvocation new ConversionServiceParameterValueMapper(), endpointMediaTypes, null, Collections.emptyList(), Collections.emptyList()); return new WebMvcEndpointHandlerMapping(new EndpointMapping("/actuator"), discoverer.getEndpoints(), - endpointMediaTypes, new CorsConfiguration(), new EndpointLinksResolver(discoverer.getEndpoints())); + endpointMediaTypes, new CorsConfiguration(), new EndpointLinksResolver(discoverer.getEndpoints()), + true); } } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java index a9025f0ad0..fc32f7f942 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java @@ -1,36 +1,53 @@ +/* + * Copyright 2012-2019 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 + * + * https://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 smoketest.actuator; import org.junit.jupiter.api.Test; + import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import static org.assertj.core.api.Assertions.assertThat; +/** + * Integration tests for separate management and main service ports with empty endpoint + * base path. + * + * @author HaiTao Zhang + */ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = { "management.endpoints.web.base-path=/","management.server.port=0"}) -public class ManagementDifferentPortSampleActuatorApplicationTests { - - @LocalServerPort - private int port; + properties = { "management.endpoints.web.base-path=/", "management.server.port=0" }) +class ManagementDifferentPortSampleActuatorApplicationTests { @LocalManagementPort private int managementPort; @Test - void testDifferentServerPort(){ - if(this.managementPort != this.port) { - ResponseEntity entity = new TestRestTemplate("user", getPassword()) - .getForEntity("http://localhost:" + this.managementPort + "/", String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(entity.getBody()).contains("\"_links\""); - } + void linksEndpointShouldBeAvailable() { + ResponseEntity entity = new TestRestTemplate("user", getPassword()) + .getForEntity("http://localhost:" + this.managementPort + "/", String.class); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(entity.getBody()).contains("\"_links\""); } - private String getPassword(){ + private String getPassword() { return "password"; } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyDifferentPortSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyDifferentPortSampleActuatorApplicationTests.java index 8e1577aee2..8cc580e0a2 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyDifferentPortSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyDifferentPortSampleActuatorApplicationTests.java @@ -1,35 +1,54 @@ +/* + * Copyright 2012-2019 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 + * + * https://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 smoketest.jersey; import org.junit.jupiter.api.Test; + import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import static org.assertj.core.api.Assertions.assertThat; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {"management.server.port=0","management.endpoints.web.base-path=/"}) -public class JerseyDifferentPortSampleActuatorApplicationTests { +/** + * Integration tests for separate management and main service ports with empty base path + * for endpoints. + * + * @author HaiTao Zhang + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { "management.server.port=0", "management.endpoints.web.base-path=/" }) +class JerseyDifferentPortSampleActuatorApplicationTests { @LocalManagementPort private int managementPort; - @LocalServerPort - private int port; - @Test - void testDifferentServerPort(){ - if(this.managementPort != this.port) { - ResponseEntity entity = new TestRestTemplate("user", getPassword()) - .getForEntity("http://localhost:" + this.managementPort + "/", String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(entity.getBody()).contains("\"_links\""); - } + void linksEndpointShouldBeAvailable() { + ResponseEntity entity = new TestRestTemplate("user", getPassword()) + .getForEntity("http://localhost:" + this.managementPort + "/", String.class); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(entity.getBody()).contains("\"_links\""); } - private String getPassword(){ + private String getPassword() { return "password"; } + } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java index e7fe948190..d0450b9170 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java @@ -1,35 +1,54 @@ +/* + * Copyright 2012-2019 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 + * + * https://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 smoketest.webflux; import org.junit.jupiter.api.Test; + import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import static org.assertj.core.api.Assertions.assertThat; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {"management.server.port=0","management.endpoints.web.base-path=/"}) -public class WebFluxDifferentPortSampleActuatorApplicationTests { +/** + * Integration tests for separate management and main service ports with empty endpoint + * base path. + * + * @author HaiTao Zhang + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { "management.server.port=0", "management.endpoints.web.base-path=/" }) +class WebFluxDifferentPortSampleActuatorApplicationTests { @LocalManagementPort private int managementPort; - @LocalServerPort - private int port; - @Test - void testDifferentServerPort(){ - if(this.managementPort != this.port) { - ResponseEntity entity = new TestRestTemplate("user", getPassword()) - .getForEntity("http://localhost:" + this.managementPort + "/", String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(entity.getBody()).contains("\"_links\""); - } + void linksEndpointShouldBeAvailable() { + ResponseEntity entity = new TestRestTemplate("user", getPassword()) + .getForEntity("http://localhost:" + this.managementPort + "/", String.class); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(entity.getBody()).contains("\"_links\""); } - private String getPassword(){ + private String getPassword() { return "password"; } + }