From 1ec60678955a692e776b4527dcfcd465e3c49f93 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 4 Jun 2025 14:42:59 +0100 Subject: [PATCH] Move HTTP exchange auto-config into appropriate modules See gh-46071 --- ...itional-spring-configuration-metadata.json | 14 -- ...ot.autoconfigure.AutoConfiguration.imports | 2 - .../JmxEndpointAccessIntegrationTests.java | 4 +- .../JmxEndpointIntegrationTests.java | 4 +- ...ebMvcEndpointExposureIntegrationTests.java | 4 +- .../HttpExchangesAutoConfigurationTests.java | 161 ------------------ ...ttpExchangesEndpointAutoConfiguration.java | 2 +- .../exchanges/HttpExchangesProperties.java | 0 .../web/exchanges/package-info.java | 0 ...itional-spring-configuration-metadata.json | 14 ++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + ...changesEndpointAutoConfigurationTests.java | 4 +- ...ervletHttpExchangesAutoConfiguration.java} | 40 ++--- .../autoconfigure/exchanges/package-info.java | 21 +++ .../exchanges}/HttpExchangesFilter.java | 4 +- .../RecordableServletHttpRequest.java | 2 +- .../RecordableServletHttpResponse.java | 2 +- .../actuate/exchanges}/package-info.java | 4 +- ...ot.autoconfigure.AutoConfiguration.imports | 1 + ...etHttpExchangesAutoConfigurationTests.java | 81 +++++++++ .../exchanges}/HttpExchangesFilterTests.java | 2 +- .../RecordableServletHttpRequestTests.java | 2 +- ...WebFluxHttpExchangesAutoConfiguration.java | 54 ++++++ .../autoconfigure/exchanges/package-info.java | 21 +++ .../exchanges/HttpExchangesWebFilter.java | 2 +- .../RecordableServerHttpRequest.java | 2 +- .../RecordableServerHttpResponse.java | 2 +- .../{web => }/exchanges/package-info.java | 2 +- ...ot.autoconfigure.AutoConfiguration.imports | 3 +- ...uxHttpExchangesAutoConfigurationTests.java | 83 +++++++++ ...ttpExchangesWebFilterIntegrationTests.java | 2 +- .../HttpExchangesWebFilterTests.java | 2 +- .../RecordableServerHttpRequestTests.java | 2 +- 33 files changed, 310 insertions(+), 234 deletions(-) delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfigurationTests.java rename spring-boot-project/{spring-boot-actuator-autoconfigure-all => spring-boot-actuator-autoconfigure}/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfiguration.java (96%) rename spring-boot-project/{spring-boot-actuator-autoconfigure-all => spring-boot-actuator-autoconfigure}/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesProperties.java (100%) rename spring-boot-project/{spring-boot-actuator-autoconfigure-all => spring-boot-actuator-autoconfigure}/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/package-info.java (100%) rename spring-boot-project/{spring-boot-actuator-autoconfigure-all => spring-boot-actuator-autoconfigure}/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfigurationTests.java (94%) rename spring-boot-project/{spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfiguration.java => spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/autoconfigure/exchanges/ServletHttpExchangesAutoConfiguration.java} (60%) create mode 100644 spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/autoconfigure/exchanges/package-info.java rename spring-boot-project/{spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet => spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges}/HttpExchangesFilter.java (97%) rename spring-boot-project/{spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet => spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges}/RecordableServletHttpRequest.java (97%) rename spring-boot-project/{spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet => spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges}/RecordableServletHttpResponse.java (96%) rename spring-boot-project/{spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet => spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges}/package-info.java (85%) create mode 100644 spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/autoconfigure/exchanges/ServletHttpExchangesAutoConfigurationTests.java rename spring-boot-project/{spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet => spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/exchanges}/HttpExchangesFilterTests.java (98%) rename spring-boot-project/{spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet => spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/exchanges}/RecordableServletHttpRequestTests.java (96%) create mode 100644 spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/exchanges/WebFluxHttpExchangesAutoConfiguration.java create mode 100644 spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/exchanges/package-info.java rename spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/{web => }/exchanges/HttpExchangesWebFilter.java (98%) rename spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/{web => }/exchanges/RecordableServerHttpRequest.java (97%) rename spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/{web => }/exchanges/RecordableServerHttpResponse.java (96%) rename spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/{web => }/exchanges/package-info.java (92%) create mode 100644 spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/autoconfigure/exchanges/WebFluxHttpExchangesAutoConfigurationTests.java rename spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/{web => }/exchanges/HttpExchangesWebFilterIntegrationTests.java (98%) rename spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/{web => }/exchanges/HttpExchangesWebFilterTests.java (98%) rename spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/{web => }/exchanges/RecordableServerHttpRequestTests.java (98%) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 02510d47819..4a3cbc952ae 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -6,20 +6,6 @@ "type": "java.lang.Boolean", "description": "Whether to enable SSL certificate health check.", "defaultValue": true - }, - { - "name": "management.httpexchanges.recording.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable HTTP request-response exchange recording.", - "defaultValue": true - }, - { - "name": "management.httpexchanges.recording.include", - "defaultValue": [ - "request-headers", - "response-headers", - "errors" - ] }, { "name": "management.otlp.tracing.export.enabled", diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index c51177ef371..d119b397999 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -12,5 +12,3 @@ org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryTracingAutoC org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingAutoConfiguration org.springframework.boot.actuate.autoconfigure.tracing.prometheus.PrometheusExemplarsAutoConfiguration org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinTracingAutoConfiguration -org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesAutoConfiguration -org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesEndpointAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JmxEndpointAccessIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JmxEndpointAccessIntegrationTests.java index f5516d3dee1..0ca8cf499ce 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JmxEndpointAccessIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JmxEndpointAccessIntegrationTests.java @@ -26,7 +26,6 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesAutoConfiguration; import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; @@ -47,8 +46,7 @@ class JmxEndpointAccessIntegrationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class, EndpointAutoConfiguration.class, - JmxEndpointAutoConfiguration.class, HealthContributorAutoConfiguration.class, - HttpExchangesAutoConfiguration.class)) + JmxEndpointAutoConfiguration.class, HealthContributorAutoConfiguration.class)) .withUserConfiguration(CustomJmxEndpoint.class) .withPropertyValues("spring.jmx.enabled=true") .withConfiguration(AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL)); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JmxEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JmxEndpointIntegrationTests.java index f3759191df5..8c0a4be15a6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JmxEndpointIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JmxEndpointIntegrationTests.java @@ -31,7 +31,6 @@ import org.springframework.boot.actuate.audit.InMemoryAuditEventRepository; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesAutoConfiguration; import org.springframework.boot.actuate.web.exchanges.InMemoryHttpExchangeRepository; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; @@ -52,8 +51,7 @@ class JmxEndpointIntegrationTests { private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() .withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class, EndpointAutoConfiguration.class, - JmxEndpointAutoConfiguration.class, HealthContributorAutoConfiguration.class, - HttpExchangesAutoConfiguration.class)) + JmxEndpointAutoConfiguration.class, HealthContributorAutoConfiguration.class)) .withUserConfiguration(HttpExchangeRepositoryConfiguration.class, AuditEventRepositoryConfiguration.class) .withPropertyValues("spring.jmx.enabled=true") .withConfiguration(AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL)); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcEndpointExposureIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcEndpointExposureIntegrationTests.java index e888ed01da1..28c338639ef 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcEndpointExposureIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcEndpointExposureIntegrationTests.java @@ -30,13 +30,13 @@ import org.springframework.boot.actuate.audit.InMemoryAuditEventRepository; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; import org.springframework.boot.actuate.web.exchanges.InMemoryHttpExchangeRepository; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.servlet.actuate.autoconfigure.ServletManagementContextAutoConfiguration; +import org.springframework.boot.servlet.actuate.autoconfigure.exchanges.ServletHttpExchangesAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; @@ -70,7 +70,7 @@ class WebMvcEndpointExposureIntegrationTests { JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, WebMvcAutoConfiguration.class, EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, ManagementContextAutoConfiguration.class, ManagementContextAutoConfiguration.class, - ServletManagementContextAutoConfiguration.class, HttpExchangesAutoConfiguration.class, + ServletManagementContextAutoConfiguration.class, ServletHttpExchangesAutoConfiguration.class, HealthContributorAutoConfiguration.class)) .withConfiguration(AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL)) .withUserConfiguration(CustomMvcEndpoint.class, CustomServletEndpoint.class, 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 deleted file mode 100644 index 59d294d5849..00000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfigurationTests.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2012-present 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.actuate.autoconfigure.web.exchanges; - -import java.util.List; -import java.util.Set; - -import org.junit.jupiter.api.Test; - -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.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; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link HttpExchangesAutoConfiguration}. - * - * @author Andy Wilkinson - * @author Madhura Bhave - */ -class HttpExchangesAutoConfigurationTests { - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(HttpExchangesAutoConfiguration.class)); - - @Test - void autoConfigurationIsDisabledByDefault() { - this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(HttpExchangesAutoConfiguration.class)); - } - - @Test - void autoConfigurationIsEnabledWhenHttpExchangeRepositoryBeanPresent() { - this.contextRunner.withUserConfiguration(CustomHttpExchangesRepositoryConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(HttpExchangesFilter.class); - assertThat(context).hasSingleBean(HttpExchangeRepository.class); - assertThat(context.getBean(HttpExchangeRepository.class)).isInstanceOf(CustomHttpExchangesRepository.class); - }); - } - - @Test - void usesUserProvidedWebFilterWhenReactiveContext() { - new ReactiveWebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(HttpExchangesAutoConfiguration.class)) - .withUserConfiguration(CustomHttpExchangesRepositoryConfiguration.class) - .withUserConfiguration(CustomWebFilterConfiguration.class) - .run((context) -> { - assertThat(context).hasSingleBean(HttpExchangesWebFilter.class); - assertThat(context.getBean(HttpExchangesWebFilter.class)) - .isInstanceOf(CustomHttpExchangesWebFilter.class); - }); - } - - @Test - void configuresServletFilter() { - this.contextRunner.withUserConfiguration(CustomHttpExchangesRepositoryConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(HttpExchangesFilter.class)); - } - - @Test - void usesUserProvidedServletFilter() { - this.contextRunner.withUserConfiguration(CustomHttpExchangesRepositoryConfiguration.class) - .withUserConfiguration(CustomFilterConfiguration.class) - .run((context) -> { - assertThat(context).hasSingleBean(HttpExchangesFilter.class); - assertThat(context.getBean(HttpExchangesFilter.class)).isInstanceOf(CustomHttpExchangesFilter.class); - }); - } - - @Test - void backsOffWhenNotRecording() { - this.contextRunner.withUserConfiguration(CustomHttpExchangesRepositoryConfiguration.class) - .withPropertyValues("management.httpexchanges.recording.enabled=false") - .run((context) -> assertThat(context).doesNotHaveBean(InMemoryHttpExchangeRepository.class) - .doesNotHaveBean(HttpExchangesFilter.class)); - } - - static class CustomHttpExchangesRepository implements HttpExchangeRepository { - - @Override - public List findAll() { - return null; - } - - @Override - public void add(HttpExchange exchange) { - - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomHttpExchangesRepositoryConfiguration { - - @Bean - CustomHttpExchangesRepository customRepository() { - return new CustomHttpExchangesRepository(); - } - - } - - private static final class CustomHttpExchangesWebFilter extends HttpExchangesWebFilter { - - private CustomHttpExchangesWebFilter(HttpExchangeRepository repository, Set includes) { - super(repository, includes); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomWebFilterConfiguration { - - @Bean - CustomHttpExchangesWebFilter customWebFilter(HttpExchangeRepository repository, - HttpExchangesProperties properties) { - return new CustomHttpExchangesWebFilter(repository, properties.getRecording().getInclude()); - } - - } - - private static final class CustomHttpExchangesFilter extends HttpExchangesFilter { - - private CustomHttpExchangesFilter(HttpExchangeRepository repository, Set includes) { - super(repository, includes); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomFilterConfiguration { - - @Bean - CustomHttpExchangesFilter customWebFilter(HttpExchangeRepository repository, Set includes) { - return new CustomHttpExchangesFilter(repository, includes); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfiguration.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfiguration.java index 388b1a4b4f6..0c285099c42 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfiguration.java @@ -32,7 +32,7 @@ import org.springframework.context.annotation.Bean; * @author Phillip Webb * @since 3.0.0 */ -@AutoConfiguration(after = HttpExchangesAutoConfiguration.class) +@AutoConfiguration @ConditionalOnAvailableEndpoint(HttpExchangesEndpoint.class) public class HttpExchangesEndpointAutoConfiguration { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesProperties.java similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesProperties.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesProperties.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/package-info.java similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/package-info.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/package-info.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 84c29f7641a..06eac54ccfe 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -138,6 +138,20 @@ "description": "Whether to enable readiness state health check.", "defaultValue": false }, + { + "name": "management.httpexchanges.recording.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable HTTP request-response exchange recording.", + "defaultValue": true + }, + { + "name": "management.httpexchanges.recording.include", + "defaultValue": [ + "request-headers", + "response-headers", + "errors" + ] + }, { "name": "management.info.build.enabled", "type": "java.lang.Boolean", diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 61d842de225..3ad7d831009 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -23,5 +23,6 @@ org.springframework.boot.actuate.autoconfigure.sbom.SbomEndpointAutoConfiguratio org.springframework.boot.actuate.autoconfigure.scheduling.ScheduledTasksEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.startup.StartupEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.system.DiskSpaceHealthContributorAutoConfiguration +org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.web.mappings.MappingsEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfigurationTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfigurationTests.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfigurationTests.java index 2c3e4d3d414..8bea75726e4 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfigurationTests.java @@ -35,8 +35,8 @@ import static org.assertj.core.api.Assertions.assertThat; */ class HttpExchangesEndpointAutoConfigurationTests { - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner().withConfiguration( - AutoConfigurations.of(HttpExchangesAutoConfiguration.class, HttpExchangesEndpointAutoConfiguration.class)); + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(HttpExchangesEndpointAutoConfiguration.class)); @Test void runWhenRepositoryBeanAvailableShouldHaveEndpointBean() { 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-servlet/src/main/java/org/springframework/boot/servlet/actuate/autoconfigure/exchanges/ServletHttpExchangesAutoConfiguration.java similarity index 60% rename from spring-boot-project/spring-boot-actuator-autoconfigure-all/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfiguration.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/autoconfigure/exchanges/ServletHttpExchangesAutoConfiguration.java index 3ed9282896f..a5b776f1615 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-servlet/src/main/java/org/springframework/boot/servlet/actuate/autoconfigure/exchanges/ServletHttpExchangesAutoConfiguration.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.exchanges; +package org.springframework.boot.servlet.actuate.autoconfigure.exchanges; +import org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesProperties; import org.springframework.boot.actuate.web.exchanges.HttpExchange; import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository; -import org.springframework.boot.actuate.web.exchanges.servlet.HttpExchangesFilter; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -27,47 +27,27 @@ 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.boot.servlet.actuate.exchanges.HttpExchangesFilter; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; /** * {@link EnableAutoConfiguration Auto-configuration} to record {@link HttpExchange HTTP * exchanges}. * * @author Dave Syer - * @since 3.0.0 + * @since 4.0.0 */ @AutoConfiguration -@ConditionalOnWebApplication +@ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnBooleanProperty(name = "management.httpexchanges.recording.enabled", matchIfMissing = true) @ConditionalOnBean(HttpExchangeRepository.class) @EnableConfigurationProperties(HttpExchangesProperties.class) -public class HttpExchangesAutoConfiguration { - - @Configuration(proxyBeanMethods = false) - @ConditionalOnWebApplication(type = Type.SERVLET) - static class ServletHttpExchangesConfiguration { - - @Bean - @ConditionalOnMissingBean - HttpExchangesFilter httpExchangesFilter(HttpExchangeRepository repository, HttpExchangesProperties properties) { - return new HttpExchangesFilter(repository, properties.getRecording().getInclude()); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnWebApplication(type = Type.REACTIVE) - static class ReactiveHttpExchangesConfiguration { - - @Bean - @ConditionalOnMissingBean - HttpExchangesWebFilter httpExchangesWebFilter(HttpExchangeRepository repository, - HttpExchangesProperties properties) { - return new HttpExchangesWebFilter(repository, properties.getRecording().getInclude()); - } +public class ServletHttpExchangesAutoConfiguration { + @Bean + @ConditionalOnMissingBean + HttpExchangesFilter httpExchangesFilter(HttpExchangeRepository repository, HttpExchangesProperties properties) { + return new HttpExchangesFilter(repository, properties.getRecording().getInclude()); } } diff --git a/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/autoconfigure/exchanges/package-info.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/autoconfigure/exchanges/package-info.java new file mode 100644 index 00000000000..b65171b8922 --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/autoconfigure/exchanges/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present 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 Servlet-based integration with Actuator's HTTP exchanges + * support. + */ +package org.springframework.boot.servlet.actuate.autoconfigure.exchanges; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/HttpExchangesFilter.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/HttpExchangesFilter.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/HttpExchangesFilter.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/HttpExchangesFilter.java index b02537214ae..8b82c9938e4 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/HttpExchangesFilter.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/HttpExchangesFilter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.servlet; +package org.springframework.boot.servlet.actuate.exchanges; import java.io.IOException; import java.net.URI; @@ -43,7 +43,7 @@ import org.springframework.web.filter.OncePerRequestFilter; * @author Andy Wilkinson * @author Venil Noronha * @author Madhura Bhave - * @since 3.0.0 + * @since 4.0.0 */ public class HttpExchangesFilter extends OncePerRequestFilter implements Ordered { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequest.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpRequest.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequest.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpRequest.java index 20ec61db570..aaefc148da4 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequest.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpRequest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.servlet; +package org.springframework.boot.servlet.actuate.exchanges; import java.net.URI; import java.net.URISyntaxException; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpResponse.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpResponse.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpResponse.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpResponse.java index f6cfb7ed4e9..2666dbf112c 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpResponse.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpResponse.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.servlet; +package org.springframework.boot.servlet.actuate.exchanges; import java.util.ArrayList; import java.util.LinkedHashMap; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/package-info.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/package-info.java similarity index 85% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/package-info.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/package-info.java index e1020dd754b..dce4f92c9ec 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/package-info.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/package-info.java @@ -15,8 +15,8 @@ */ /** - * Actuator HTTP exchanges support for servlet servers. + * Actuator HTTP exchanges support for Servlet servers. * * @see org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository */ -package org.springframework.boot.actuate.web.exchanges.servlet; +package org.springframework.boot.servlet.actuate.exchanges; diff --git a/spring-boot-project/spring-boot-servlet/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-servlet/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index f496b9b99d8..69bde43033a 100644 --- a/spring-boot-project/spring-boot-servlet/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/spring-boot-project/spring-boot-servlet/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,3 +1,4 @@ org.springframework.boot.servlet.actuate.autoconfigure.ServletManagementContextAutoConfiguration +org.springframework.boot.servlet.actuate.autoconfigure.exchanges.ServletHttpExchangesAutoConfiguration org.springframework.boot.servlet.actuate.autoconfigure.mappings.ServletMappingsAutoConfiguration org.springframework.boot.servlet.autoconfigure.MultipartAutoConfiguration diff --git a/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/autoconfigure/exchanges/ServletHttpExchangesAutoConfigurationTests.java b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/autoconfigure/exchanges/ServletHttpExchangesAutoConfigurationTests.java new file mode 100644 index 00000000000..7e93a3f21d8 --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/autoconfigure/exchanges/ServletHttpExchangesAutoConfigurationTests.java @@ -0,0 +1,81 @@ +/* + * Copyright 2012-present 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.servlet.actuate.autoconfigure.exchanges; + +import java.util.EnumSet; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +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.autoconfigure.AutoConfigurations; +import org.springframework.boot.servlet.actuate.exchanges.HttpExchangesFilter; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ServletHttpExchangesAutoConfiguration}. + * + * @author Andy Wilkinson + */ +class ServletHttpExchangesAutoConfigurationTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ServletHttpExchangesAutoConfiguration.class)); + + @Test + void whenRecordingIsDisabledThenFilterIsNotCreated() { + this.contextRunner.withBean(InMemoryHttpExchangeRepository.class) + .withPropertyValues("management.httpexchanges.recording.enabled=false") + .run((context) -> assertThat(context).doesNotHaveBean(HttpExchangesFilter.class)); + } + + @Test + void whenNoRepositoryIsDefinedThenFilterIsNotCreated() { + this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(HttpExchangesFilter.class)); + } + + @Test + void filterIsCreated() { + this.contextRunner.withBean(InMemoryHttpExchangeRepository.class) + .run((context) -> assertThat(context).hasSingleBean(HttpExchangesFilter.class)); + } + + @Test + void usesUserProvidedWebFilter() { + InMemoryHttpExchangeRepository repository = new InMemoryHttpExchangeRepository(); + this.contextRunner.withBean(InMemoryHttpExchangeRepository.class, () -> repository) + .withBean(CustomHttpExchangesFilter.class, + () -> new CustomHttpExchangesFilter(repository, EnumSet.allOf(Include.class))) + .run((context) -> { + assertThat(context).hasSingleBean(HttpExchangesFilter.class); + assertThat(context.getBean(HttpExchangesFilter.class)).isInstanceOf(CustomHttpExchangesFilter.class); + }); + } + + private static final class CustomHttpExchangesFilter extends HttpExchangesFilter { + + private CustomHttpExchangesFilter(HttpExchangeRepository repository, Set includes) { + super(repository, includes); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/HttpExchangesFilterTests.java b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/exchanges/HttpExchangesFilterTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/HttpExchangesFilterTests.java rename to spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/exchanges/HttpExchangesFilterTests.java index d203e86828a..9b04520a7a8 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/HttpExchangesFilterTests.java +++ b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/exchanges/HttpExchangesFilterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.servlet; +package org.springframework.boot.servlet.actuate.exchanges; import java.io.IOException; import java.security.Principal; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequestTests.java b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpRequestTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequestTests.java rename to spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpRequestTests.java index 361ae1706dc..53606ecb5a0 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequestTests.java +++ b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpRequestTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.servlet; +package org.springframework.boot.servlet.actuate.exchanges; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/exchanges/WebFluxHttpExchangesAutoConfiguration.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/exchanges/WebFluxHttpExchangesAutoConfiguration.java new file mode 100644 index 00000000000..900089cd405 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/exchanges/WebFluxHttpExchangesAutoConfiguration.java @@ -0,0 +1,54 @@ +/* + * Copyright 2012-present 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.exchanges; + +import org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesProperties; +import org.springframework.boot.actuate.web.exchanges.HttpExchange; +import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; +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.exchanges.HttpExchangesWebFilter; +import org.springframework.context.annotation.Bean; + +/** + * {@link EnableAutoConfiguration Auto-configuration} to record {@link HttpExchange HTTP + * exchanges}. + * + * @author Dave Syer + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnWebApplication(type = Type.REACTIVE) +@ConditionalOnBooleanProperty(name = "management.httpexchanges.recording.enabled", matchIfMissing = true) +@ConditionalOnBean(HttpExchangeRepository.class) +@EnableConfigurationProperties(HttpExchangesProperties.class) +public class WebFluxHttpExchangesAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + HttpExchangesWebFilter httpExchangesWebFilter(HttpExchangeRepository repository, + HttpExchangesProperties properties) { + return new HttpExchangesWebFilter(repository, properties.getRecording().getInclude()); + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/exchanges/package-info.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/exchanges/package-info.java new file mode 100644 index 00000000000..8eafe0867f7 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/autoconfigure/exchanges/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present 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 WebFlux-based integration with Actuator's HTTP exchanges + * support. + */ +package org.springframework.boot.webflux.actuate.autoconfigure.exchanges; diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilter.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilter.java similarity index 98% rename from spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilter.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilter.java index d1146665caf..4d72a1f4ea6 100644 --- a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilter.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.webflux.actuate.web.exchanges; +package org.springframework.boot.webflux.actuate.exchanges; import java.security.Principal; import java.util.Set; diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpRequest.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpRequest.java similarity index 97% rename from spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpRequest.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpRequest.java index bd464d90498..63bdebff43d 100644 --- a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpRequest.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpRequest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.webflux.actuate.web.exchanges; +package org.springframework.boot.webflux.actuate.exchanges; import java.net.InetAddress; import java.net.InetSocketAddress; diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpResponse.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpResponse.java similarity index 96% rename from spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpResponse.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpResponse.java index 1e70b756224..dcca41210b6 100644 --- a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpResponse.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpResponse.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.webflux.actuate.web.exchanges; +package org.springframework.boot.webflux.actuate.exchanges; import java.util.Collections; import java.util.LinkedHashMap; diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/package-info.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/package-info.java similarity index 92% rename from spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/package-info.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/package-info.java index 9b25334994a..3175301f3b5 100644 --- a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/web/exchanges/package-info.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/package-info.java @@ -19,4 +19,4 @@ * * @see org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository */ -package org.springframework.boot.webflux.actuate.web.exchanges; +package org.springframework.boot.webflux.actuate.exchanges; 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 8f8b489e602..0baeaf3f6f5 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.exchanges.WebFluxHttpExchangesAutoConfiguration org.springframework.boot.webflux.actuate.autoconfigure.health.WebFluxHealthEndpointExtensionAutoConfiguration org.springframework.boot.webflux.actuate.autoconfigure.mappings.WebFluxMappingsAutoConfiguration org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration @@ -5,4 +6,4 @@ org.springframework.boot.webflux.autoconfigure.ReactiveMultipartAutoConfiguratio org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration org.springframework.boot.webflux.autoconfigure.WebSessionIdResolverAutoConfiguration org.springframework.boot.webflux.autoconfigure.error.ErrorWebFluxAutoConfiguration -org.springframework.boot.webflux.observation.autoconfigure.WebFluxObservationAutoConfiguration \ No newline at end of file +org.springframework.boot.webflux.observation.autoconfigure.WebFluxObservationAutoConfiguration diff --git a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/autoconfigure/exchanges/WebFluxHttpExchangesAutoConfigurationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/autoconfigure/exchanges/WebFluxHttpExchangesAutoConfigurationTests.java new file mode 100644 index 00000000000..9386c0e5cca --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/autoconfigure/exchanges/WebFluxHttpExchangesAutoConfigurationTests.java @@ -0,0 +1,83 @@ +/* + * Copyright 2012-present 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.exchanges; + +import java.util.EnumSet; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +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.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.webflux.actuate.exchanges.HttpExchangesWebFilter; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link WebFluxHttpExchangesAutoConfiguration}. + * + * @author Andy Wilkinson + * @author Madhura Bhave + */ +class WebFluxHttpExchangesAutoConfigurationTests { + + private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(WebFluxHttpExchangesAutoConfiguration.class)); + + @Test + void whenRecordingIsDisabledThenFilterIsNotCreated() { + this.contextRunner.withBean(InMemoryHttpExchangeRepository.class) + .withPropertyValues("management.httpexchanges.recording.enabled=false") + .run((context) -> assertThat(context).doesNotHaveBean(HttpExchangesWebFilter.class)); + } + + @Test + void whenNoRepositoryIsDefinedThenFilterIsNotCreated() { + this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(HttpExchangesWebFilter.class)); + } + + @Test + void filterIsCreated() { + this.contextRunner.withBean(InMemoryHttpExchangeRepository.class) + .run((context) -> assertThat(context).hasSingleBean(HttpExchangesWebFilter.class)); + } + + @Test + void usesUserProvidedWebFilter() { + InMemoryHttpExchangeRepository repository = new InMemoryHttpExchangeRepository(); + this.contextRunner.withBean(InMemoryHttpExchangeRepository.class, () -> repository) + .withBean(CustomHttpExchangesWebFilter.class, + () -> new CustomHttpExchangesWebFilter(repository, EnumSet.allOf(Include.class))) + .run((context) -> { + assertThat(context).hasSingleBean(HttpExchangesWebFilter.class); + assertThat(context.getBean(HttpExchangesWebFilter.class)) + .isInstanceOf(CustomHttpExchangesWebFilter.class); + }); + } + + private static final class CustomHttpExchangesWebFilter extends HttpExchangesWebFilter { + + private CustomHttpExchangesWebFilter(HttpExchangeRepository repository, Set includes) { + super(repository, includes); + } + + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilterIntegrationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilterIntegrationTests.java similarity index 98% rename from spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilterIntegrationTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilterIntegrationTests.java index 8caa555a85c..b7cdd6c1a18 100644 --- a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilterIntegrationTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilterIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.webflux.actuate.web.exchanges; +package org.springframework.boot.webflux.actuate.exchanges; import java.util.EnumSet; diff --git a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilterTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilterTests.java similarity index 98% rename from spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilterTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilterTests.java index be03e9ff3b8..83e1c866714 100644 --- a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/HttpExchangesWebFilterTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.webflux.actuate.web.exchanges; +package org.springframework.boot.webflux.actuate.exchanges; import java.security.Principal; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpRequestTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpRequestTests.java similarity index 98% rename from spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpRequestTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpRequestTests.java index 3df636b3237..0c5d6c027a8 100644 --- a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/web/exchanges/RecordableServerHttpRequestTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpRequestTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.webflux.actuate.web.exchanges; +package org.springframework.boot.webflux.actuate.exchanges; import java.net.InetSocketAddress; import java.net.URI;