From e0a6237b8ae5347b7bab6ba8d4cc3c7918be550d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Fri, 30 May 2025 12:06:09 +0200 Subject: [PATCH] Move Actuator infrastructure for WebFlux to spring-boot-webflux --- ...dFoundryWebFluxEndpointHandlerMapping.java | 2 +- .../HttpExchangesAutoConfiguration.java | 2 +- ...web.ManagementContextConfiguration.imports | 2 - .../WebFluxEndpointCorsIntegrationTests.java | 2 +- ...ndpointAdditionalPathIntegrationTests.java | 7 +- .../HttpExchangesAutoConfigurationTests.java | 2 +- ...ointReactiveWebExtensionConfiguration.java | 26 +----- .../HealthEndpointAutoConfigurationTests.java | 20 ----- .../AbstractEndpointDocumentationTests.java | 2 +- ...ndpointHandlerMappingIntegrationTests.java | 1 + .../WebFluxEndpointIntegrationTests.java | 1 + .../spring-boot-actuator/build.gradle | 2 +- .../modules/reference/pages/web/reactive.adoc | 2 +- .../spring-boot-webflux/build.gradle | 7 +- ...ndpointManagementContextConfiguration.java | 10 +-- .../endpoint/web}/package-info.java | 2 +- ...lthEndpointExtensionAutoConfiguration.java | 62 ++++++++++++++ .../autoconfigure/health/package-info.java | 20 +++++ ...xManagementChildContextConfiguration.java} | 14 +-- .../autoconfigure/web}/package-info.java | 2 +- ...AbstractWebFluxEndpointHandlerMapping.java | 6 +- ...lthEndpointPathsWebFluxHandlerMapping.java | 6 +- .../ControllerEndpointHandlerMapping.java | 4 +- .../web}/WebFluxEndpointHandlerMapping.java | 8 +- .../actuate/endpoint/web}/package-info.java | 4 +- .../exchanges}/HttpExchangesWebFilter.java | 4 +- .../RecordableServerHttpRequest.java | 2 +- .../RecordableServerHttpResponse.java | 2 +- .../actuate/web/exchanges}/package-info.java | 4 +- ...web.ManagementContextConfiguration.imports | 2 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + ...dpointExtensionAutoConfigurationTests.java | 85 +++++++++++++++++++ ...ContextConfigurationIntegrationTests.java} | 6 +- ...gementChildContextConfigurationTests.java} | 10 +-- ...actWebFluxEndpointHandlerMappingTests.java | 10 +-- ...ControllerEndpointHandlerMappingTests.java | 4 +- .../WebFluxEndpointHandlerMappingTests.java | 6 +- ...ttpExchangesWebFilterIntegrationTests.java | 4 +- .../HttpExchangesWebFilterTests.java | 4 +- .../RecordableServerHttpRequestTests.java | 4 +- .../test/WebFluxEndpointConfiguration.java | 2 +- 41 files changed, 250 insertions(+), 116 deletions(-) rename spring-boot-project/{spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive => spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/endpoint/web}/WebFluxEndpointManagementContextConfiguration.java (94%) rename spring-boot-project/{spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive => spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/endpoint/web}/package-info.java (90%) create mode 100644 spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/health/WebFluxHealthEndpointExtensionAutoConfiguration.java create mode 100644 spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/health/package-info.java rename spring-boot-project/{spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfiguration.java => spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/web/WebFluxManagementChildContextConfiguration.java} (83%) rename spring-boot-project/{spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive => spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/web}/package-info.java (90%) rename spring-boot-project/{spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive => spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web}/AbstractWebFluxEndpointHandlerMapping.java (98%) rename spring-boot-project/{spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive => spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web}/AdditionalHealthEndpointPathsWebFluxHandlerMapping.java (96%) rename spring-boot-project/{spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive => spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web}/ControllerEndpointHandlerMapping.java (98%) rename spring-boot-project/{spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive => spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web}/WebFluxEndpointHandlerMapping.java (94%) rename spring-boot-project/{spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive => spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web}/package-info.java (84%) rename spring-boot-project/{spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive => spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges}/HttpExchangesWebFilter.java (97%) rename spring-boot-project/{spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive => spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges}/RecordableServerHttpRequest.java (97%) rename spring-boot-project/{spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive => spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges}/RecordableServerHttpResponse.java (96%) rename spring-boot-project/{spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive => spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges}/package-info.java (85%) create mode 100644 spring-boot-project/spring-boot-webflux/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports create mode 100644 spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/autoconfigure/health/WebFluxHealthEndpointExtensionAutoConfigurationTests.java rename spring-boot-project/{spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfigurationIntegrationTests.java => spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/autoconfigure/web/WebFluxManagementChildContextConfigurationIntegrationTests.java} (97%) rename spring-boot-project/{spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfigurationTests.java => spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/autoconfigure/web/WebFluxManagementChildContextConfigurationTests.java} (81%) rename spring-boot-project/{spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive => spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web}/AbstractWebFluxEndpointHandlerMappingTests.java (72%) rename spring-boot-project/{spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive => spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web}/ControllerEndpointHandlerMappingTests.java (98%) rename spring-boot-project/{spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive => spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web}/WebFluxEndpointHandlerMappingTests.java (82%) rename spring-boot-project/{spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive => spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges}/HttpExchangesWebFilterIntegrationTests.java (97%) rename spring-boot-project/{spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive => spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges}/HttpExchangesWebFilterTests.java (97%) rename spring-boot-project/{spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive => spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges}/RecordableServerHttpRequestTests.java (96%) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java index 4d6b5913da..279c26ed78 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java @@ -41,7 +41,7 @@ import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; import org.springframework.boot.actuate.endpoint.web.Link; import org.springframework.boot.actuate.endpoint.web.WebOperation; -import org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping; +import org.springframework.boot.webflux.actuate.endpoint.web.AbstractWebFluxEndpointHandlerMapping; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfiguration.java index ab33137281..4aedddf9f9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfiguration.java @@ -18,7 +18,6 @@ package org.springframework.boot.actuate.autoconfigure.web.exchanges; import org.springframework.boot.actuate.web.exchanges.HttpExchange; import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository; -import org.springframework.boot.actuate.web.exchanges.reactive.HttpExchangesWebFilter; import org.springframework.boot.actuate.web.exchanges.servlet.HttpExchangesFilter; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -28,6 +27,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.webflux.actuate.web.exchanges.HttpExchangesWebFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports index b9305e3342..5df679e64f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports +++ b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports @@ -1,3 +1 @@ -org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive.WebFluxEndpointManagementContextConfiguration org.springframework.boot.actuate.autoconfigure.security.servlet.SecurityRequestMatchersManagementContextConfiguration -org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementChildContextConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxEndpointCorsIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxEndpointCorsIntegrationTests.java index 792f6ab072..b64682fd1b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxEndpointCorsIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxEndpointCorsIntegrationTests.java @@ -23,7 +23,6 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive.WebFluxEndpointManagementContextConfiguration; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration; @@ -31,6 +30,7 @@ import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.test.context.runner.ContextConsumer; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.web.context.reactive.ReactiveWebApplicationContext; +import org.springframework.boot.webflux.actuate.autoconfigure.endpoint.web.WebFluxEndpointManagementContextConfiguration; import org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration; import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; import org.springframework.http.HttpHeaders; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxHealthEndpointAdditionalPathIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxHealthEndpointAdditionalPathIntegrationTests.java index f067a03891..f80c0d62d6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxHealthEndpointAdditionalPathIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxHealthEndpointAdditionalPathIntegrationTests.java @@ -32,6 +32,7 @@ import org.springframework.boot.test.context.runner.ReactiveWebApplicationContex import org.springframework.boot.web.context.reactive.ConfigurableReactiveWebApplicationContext; import org.springframework.boot.web.server.context.ServerPortInfoApplicationContextInitializer; import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.webflux.actuate.autoconfigure.health.WebFluxHealthEndpointExtensionAutoConfiguration; import org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration; import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; @@ -47,9 +48,9 @@ class WebFluxHealthEndpointAdditionalPathIntegrationTests extends super(new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class, CodecsAutoConfiguration.class, WebFluxAutoConfiguration.class, HttpHandlerAutoConfiguration.class, EndpointAutoConfiguration.class, - HealthEndpointAutoConfiguration.class, DiskSpaceHealthContributorAutoConfiguration.class, - WebEndpointAutoConfiguration.class, ManagementContextAutoConfiguration.class, - NettyReactiveWebServerAutoConfiguration.class, + HealthEndpointAutoConfiguration.class, WebFluxHealthEndpointExtensionAutoConfiguration.class, + DiskSpaceHealthContributorAutoConfiguration.class, WebEndpointAutoConfiguration.class, + ManagementContextAutoConfiguration.class, NettyReactiveWebServerAutoConfiguration.class, NettyReactiveManagementContextAutoConfiguration.class, BeansEndpointAutoConfiguration.class)) .withInitializer(new ServerPortInfoApplicationContextInitializer()) .withPropertyValues("server.port=0")); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfigurationTests.java index b1baaf9968..67ec47b147 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfigurationTests.java @@ -25,11 +25,11 @@ import org.springframework.boot.actuate.web.exchanges.HttpExchange; import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository; import org.springframework.boot.actuate.web.exchanges.InMemoryHttpExchangeRepository; import org.springframework.boot.actuate.web.exchanges.Include; -import org.springframework.boot.actuate.web.exchanges.reactive.HttpExchangesWebFilter; import org.springframework.boot.actuate.web.exchanges.servlet.HttpExchangesFilter; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.webflux.actuate.web.exchanges.HttpExchangesWebFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointReactiveWebExtensionConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointReactiveWebExtensionConfiguration.java index 7bed528a65..35e5584b7a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointReactiveWebExtensionConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointReactiveWebExtensionConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 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. @@ -16,15 +16,8 @@ package org.springframework.boot.actuate.autoconfigure.health; -import java.util.Collection; - import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure; -import org.springframework.boot.actuate.endpoint.web.EndpointMapping; -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.actuate.endpoint.web.reactive.AdditionalHealthEndpointPathsWebFluxHandlerMapping; import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.actuate.health.HealthEndpointGroups; import org.springframework.boot.actuate.health.ReactiveHealthContributorRegistry; @@ -58,21 +51,4 @@ class HealthEndpointReactiveWebExtensionConfiguration { properties.getLogging().getSlowIndicatorThreshold()); } - @Configuration(proxyBeanMethods = false) - static class WebFluxAdditionalHealthEndpointPathsConfiguration { - - @Bean - AdditionalHealthEndpointPathsWebFluxHandlerMapping healthEndpointWebFluxHandlerMapping( - WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups groups) { - Collection webEndpoints = webEndpointsSupplier.getEndpoints(); - ExposableWebEndpoint health = webEndpoints.stream() - .filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID)) - .findFirst() - .orElse(null); - return new AdditionalHealthEndpointPathsWebFluxHandlerMapping(new EndpointMapping(""), health, - groups.getAllWithAdditionalPath(WebServerNamespace.SERVER)); - } - - } - } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointAutoConfigurationTests.java index c5815dfba3..b80f22d768 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointAutoConfigurationTests.java @@ -24,14 +24,11 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.condition.WithTestEndpointOutcomeExposureContributor; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointConfiguration.HealthEndpointGroupMembershipValidator.NoSuchHealthContributorException; -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointReactiveWebExtensionConfiguration.WebFluxAdditionalHealthEndpointPathsConfiguration; import org.springframework.boot.actuate.endpoint.ApiVersion; import org.springframework.boot.actuate.endpoint.SecurityContext; import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; -import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; import org.springframework.boot.actuate.health.CompositeHealthContributor; import org.springframework.boot.actuate.health.DefaultHealthContributorRegistry; @@ -340,23 +337,6 @@ class HealthEndpointAutoConfigurationTests { })); } - @Test - @WithTestEndpointOutcomeExposureContributor - void additionalReactiveHealthEndpointsPathsTolerateHealthEndpointThatIsNotWebExposed() { - this.reactiveContextRunner - .withConfiguration( - AutoConfigurations.of(EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class)) - .withPropertyValues("management.endpoints.web.exposure.exclude=*", - "management.endpoints.test.exposure.include=*") - .run((context) -> { - assertThat(context).hasNotFailed(); - assertThat(context).hasSingleBean(HealthEndpoint.class); - assertThat(context).hasSingleBean(ReactiveHealthEndpointWebExtension.class); - assertThat(context.getBean(WebEndpointsSupplier.class).getEndpoints()).isEmpty(); - assertThat(context).hasSingleBean(WebFluxAdditionalHealthEndpointPathsConfiguration.class); - }); - } - @Configuration(proxyBeanMethods = false) static class HealthIndicatorsConfiguration { diff --git a/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/AbstractEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/AbstractEndpointDocumentationTests.java index 2b3e6baf8f..a3f5c378af 100644 --- a/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/AbstractEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/AbstractEndpointDocumentationTests.java @@ -31,13 +31,13 @@ import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.jackson.JacksonEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive.WebFluxEndpointManagementContextConfiguration; import org.springframework.boot.actuate.docs.AbstractEndpointDocumentationTests.BaseDocumentationConfiguration; import org.springframework.boot.actuate.endpoint.jackson.EndpointObjectMapper; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.webflux.actuate.autoconfigure.endpoint.web.WebFluxEndpointManagementContextConfiguration; import org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration; import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; import org.springframework.boot.webmvc.actuate.autoconfigure.endpoint.web.WebMvcEndpointManagementContextConfiguration; diff --git a/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMappingIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMappingIntegrationTests.java index da98ad8b76..421087f048 100644 --- a/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMappingIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMappingIntegrationTests.java @@ -38,6 +38,7 @@ import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplic import org.springframework.boot.test.context.runner.ContextConsumer; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.webflux.actuate.endpoint.web.ControllerEndpointHandlerMapping; import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointIntegrationTests.java index e4c3258988..2a75698412 100644 --- a/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointIntegrationTests.java @@ -29,6 +29,7 @@ import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.reactor.netty.NettyReactiveWebServerFactory; import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; import org.springframework.boot.web.server.reactive.context.ReactiveWebServerInitializedEvent; +import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping; import org.springframework.boot.webflux.autoconfigure.error.ErrorWebFluxAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationListener; diff --git a/spring-boot-project/spring-boot-actuator/build.gradle b/spring-boot-project/spring-boot-actuator/build.gradle index a32e7cd551..a4ffb16a4c 100644 --- a/spring-boot-project/spring-boot-actuator/build.gradle +++ b/spring-boot-project/spring-boot-actuator/build.gradle @@ -37,7 +37,6 @@ dependencies { optional("org.springframework:spring-context-support") optional("org.springframework:spring-jdbc") optional("org.springframework:spring-messaging") - optional("org.springframework:spring-webflux") optional("org.springframework.graphql:spring-graphql") optional("org.springframework.security:spring-security-core") optional("org.springframework.security:spring-security-web") @@ -45,6 +44,7 @@ dependencies { testFixturesApi("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") testFixturesImplementation("org.junit.jupiter:junit-jupiter-api") testFixturesImplementation("org.springframework:spring-test") + testFixturesImplementation("org.springframework:spring-webflux") testImplementation(project(":spring-boot-project:spring-boot-autoconfigure")) testImplementation(project(":spring-boot-project:spring-boot-jackson")) diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/web/reactive.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/web/reactive.adoc index ef92b27b99..7910108165 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/web/reactive.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/web/reactive.adoc @@ -269,7 +269,7 @@ When it does so, the orders shown in the following table will be used: | javadoc:org.springframework.security.web.server.WebFilterChainProxy[] (Spring Security) | `-100` -| javadoc:org.springframework.boot.actuate.web.exchanges.reactive.HttpExchangesWebFilter[] +| javadoc:org.springframework.boot.webflux.actuate.web.exchanges.HttpExchangesWebFilter[] | `Ordered.LOWEST_PRECEDENCE - 10` |=== diff --git a/spring-boot-project/spring-boot-webflux/build.gradle b/spring-boot-project/spring-boot-webflux/build.gradle index 272b6e5f60..eca43f699c 100644 --- a/spring-boot-project/spring-boot-webflux/build.gradle +++ b/spring-boot-project/spring-boot-webflux/build.gradle @@ -16,11 +16,13 @@ dependencies { implementation(project(":spring-boot-project:spring-boot-http-codec")) implementation(project(":spring-boot-project:spring-boot-web-server")) - optional(project(":spring-boot-project:spring-boot-actuator")) + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) optional(project(":spring-boot-project:spring-boot-autoconfigure")) optional(project(":spring-boot-project:spring-boot-metrics")) optional(project(":spring-boot-project:spring-boot-observation")) optional(project(":spring-boot-project:spring-boot-validation")) + optional("com.fasterxml.jackson.core:jackson-databind") + optional("org.springframework.security:spring-security-core") testFixturesApi(testFixtures(project(":spring-boot-project:spring-boot-actuator"))) testFixturesImplementation(project(":spring-boot-project:spring-boot-jackson")) @@ -29,8 +31,11 @@ dependencies { testImplementation(project(":spring-boot-project:spring-boot-mustache")) testImplementation(project(":spring-boot-project:spring-boot-reactor-netty")) testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-actuator-autoconfigure"))) testImplementation(testFixtures(project(":spring-boot-project:spring-boot-web-server"))) + testImplementation("io.projectreactor:reactor-test") testImplementation("org.aspectj:aspectjweaver") testRuntimeOnly("ch.qos.logback:logback-classic") diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/endpoint/web/WebFluxEndpointManagementContextConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/endpoint/web/WebFluxEndpointManagementContextConfiguration.java index 573f7fc3b5..60e58c33ff 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/endpoint/web/WebFluxEndpointManagementContextConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive; +package org.springframework.boot.webflux.actuate.autoconfigure.endpoint.web; import java.util.ArrayList; import java.util.Arrays; @@ -47,8 +47,6 @@ import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; 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.actuate.endpoint.web.reactive.AdditionalHealthEndpointPathsWebFluxHandlerMapping; -import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping; import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.actuate.health.HealthEndpointGroups; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -57,6 +55,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.context.properties.EnableConfigurationProperties; +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.Role; import org.springframework.core.codec.Encoder; @@ -128,12 +128,12 @@ public class WebFluxEndpointManagementContextConfiguration { @ConditionalOnMissingBean @SuppressWarnings("removal") @Deprecated(since = "3.3.5", forRemoval = true) - public org.springframework.boot.actuate.endpoint.web.reactive.ControllerEndpointHandlerMapping controllerEndpointHandlerMapping( + public org.springframework.boot.webflux.actuate.endpoint.web.ControllerEndpointHandlerMapping controllerEndpointHandlerMapping( org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier controllerEndpointsSupplier, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, EndpointAccessResolver endpointAccessResolver) { EndpointMapping endpointMapping = new EndpointMapping(webEndpointProperties.getBasePath()); - return new org.springframework.boot.actuate.endpoint.web.reactive.ControllerEndpointHandlerMapping( + return new org.springframework.boot.webflux.actuate.endpoint.web.ControllerEndpointHandlerMapping( endpointMapping, controllerEndpointsSupplier.getEndpoints(), corsProperties.toCorsConfiguration(), endpointAccessResolver); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/package-info.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/endpoint/web/package-info.java similarity index 90% rename from spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/package-info.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/endpoint/web/package-info.java index 7f4e5cbaee..90794309ed 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/package-info.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/endpoint/web/package-info.java @@ -17,4 +17,4 @@ /** * Auto-configuration for exposing actuator web endpoints using WebFlux. */ -package org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive; +package org.springframework.boot.webflux.actuate.autoconfigure.endpoint.web; diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/health/WebFluxHealthEndpointExtensionAutoConfiguration.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/health/WebFluxHealthEndpointExtensionAutoConfiguration.java new file mode 100644 index 0000000000..63ba314611 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/health/WebFluxHealthEndpointExtensionAutoConfiguration.java @@ -0,0 +1,62 @@ +/* + * Copyright 2012-2025 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 org.springframework.boot.webflux.actuate.autoconfigure.health; + +import java.util.Collection; + +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure; +import org.springframework.boot.actuate.endpoint.web.EndpointMapping; +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.actuate.health.HealthEndpoint; +import org.springframework.boot.actuate.health.HealthEndpointGroups; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.webflux.actuate.endpoint.web.AdditionalHealthEndpointPathsWebFluxHandlerMapping; +import org.springframework.context.annotation.Bean; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for {@link HealthEndpoint} web + * extension with Spring WebFlux. + * + * @author Stephane Nicoll + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnWebApplication(type = Type.REACTIVE) +@ConditionalOnClass(HealthEndpoint.class) +@ConditionalOnAvailableEndpoint(endpoint = HealthEndpoint.class, exposure = EndpointExposure.WEB) +public class WebFluxHealthEndpointExtensionAutoConfiguration { + + @Bean + AdditionalHealthEndpointPathsWebFluxHandlerMapping healthEndpointWebFluxHandlerMapping( + WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups groups) { + Collection webEndpoints = webEndpointsSupplier.getEndpoints(); + ExposableWebEndpoint health = webEndpoints.stream() + .filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID)) + .findFirst() + .orElse(null); + return new AdditionalHealthEndpointPathsWebFluxHandlerMapping(new EndpointMapping(""), health, + groups.getAllWithAdditionalPath(WebServerNamespace.SERVER)); + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/health/package-info.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/health/package-info.java new file mode 100644 index 0000000000..fd089222ef --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-2025 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. + */ + +/** + * Auto-configuration for actuator health concerns using Spring WebFlux. + */ +package org.springframework.boot.webflux.actuate.autoconfigure.health; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfiguration.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/web/WebFluxManagementChildContextConfiguration.java similarity index 83% rename from spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfiguration.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/web/WebFluxManagementChildContextConfiguration.java index cb20de44d1..ea52ab8163 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfiguration.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/web/WebFluxManagementChildContextConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.reactive; +package org.springframework.boot.webflux.actuate.autoconfigure.web; import java.util.Collections; import java.util.Map; @@ -24,6 +24,7 @@ import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfi import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementWebServerFactoryCustomizer; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.web.server.ConfigurableWebServerFactory; @@ -32,6 +33,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.http.server.reactive.ContextPathCompositeHandler; import org.springframework.http.server.reactive.HttpHandler; import org.springframework.util.StringUtils; +import org.springframework.web.reactive.DispatcherHandler; import org.springframework.web.reactive.config.EnableWebFlux; import org.springframework.web.server.adapter.WebHttpHandlerBuilder; @@ -43,21 +45,21 @@ import org.springframework.web.server.adapter.WebHttpHandlerBuilder; * @author Andy Wilkinson * @author Phillip Webb * @author Moritz Halbritter - * @since 2.0.0 */ -@EnableWebFlux @ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false) @ConditionalOnWebApplication(type = Type.REACTIVE) -public class ReactiveManagementChildContextConfiguration { +@ConditionalOnClass(DispatcherHandler.class) +@EnableWebFlux +class WebFluxManagementChildContextConfiguration { @Bean - public ManagementWebServerFactoryCustomizer reactiveManagementWebServerFactoryCustomizer( + ManagementWebServerFactoryCustomizer reactiveManagementWebServerFactoryCustomizer( ListableBeanFactory beanFactory) { return new ManagementWebServerFactoryCustomizer<>(beanFactory); } @Bean - public HttpHandler httpHandler(ApplicationContext applicationContext, ManagementServerProperties properties) { + HttpHandler httpHandler(ApplicationContext applicationContext, ManagementServerProperties properties) { HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(applicationContext).build(); if (StringUtils.hasText(properties.getBasePath())) { Map handlersMap = Collections.singletonMap(properties.getBasePath(), httpHandler); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/package-info.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/web/package-info.java similarity index 90% rename from spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/package-info.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/web/package-info.java index 6ba76845ce..68c6cc6b70 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/package-info.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/web/package-info.java @@ -17,4 +17,4 @@ /** * Configuration for a WebFlux-based management context. */ -package org.springframework.boot.actuate.autoconfigure.web.reactive; +package org.springframework.boot.webflux.actuate.autoconfigure.web; 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-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/AbstractWebFluxEndpointHandlerMapping.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/AbstractWebFluxEndpointHandlerMapping.java index 62bddd46c8..2ff128b13b 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-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/AbstractWebFluxEndpointHandlerMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.reactive; +package org.springframework.boot.webflux.actuate.endpoint.web; import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; @@ -49,8 +49,8 @@ import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; import org.springframework.boot.actuate.endpoint.web.WebOperation; import org.springframework.boot.actuate.endpoint.web.WebOperationRequestPredicate; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; -import org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping.AbstractWebFluxEndpointHandlerMappingRuntimeHints; import org.springframework.boot.web.server.context.WebServerApplicationContext; +import org.springframework.boot.webflux.actuate.endpoint.web.AbstractWebFluxEndpointHandlerMapping.AbstractWebFluxEndpointHandlerMappingRuntimeHints; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; @@ -85,7 +85,7 @@ import org.springframework.web.util.pattern.PathPattern; * @author Phillip Webb * @author Brian Clozel * @author Scott Frederick - * @since 2.0.0 + * @since 4.0.0 */ @ImportRuntimeHints(AbstractWebFluxEndpointHandlerMappingRuntimeHints.class) public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappingInfoHandlerMapping { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AdditionalHealthEndpointPathsWebFluxHandlerMapping.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/AdditionalHealthEndpointPathsWebFluxHandlerMapping.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AdditionalHealthEndpointPathsWebFluxHandlerMapping.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/AdditionalHealthEndpointPathsWebFluxHandlerMapping.java index 93f7428869..55db20a006 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AdditionalHealthEndpointPathsWebFluxHandlerMapping.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/AdditionalHealthEndpointPathsWebFluxHandlerMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.reactive; +package org.springframework.boot.webflux.actuate.endpoint.web; import java.util.Collection; import java.util.Collections; @@ -36,7 +36,7 @@ import org.springframework.web.reactive.result.method.RequestMappingInfo; * path. * * @author Madhura Bhave - * @since 2.6.0 + * @since 4.0.0 */ public class AdditionalHealthEndpointPathsWebFluxHandlerMapping extends AbstractWebFluxEndpointHandlerMapping { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMapping.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/ControllerEndpointHandlerMapping.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMapping.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/ControllerEndpointHandlerMapping.java index a2f2d5142c..4c924fe65c 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/ControllerEndpointHandlerMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.reactive; +package org.springframework.boot.webflux.actuate.endpoint.web; import java.lang.reflect.Method; import java.util.Collection; @@ -46,7 +46,7 @@ import org.springframework.web.util.pattern.PathPattern; * annotated endpoints over Spring WebFlux. * * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 * @deprecated since 3.3.5 in favor of {@code @Endpoint} and {@code @WebEndpoint} support */ @Deprecated(since = "3.3.5", forRemoval = true) 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-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/WebFluxEndpointHandlerMapping.java similarity index 94% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMapping.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/WebFluxEndpointHandlerMapping.java index b9e898097f..373b1a3bb1 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-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/WebFluxEndpointHandlerMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.reactive; +package org.springframework.boot.webflux.actuate.endpoint.web; import java.util.Collection; import java.util.Collections; @@ -32,7 +32,7 @@ import org.springframework.boot.actuate.endpoint.web.EndpointMapping; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; import org.springframework.boot.actuate.endpoint.web.Link; -import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping.WebFluxEndpointHandlerMappingRuntimeHints; +import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping.WebFluxEndpointHandlerMappingRuntimeHints; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.cors.CorsConfiguration; @@ -47,7 +47,7 @@ import org.springframework.web.util.UriComponentsBuilder; * @author Andy Wilkinson * @author Phillip Webb * @author Brian Clozel - * @since 2.0.0 + * @since 4.0.0 */ @ImportRuntimeHints(WebFluxEndpointHandlerMappingRuntimeHints.class) public class WebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointHandlerMapping implements InitializingBean { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/package-info.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/package-info.java similarity index 84% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/package-info.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/package-info.java index c1788f9498..a14fff689e 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/package-info.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2025 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. @@ -17,4 +17,4 @@ /** * Spring WebFlux support for actuator endpoints. */ -package org.springframework.boot.actuate.endpoint.web.reactive; +package org.springframework.boot.webflux.actuate.endpoint.web; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilter.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilter.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilter.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilter.java index 411bc8faf1..78657a871a 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilter.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.reactive; +package org.springframework.boot.webflux.actuate.web.exchanges; import java.security.Principal; import java.util.Set; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequest.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpRequest.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequest.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpRequest.java index cda765aa92..f4b31158c6 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequest.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpRequest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.reactive; +package org.springframework.boot.webflux.actuate.web.exchanges; import java.net.InetAddress; import java.net.InetSocketAddress; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpResponse.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpResponse.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpResponse.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpResponse.java index 3faa76ce68..67a289562b 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpResponse.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpResponse.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.reactive; +package org.springframework.boot.webflux.actuate.web.exchanges; import java.util.Collections; import java.util.LinkedHashMap; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/package-info.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/package-info.java similarity index 85% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/package-info.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/package-info.java index 650befc80b..3b8206d126 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/package-info.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2025 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. @@ -19,4 +19,4 @@ * * @see org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository */ -package org.springframework.boot.actuate.web.exchanges.reactive; +package org.springframework.boot.webflux.actuate.web.exchanges; diff --git a/spring-boot-project/spring-boot-webflux/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports b/spring-boot-project/spring-boot-webflux/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports new file mode 100644 index 0000000000..23197578df --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.webflux.actuate.autoconfigure.endpoint.web.WebFluxEndpointManagementContextConfiguration +org.springframework.boot.webflux.actuate.autoconfigure.web.WebFluxManagementChildContextConfiguration diff --git a/spring-boot-project/spring-boot-webflux/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-webflux/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 62e2c9a046..d3b358a40d 100644 --- a/spring-boot-project/spring-boot-webflux/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/spring-boot-project/spring-boot-webflux/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,3 +1,4 @@ +org.springframework.boot.webflux.actuate.autoconfigure.health.WebFluxHealthEndpointExtensionAutoConfiguration org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration org.springframework.boot.webflux.autoconfigure.ReactiveMultipartAutoConfiguration org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration diff --git a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/autoconfigure/health/WebFluxHealthEndpointExtensionAutoConfigurationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/autoconfigure/health/WebFluxHealthEndpointExtensionAutoConfigurationTests.java new file mode 100644 index 0000000000..3a6f3ea376 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/autoconfigure/health/WebFluxHealthEndpointExtensionAutoConfigurationTests.java @@ -0,0 +1,85 @@ +/* + * Copyright 2012-2025 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 org.springframework.boot.webflux.actuate.autoconfigure.health; + +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; + +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.WithTestEndpointOutcomeExposureContributor; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; +import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension; +import org.springframework.boot.actuate.health.ReactiveHealthIndicator; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.webflux.actuate.endpoint.web.AdditionalHealthEndpointPathsWebFluxHandlerMapping; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link WebFluxHealthEndpointExtensionAutoConfiguration}. + * + * @author Stephane Nicoll + */ +class WebFluxHealthEndpointExtensionAutoConfigurationTests { + + private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() + .withUserConfiguration(HealthIndicatorsConfiguration.class) + .withConfiguration(AutoConfigurations.of(HealthContributorAutoConfiguration.class, + HealthEndpointAutoConfiguration.class, WebFluxHealthEndpointExtensionAutoConfiguration.class)); + + @Test + @WithTestEndpointOutcomeExposureContributor + void additionalReactiveHealthEndpointsPathsTolerateHealthEndpointThatIsNotWebExposed() { + this.contextRunner + .withConfiguration( + AutoConfigurations.of(EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class)) + .withPropertyValues("management.endpoints.web.exposure.exclude=*", + "management.endpoints.test.exposure.include=*") + .run((context) -> { + assertThat(context).hasNotFailed(); + assertThat(context).hasSingleBean(HealthEndpoint.class); + assertThat(context).hasSingleBean(ReactiveHealthEndpointWebExtension.class); + assertThat(context.getBean(WebEndpointsSupplier.class).getEndpoints()).isEmpty(); + assertThat(context).hasSingleBean(AdditionalHealthEndpointPathsWebFluxHandlerMapping.class); + }); + } + + @Configuration(proxyBeanMethods = false) + static class HealthIndicatorsConfiguration { + + @Bean + ReactiveHealthIndicator simpleHealthIndicator() { + return () -> Mono.just(Health.up().build()); + } + + @Bean + HealthIndicator additionalHealthIndicator() { + return () -> Health.up().build(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/autoconfigure/web/WebFluxManagementChildContextConfigurationIntegrationTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfigurationIntegrationTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/autoconfigure/web/WebFluxManagementChildContextConfigurationIntegrationTests.java index d997d5559b..9a03ecff26 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/autoconfigure/web/WebFluxManagementChildContextConfigurationIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.reactive; +package org.springframework.boot.webflux.actuate.autoconfigure.web; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -59,11 +59,11 @@ import org.springframework.web.reactive.function.client.WebClient; import static org.assertj.core.api.Assertions.assertThat; /** - * Integration tests for {@link ReactiveManagementChildContextConfiguration}. + * Integration tests for {@link WebFluxManagementChildContextConfiguration}. * * @author Andy Wilkinson */ -class ReactiveManagementChildContextConfigurationIntegrationTests { +class WebFluxManagementChildContextConfigurationIntegrationTests { private final List webServers = new ArrayList<>(); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfigurationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/autoconfigure/web/WebFluxManagementChildContextConfigurationTests.java similarity index 81% rename from spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfigurationTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/autoconfigure/web/WebFluxManagementChildContextConfigurationTests.java index d8616f063a..d40173ce12 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfigurationTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/autoconfigure/web/WebFluxManagementChildContextConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.reactive; +package org.springframework.boot.webflux.actuate.autoconfigure.web; import org.junit.jupiter.api.Test; @@ -24,18 +24,18 @@ import org.springframework.boot.test.context.runner.ReactiveWebApplicationContex import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link ReactiveManagementChildContextConfiguration}. + * Tests for {@link WebFluxManagementChildContextConfiguration}. * * @author Moritz Halbritter */ -class ReactiveManagementChildContextConfigurationTests { +class WebFluxManagementChildContextConfigurationTests { @Test // gh-45857 void failsWithoutManagementServerPropertiesBeanFromParent() { new ReactiveWebApplicationContextRunner() .run((parent) -> new ReactiveWebApplicationContextRunner().withParent(parent) - .withUserConfiguration(ReactiveManagementChildContextConfiguration.class) + .withUserConfiguration(WebFluxManagementChildContextConfiguration.class) .run((context) -> assertThat(context).hasFailed())); } @@ -44,7 +44,7 @@ class ReactiveManagementChildContextConfigurationTests { void succeedsWithManagementServerPropertiesBeanFromParent() { new ReactiveWebApplicationContextRunner().withBean(ManagementServerProperties.class) .run((parent) -> new ReactiveWebApplicationContextRunner().withParent(parent) - .withUserConfiguration(ReactiveManagementChildContextConfiguration.class) + .withUserConfiguration(WebFluxManagementChildContextConfiguration.class) .run((context) -> assertThat(context).hasNotFailed())); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMappingTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/AbstractWebFluxEndpointHandlerMappingTests.java similarity index 72% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMappingTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/AbstractWebFluxEndpointHandlerMappingTests.java index 3abb506a72..f24441110f 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMappingTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/AbstractWebFluxEndpointHandlerMappingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2025 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. @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.reactive; +package org.springframework.boot.webflux.actuate.endpoint.web; import org.junit.jupiter.api.Test; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.TypeReference; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping.AbstractWebFluxEndpointHandlerMappingRuntimeHints; +import org.springframework.boot.webflux.actuate.endpoint.web.AbstractWebFluxEndpointHandlerMapping.AbstractWebFluxEndpointHandlerMappingRuntimeHints; import static org.assertj.core.api.Assertions.assertThat; @@ -39,11 +39,11 @@ class AbstractWebFluxEndpointHandlerMappingTests { getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection() .onType(TypeReference - .of("org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping.WriteOperationHandler"))) + .of("org.springframework.boot.webflux.actuate.endpoint.web.AbstractWebFluxEndpointHandlerMapping.WriteOperationHandler"))) .accepts(runtimeHints); assertThat(RuntimeHintsPredicates.reflection() .onType(TypeReference - .of("org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping.ReadOperationHandler"))) + .of("org.springframework.boot.webflux.actuate.endpoint.web.AbstractWebFluxEndpointHandlerMapping.ReadOperationHandler"))) .accepts(runtimeHints); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMappingTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/ControllerEndpointHandlerMappingTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMappingTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/ControllerEndpointHandlerMappingTests.java index 51e9c83c2b..a829e17724 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMappingTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/ControllerEndpointHandlerMappingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.reactive; +package org.springframework.boot.webflux.actuate.endpoint.web; import java.time.Duration; import java.util.Arrays; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMappingTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/WebFluxEndpointHandlerMappingTests.java similarity index 82% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMappingTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/WebFluxEndpointHandlerMappingTests.java index 68456b1f57..78fc3c4dce 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMappingTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/WebFluxEndpointHandlerMappingTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.reactive; +package org.springframework.boot.webflux.actuate.endpoint.web; import org.junit.jupiter.api.Test; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.boot.actuate.endpoint.web.Link; -import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping.WebFluxEndpointHandlerMappingRuntimeHints; -import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping.WebFluxLinksHandler; +import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping.WebFluxEndpointHandlerMappingRuntimeHints; +import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping.WebFluxLinksHandler; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilterIntegrationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilterIntegrationTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilterIntegrationTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilterIntegrationTests.java index c3d0d70804..7379565438 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilterIntegrationTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilterIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.reactive; +package org.springframework.boot.webflux.actuate.web.exchanges; import java.util.EnumSet; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilterTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilterTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilterTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilterTests.java index caacc79498..62d2aa87c3 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilterTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.reactive; +package org.springframework.boot.webflux.actuate.web.exchanges; import java.security.Principal; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequestTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpRequestTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequestTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpRequestTests.java index 9a0962cec6..83fcb29de7 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequestTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpRequestTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.reactive; +package org.springframework.boot.webflux.actuate.web.exchanges; import java.net.InetSocketAddress; import java.net.URI; diff --git a/spring-boot-project/spring-boot-webflux/src/testFixtures/java/org/springframework/boot/webflux/actuate/endpoint/web/test/WebFluxEndpointConfiguration.java b/spring-boot-project/spring-boot-webflux/src/testFixtures/java/org/springframework/boot/webflux/actuate/endpoint/web/test/WebFluxEndpointConfiguration.java index 698545c673..fe3f5edc10 100644 --- a/spring-boot-project/spring-boot-webflux/src/testFixtures/java/org/springframework/boot/webflux/actuate/endpoint/web/test/WebFluxEndpointConfiguration.java +++ b/spring-boot-project/spring-boot-webflux/src/testFixtures/java/org/springframework/boot/webflux/actuate/endpoint/web/test/WebFluxEndpointConfiguration.java @@ -23,10 +23,10 @@ import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; import org.springframework.boot.actuate.endpoint.web.EndpointMapping; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; -import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.reactor.netty.NettyReactiveWebServerFactory; +import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping; import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean;