Browse Source

Merge branch '4.0.x'

Closes gh-49198
pull/49208/head
Andy Wilkinson 1 month ago
parent
commit
0c8f95575e
  1. 5
      module/spring-boot-webflux/build.gradle
  2. 37
      module/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxEndpointManagementContextConfiguration.java
  3. 9
      module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxManagementChildContextConfigurationIntegrationTests.java
  4. 46
      module/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointManagementContextConfiguration.java
  5. 7
      module/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointManagementContextConfigurationTests.java

5
module/spring-boot-webflux/build.gradle

@ -63,3 +63,8 @@ dependencies { @@ -63,3 +63,8 @@ dependencies {
tasks.named("compileTestJava") {
options.nullability.checking = "tests"
}
tasks.named("test") {
jvmArgs += "--add-opens=java.base/java.net=ALL-UNNAMED"
}

37
module/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxEndpointManagementContextConfiguration.java

@ -58,6 +58,7 @@ import org.springframework.boot.health.actuate.endpoint.HealthEndpointGroups; @@ -58,6 +58,7 @@ import org.springframework.boot.health.actuate.endpoint.HealthEndpointGroups;
import org.springframework.boot.webflux.actuate.endpoint.web.AdditionalHealthEndpointPathsWebFluxHandlerMapping;
import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;
import org.springframework.core.codec.Encoder;
import org.springframework.core.env.Environment;
@ -113,21 +114,6 @@ public class WebFluxEndpointManagementContextConfiguration { @@ -113,21 +114,6 @@ public class WebFluxEndpointManagementContextConfiguration {
|| ManagementPortType.get(environment) == ManagementPortType.DIFFERENT);
}
@Bean
@ConditionalOnManagementPort(ManagementPortType.DIFFERENT)
@ConditionalOnAvailableEndpoint(endpoint = HealthEndpoint.class, exposure = EndpointExposure.WEB)
@ConditionalOnBean(HealthEndpoint.class)
public AdditionalHealthEndpointPathsWebFluxHandlerMapping managementHealthEndpointWebFluxHandlerMapping(
WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups groups) {
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
ExposableWebEndpoint healthEndpoint = webEndpoints.stream()
.filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID))
.findFirst()
.orElse(null);
return new AdditionalHealthEndpointPathsWebFluxHandlerMapping(new EndpointMapping(""), healthEndpoint,
groups.getAllWithAdditionalPath(WebServerNamespace.MANAGEMENT));
}
@Bean
@ConditionalOnMissingBean
@SuppressWarnings("removal")
@ -161,6 +147,27 @@ public class WebFluxEndpointManagementContextConfiguration { @@ -161,6 +147,27 @@ public class WebFluxEndpointManagementContextConfiguration {
SingletonSupplier.of(endpointJsonMapper::getObject));
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(HealthEndpoint.class)
static class HealthConfiguration {
@Bean
@ConditionalOnManagementPort(ManagementPortType.DIFFERENT)
@ConditionalOnAvailableEndpoint(endpoint = HealthEndpoint.class, exposure = EndpointExposure.WEB)
@ConditionalOnBean(HealthEndpoint.class)
AdditionalHealthEndpointPathsWebFluxHandlerMapping managementHealthEndpointWebFluxHandlerMapping(
WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups groups) {
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
ExposableWebEndpoint healthEndpoint = webEndpoints.stream()
.filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID))
.findFirst()
.orElse(null);
return new AdditionalHealthEndpointPathsWebFluxHandlerMapping(new EndpointMapping(""), healthEndpoint,
groups.getAllWithAdditionalPath(WebServerNamespace.MANAGEMENT));
}
}
/**
* {@link BeanPostProcessor} to apply {@link EndpointJsonMapper} for
* {@link OperationResponseBody} to {@link JacksonJsonEncoder} instances.

9
module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxManagementChildContextConfigurationIntegrationTests.java

@ -41,6 +41,8 @@ import org.springframework.boot.env.ConfigTreePropertySource; @@ -41,6 +41,8 @@ import org.springframework.boot.env.ConfigTreePropertySource;
import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories;
import org.springframework.boot.tomcat.TomcatWebServer;
import org.springframework.boot.tomcat.autoconfigure.actuate.web.server.TomcatReactiveManagementContextAutoConfiguration;
import org.springframework.boot.tomcat.autoconfigure.reactive.TomcatReactiveWebServerAutoConfiguration;
@ -64,6 +66,7 @@ import static org.assertj.core.api.Assertions.assertThat; @@ -64,6 +66,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Andy Wilkinson
*/
@DirtiesUrlFactories
class WebFluxManagementChildContextConfigurationIntegrationTests {
private final List<WebServer> webServers = new ArrayList<>();
@ -124,6 +127,12 @@ class WebFluxManagementChildContextConfigurationIntegrationTests { @@ -124,6 +127,12 @@ class WebFluxManagementChildContextConfigurationIntegrationTests {
});
}
@Test
@ClassPathExclusions(packages = "org.springframework.boot.health.actuate.endpoint")
void refreshSucceedsWithoutHealth() {
this.runner.run((context) -> assertThat(context).hasNotFailed());
}
private @Nullable AccessLogValve findAccessLogValve() {
assertThat(this.webServers).hasSize(2);
Tomcat tomcat = ((TomcatWebServer) this.webServers.get(1)).getTomcat();

46
module/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointManagementContextConfiguration.java

@ -44,6 +44,7 @@ import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; @@ -44,6 +44,7 @@ import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.WebServerNamespace;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
@ -54,6 +55,7 @@ import org.springframework.boot.webmvc.actuate.endpoint.web.AdditionalHealthEndp @@ -54,6 +55,7 @@ import org.springframework.boot.webmvc.actuate.endpoint.web.AdditionalHealthEndp
import org.springframework.boot.webmvc.actuate.endpoint.web.WebMvcEndpointHandlerMapping;
import org.springframework.boot.webmvc.autoconfigure.DispatcherServletPath;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;
import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
@ -108,25 +110,6 @@ public class WebMvcEndpointManagementContextConfiguration { @@ -108,25 +110,6 @@ public class WebMvcEndpointManagementContextConfiguration {
|| ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
}
@Bean
@ConditionalOnManagementPort(ManagementPortType.DIFFERENT)
@ConditionalOnBean(HealthEndpoint.class)
@ConditionalOnAvailableEndpoint(endpoint = HealthEndpoint.class, exposure = EndpointExposure.WEB)
AdditionalHealthEndpointPathsWebMvcHandlerMapping managementHealthEndpointWebMvcHandlerMapping(
WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups groups) {
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
ExposableWebEndpoint healthEndpoint = webEndpoints.stream()
.filter(this::isHealthEndpoint)
.findFirst()
.orElse(null);
return new AdditionalHealthEndpointPathsWebMvcHandlerMapping(healthEndpoint,
groups.getAllWithAdditionalPath(WebServerNamespace.MANAGEMENT));
}
private boolean isHealthEndpoint(ExposableWebEndpoint endpoint) {
return endpoint.getEndpointId().equals(HealthEndpoint.ID);
}
@Bean
@ConditionalOnMissingBean
@SuppressWarnings("removal")
@ -169,6 +152,31 @@ public class WebMvcEndpointManagementContextConfiguration { @@ -169,6 +152,31 @@ public class WebMvcEndpointManagementContextConfiguration {
return new EndpointJackson2ObjectMapperWebMvcConfigurer(endpointJsonMapper);
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(HealthEndpoint.class)
static class HealthConfiguration {
@Bean
@ConditionalOnManagementPort(ManagementPortType.DIFFERENT)
@ConditionalOnBean(HealthEndpoint.class)
@ConditionalOnAvailableEndpoint(endpoint = HealthEndpoint.class, exposure = EndpointExposure.WEB)
AdditionalHealthEndpointPathsWebMvcHandlerMapping managementHealthEndpointWebMvcHandlerMapping(
WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups groups) {
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
ExposableWebEndpoint healthEndpoint = webEndpoints.stream()
.filter(this::isHealthEndpoint)
.findFirst()
.orElse(null);
return new AdditionalHealthEndpointPathsWebMvcHandlerMapping(healthEndpoint,
groups.getAllWithAdditionalPath(WebServerNamespace.MANAGEMENT));
}
private boolean isHealthEndpoint(ExposableWebEndpoint endpoint) {
return endpoint.getEndpointId().equals(HealthEndpoint.ID);
}
}
/**
* {@link WebMvcConfigurer} to apply {@link EndpointJsonMapper} for
* {@link OperationResponseBody} to {@link JacksonJsonHttpMessageConverter} instances.

7
module/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointManagementContextConfigurationTests.java

@ -30,6 +30,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -30,6 +30,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration;
import org.springframework.boot.webmvc.autoconfigure.DispatcherServletPath;
import org.springframework.context.annotation.Bean;
@ -66,6 +67,12 @@ class WebMvcEndpointManagementContextConfigurationTests { @@ -66,6 +67,12 @@ class WebMvcEndpointManagementContextConfigurationTests {
.run((context) -> assertThat(context).doesNotHaveBean(ServletEndpointRegistrar.class));
}
@Test
@ClassPathExclusions(packages = "org.springframework.boot.health.actuate.endpoint")
void refreshSucceedsWithoutHealth() {
this.contextRunner.run((context) -> assertThat(context).hasNotFailed());
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(WebMvcEndpointManagementContextConfiguration.class)
static class TestConfig {

Loading…
Cancel
Save