diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfiguration.java index 417465650a..ea79c24e16 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfiguration.java @@ -40,7 +40,7 @@ import org.springframework.context.annotation.Configuration; */ @AutoConfiguration @ConditionalOnWebApplication -@ConditionalOnProperty(prefix = "management.httpexchanges", name = "record", matchIfMissing = true) +@ConditionalOnProperty(prefix = "management.httpexchanges.recording", name = "enabled", matchIfMissing = true) @ConditionalOnBean(HttpExchangeRepository.class) @EnableConfigurationProperties(HttpExchangesProperties.class) public class HttpExchangesAutoConfiguration { @@ -52,7 +52,7 @@ public class HttpExchangesAutoConfiguration { @Bean @ConditionalOnMissingBean HttpExchangesFilter httpExchangesFilter(HttpExchangeRepository repository, HttpExchangesProperties properties) { - return new HttpExchangesFilter(repository, properties.getInclude()); + return new HttpExchangesFilter(repository, properties.getRecording().getInclude()); } } @@ -65,7 +65,7 @@ public class HttpExchangesAutoConfiguration { @ConditionalOnMissingBean HttpExchangesWebFilter httpExchangesWebFilter(HttpExchangeRepository repository, HttpExchangesProperties properties) { - return new HttpExchangesWebFilter(repository, properties.getInclude()); + return new HttpExchangesWebFilter(repository, properties.getRecording().getInclude()); } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/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 index 85b5bb2c6a..b4eb1c1df3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/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 @@ -35,19 +35,34 @@ import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "management.httpexchanges") public class HttpExchangesProperties { + private final Recording recording = new Recording(); + + public Recording getRecording() { + return this.recording; + } + /** - * Items to be included in the exchange recording. Defaults to request headers - * (excluding Authorization and Cookie), response headers (excluding Set-Cookie), and - * time taken. + * Recording properties. + * + * @since 3.0.0 */ - private Set include = new HashSet<>(Include.defaultIncludes()); + public static class Recording { - public Set getInclude() { - return this.include; - } + /** + * Items to be included in the exchange recording. Defaults to request headers + * (excluding Authorization and Cookie), response headers (excluding Set-Cookie), + * and time taken. + */ + private Set include = new HashSet<>(Include.defaultIncludes()); + + public Set getInclude() { + return this.include; + } + + public void setInclude(Set include) { + this.include = include; + } - public void setInclude(Set include) { - this.include = include; } } 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 2b21e01e49..fcdeda03d8 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 @@ -240,19 +240,19 @@ "defaultValue": true }, { - "name": "management.httpexchanges.include", + "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.httpexchanges.record", - "type": "java.lang.Boolean", - "description": "Whether to record HTTP request-response exchanges.", - "defaultValue": true - }, { "name": "management.influx.metrics.export.consistency", "defaultValue": "one" @@ -2141,21 +2141,21 @@ { "name": "management.trace.http.enabled", "deprecation": { - "replacement": "management.httpexchanges.record", + "replacement": "management.httpexchanges.recording.enabled", "level": "error" } }, { "name": "management.trace.http.include", "deprecation": { - "replacement": "management.httpexchanges.include", + "replacement": "management.httpexchanges.recording.include", "level": "error" } }, { "name": "management.trace.include", "deprecation": { - "replacement": "management.httpexchanges.include", + "replacement": "management.httpexchanges.recording.include", "level": "error" } }, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/HttpExchangesEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/HttpExchangesEndpointDocumentationTests.java index c877db48be..02de9f4403 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/HttpExchangesEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/HttpExchangesEndpointDocumentationTests.java @@ -33,8 +33,8 @@ import org.springframework.boot.actuate.web.exchanges.HttpExchange; import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository; import org.springframework.boot.actuate.web.exchanges.HttpExchangesEndpoint; import org.springframework.boot.actuate.web.exchanges.Include; -import org.springframework.boot.actuate.web.exchanges.SourceHttpRequest; -import org.springframework.boot.actuate.web.exchanges.SourceHttpResponse; +import org.springframework.boot.actuate.web.exchanges.RecordableHttpRequest; +import org.springframework.boot.actuate.web.exchanges.RecordableHttpResponse; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -62,12 +62,12 @@ class HttpExchangesEndpointDocumentationTests extends MockMvcEndpointDocumentati @Test void httpExchanges() throws Exception { - SourceHttpRequest request = mock(SourceHttpRequest.class); + RecordableHttpRequest request = mock(RecordableHttpRequest.class); given(request.getUri()).willReturn(URI.create("https://api.example.com")); given(request.getMethod()).willReturn("GET"); given(request.getHeaders()) .willReturn(Collections.singletonMap(HttpHeaders.ACCEPT, Arrays.asList("application/json"))); - SourceHttpResponse response = mock(SourceHttpResponse.class); + RecordableHttpResponse response = mock(RecordableHttpResponse.class); given(response.getStatus()).willReturn(200); given(response.getHeaders()) .willReturn(Collections.singletonMap(HttpHeaders.CONTENT_TYPE, Arrays.asList("application/json"))); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfigurationTests.java index ea6b176ae7..7ae1dc4149 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfigurationTests.java @@ -91,7 +91,7 @@ class HttpExchangesAutoConfigurationTests { @Test void backsOffWhenNotRecording() { this.contextRunner.withUserConfiguration(CustomHttpExchangesRepositoryConfiguration.class) - .withPropertyValues("management.httpexchanges.record=false") + .withPropertyValues("management.httpexchanges.recording.enabled=false") .run((context) -> assertThat(context).doesNotHaveBean(InMemoryHttpExchangeRepository.class) .doesNotHaveBean(HttpExchangesFilter.class)); } @@ -134,7 +134,7 @@ class HttpExchangesAutoConfigurationTests { @Bean CustomHttpExchangesWebFilter customWebFilter(HttpExchangeRepository repository, HttpExchangesProperties properties) { - return new CustomHttpExchangesWebFilter(repository, properties.getInclude()); + return new CustomHttpExchangesWebFilter(repository, properties.getRecording().getInclude()); } } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/HttpExchange.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/HttpExchange.java index 366b71ebf6..2b9881db93 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/HttpExchange.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/HttpExchange.java @@ -125,21 +125,21 @@ public final class HttpExchange { /** * Start a new {@link Started} from the given source request. - * @param sourceHttpRequest the source HTTP request + * @param request the recordable HTTP request * @return an in-progress request */ - public static Started start(SourceHttpRequest sourceHttpRequest) { - return start(Clock.systemUTC(), sourceHttpRequest); + public static Started start(RecordableHttpRequest request) { + return start(Clock.systemUTC(), request); } /** * Start a new {@link Started} from the given source request. * @param clock the clock to use - * @param sourceHttpRequest the source HTTP request + * @param request the recordable HTTP request * @return an in-progress request */ - public static Started start(Clock clock, SourceHttpRequest sourceHttpRequest) { - return new Started(clock, sourceHttpRequest); + public static Started start(Clock clock, RecordableHttpRequest request) { + return new Started(clock, request); } /** @@ -150,76 +150,74 @@ public final class HttpExchange { private final Instant timestamp; - private final SourceHttpRequest sourceRequest; + private final RecordableHttpRequest request; - private Started(Clock clock, SourceHttpRequest sourceRequest) { + private Started(Clock clock, RecordableHttpRequest request) { this.timestamp = Instant.now(clock); - this.sourceRequest = sourceRequest; + this.request = request; } /** * Finish the request and return a new {@link HttpExchange} instance. - * @param sourceHttpResponse the source HTTP response + * @param response the recordable HTTP response * @param principalSupplier a supplier to provide the principal * @param sessionIdSupplier a supplier to provide the session ID * @param includes the options to include * @return a new {@link HttpExchange} instance */ - public HttpExchange finish(SourceHttpResponse sourceHttpResponse, - Supplier principalSupplier, Supplier sessionIdSupplier, - Include... includes) { - return finish(Clock.systemUTC(), sourceHttpResponse, principalSupplier, sessionIdSupplier, includes); + public HttpExchange finish(RecordableHttpResponse response, Supplier principalSupplier, + Supplier sessionIdSupplier, Include... includes) { + return finish(Clock.systemUTC(), response, principalSupplier, sessionIdSupplier, includes); } /** * Finish the request and return a new {@link HttpExchange} instance. * @param clock the clock to use - * @param sourceHttpResponse the source HTTP response + * @param response the recordable HTTP response * @param principalSupplier a supplier to provide the principal * @param sessionIdSupplier a supplier to provide the session ID * @param includes the options to include * @return a new {@link HttpExchange} instance */ - public HttpExchange finish(Clock clock, SourceHttpResponse sourceHttpResponse, + public HttpExchange finish(Clock clock, RecordableHttpResponse response, Supplier principalSupplier, Supplier sessionIdSupplier, Include... includes) { - return finish(clock, sourceHttpResponse, principalSupplier, sessionIdSupplier, + return finish(clock, response, principalSupplier, sessionIdSupplier, new HashSet<>(Arrays.asList(includes))); } /** * Finish the request and return a new {@link HttpExchange} instance. - * @param sourceHttpResponse the source HTTP response + * @param response the recordable HTTP response * @param principalSupplier a supplier to provide the principal * @param sessionIdSupplier a supplier to provide the session ID * @param includes the options to include * @return a new {@link HttpExchange} instance */ - public HttpExchange finish(SourceHttpResponse sourceHttpResponse, - Supplier principalSupplier, Supplier sessionIdSupplier, - Set includes) { - return finish(Clock.systemUTC(), sourceHttpResponse, principalSupplier, sessionIdSupplier, includes); + public HttpExchange finish(RecordableHttpResponse response, Supplier principalSupplier, + Supplier sessionIdSupplier, Set includes) { + return finish(Clock.systemUTC(), response, principalSupplier, sessionIdSupplier, includes); } /** * Finish the request and return a new {@link HttpExchange} instance. * @param clock the clock to use - * @param sourceHttpResponse the source HTTP response + * @param response the recordable HTTP response * @param principalSupplier a supplier to provide the principal * @param sessionIdSupplier a supplier to provide the session ID * @param includes the options to include * @return a new {@link HttpExchange} instance */ - public HttpExchange finish(Clock clock, SourceHttpResponse sourceHttpResponse, + public HttpExchange finish(Clock clock, RecordableHttpResponse response, Supplier principalSupplier, Supplier sessionIdSupplier, Set includes) { - Request request = new Request(this.sourceRequest, includes); - Response response = new Response(sourceHttpResponse, includes); + Request exchangeRequest = new Request(this.request, includes); + Response exchangeResponse = new Response(response, includes); Principal principal = getIfIncluded(includes, Include.PRINCIPAL, () -> Principal.from(principalSupplier)); Session session = getIfIncluded(includes, Include.SESSION_ID, () -> Session.from(sessionIdSupplier)); Duration duration = getIfIncluded(includes, Include.TIME_TAKEN, () -> Duration.between(this.timestamp, Instant.now(clock))); - return new HttpExchange(this.timestamp, request, response, principal, session, duration); + return new HttpExchange(this.timestamp, exchangeRequest, exchangeResponse, principal, session, duration); } private T getIfIncluded(Set includes, Include include, Supplier supplier) { @@ -241,11 +239,11 @@ public final class HttpExchange { private final Map> headers; - private Request(SourceHttpRequest source, Set includes) { - this.uri = source.getUri(); - this.remoteAddress = (includes.contains(Include.REMOTE_ADDRESS)) ? source.getRemoteAddress() : null; - this.method = source.getMethod(); - this.headers = Collections.unmodifiableMap(filterHeaders(source.getHeaders(), includes)); + private Request(RecordableHttpRequest request, Set includes) { + this.uri = request.getUri(); + this.remoteAddress = (includes.contains(Include.REMOTE_ADDRESS)) ? request.getRemoteAddress() : null; + this.method = request.getMethod(); + this.headers = Collections.unmodifiableMap(filterHeaders(request.getHeaders(), includes)); } /** @@ -314,9 +312,9 @@ public final class HttpExchange { private final Map> headers; - private Response(SourceHttpResponse source, Set includes) { - this.status = source.getStatus(); - this.headers = Collections.unmodifiableMap(filterHeaders(source.getHeaders(), includes)); + private Response(RecordableHttpResponse request, Set includes) { + this.status = request.getStatus(); + this.headers = Collections.unmodifiableMap(filterHeaders(request.getHeaders(), includes)); } /** diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/SourceHttpRequest.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/RecordableHttpRequest.java similarity index 89% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/SourceHttpRequest.java rename to spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/RecordableHttpRequest.java index 1dfc6fd737..4fc3fd61f1 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/SourceHttpRequest.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/RecordableHttpRequest.java @@ -21,14 +21,14 @@ import java.util.List; import java.util.Map; /** - * The source of an HTTP request that will result in an {@link HttpExchange}. + * The recordable parts of an HTTP request used when creating an {@link HttpExchange}. * * @author Andy Wilkinson * @author Phillip Webb * @since 3.0.0 - * @see SourceHttpResponse + * @see RecordableHttpResponse */ -public interface SourceHttpRequest { +public interface RecordableHttpRequest { /** * Returns the URI of the request. diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/SourceHttpResponse.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/RecordableHttpResponse.java similarity index 86% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/SourceHttpResponse.java rename to spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/RecordableHttpResponse.java index 2039d64900..f4ed82023d 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/SourceHttpResponse.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/RecordableHttpResponse.java @@ -20,13 +20,13 @@ import java.util.List; import java.util.Map; /** - * The source of an HTTP response that will result in an {@link HttpExchange}. + * The recordable parts of an HTTP response used when creating an {@link HttpExchange}. * * @author Andy Wilkinson * @since 3.0.0 - * @see SourceHttpRequest + * @see RecordableHttpRequest */ -public interface SourceHttpResponse { +public interface RecordableHttpResponse { /** * The status of the response. 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-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilter.java index 3b32be692e..fb8f8558e2 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-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilter.java @@ -82,10 +82,10 @@ public class HttpExchangesWebFilter implements WebFilter, Ordered { } private void addExchangeOnCommit(ServerWebExchange exchange, PrincipalAndSession principalAndSession) { - SourceServerHttpRequest sourceRequest = new SourceServerHttpRequest(exchange.getRequest()); + RecordableServerHttpRequest sourceRequest = new RecordableServerHttpRequest(exchange.getRequest()); HttpExchange.Started startedHtppExchange = HttpExchange.start(sourceRequest); exchange.getResponse().beforeCommit(() -> { - SourceServerHttpResponse sourceResponse = new SourceServerHttpResponse(exchange.getResponse()); + RecordableServerHttpResponse sourceResponse = new RecordableServerHttpResponse(exchange.getResponse()); HttpExchange finishedExchange = startedHtppExchange.finish(sourceResponse, principalAndSession::getPrincipal, principalAndSession::getSessionId, this.includes); this.repository.add(finishedExchange); diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/SourceServerHttpRequest.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequest.java similarity index 85% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/SourceServerHttpRequest.java rename to spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequest.java index 7079f3229e..2fcc197cb1 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/SourceServerHttpRequest.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequest.java @@ -23,16 +23,15 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.springframework.boot.actuate.web.exchanges.SourceHttpRequest; +import org.springframework.boot.actuate.web.exchanges.RecordableHttpRequest; import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.web.server.ServerWebExchange; /** - * A {@link SourceHttpRequest} backed by a {@link ServerWebExchange}. + * A {@link RecordableHttpRequest} backed by a {@link ServerHttpRequest}. * * @author Andy Wilkinson */ -class SourceServerHttpRequest implements SourceHttpRequest { +class RecordableServerHttpRequest implements RecordableHttpRequest { private final String method; @@ -42,7 +41,7 @@ class SourceServerHttpRequest implements SourceHttpRequest { private final String remoteAddress; - SourceServerHttpRequest(ServerHttpRequest request) { + RecordableServerHttpRequest(ServerHttpRequest request) { this.method = request.getMethod().name(); this.headers = request.getHeaders(); this.uri = request.getURI(); diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/SourceServerHttpResponse.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpResponse.java similarity index 81% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/SourceServerHttpResponse.java rename to spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpResponse.java index 462ffd3322..cc00832e8f 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/SourceServerHttpResponse.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpResponse.java @@ -20,22 +20,23 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.springframework.boot.actuate.web.exchanges.SourceHttpResponse; +import org.springframework.boot.actuate.web.exchanges.RecordableHttpResponse; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpResponse; /** - * An adapter that exposes a {@link ServerHttpResponse} as a {@link SourceHttpResponse}. + * An adapter that exposes a {@link ServerHttpResponse} as a + * {@link RecordableHttpResponse}. * * @author Andy Wilkinson */ -class SourceServerHttpResponse implements SourceHttpResponse { +class RecordableServerHttpResponse implements RecordableHttpResponse { private final int status; private final Map> headers; - SourceServerHttpResponse(ServerHttpResponse response) { + RecordableServerHttpResponse(ServerHttpResponse response) { this.status = (response.getStatusCode() != null) ? response.getStatusCode().value() : HttpStatus.OK.value(); this.headers = new LinkedHashMap<>(response.getHeaders()); } 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-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/HttpExchangesFilter.java index c4e67ae9a2..5fe3a561d7 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-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/HttpExchangesFilter.java @@ -82,7 +82,7 @@ public class HttpExchangesFilter extends OncePerRequestFilter implements Ordered filterChain.doFilter(request, response); return; } - ServletSourceHttpRequest sourceRequest = new ServletSourceHttpRequest(request); + RecordableServletHttpRequest sourceRequest = new RecordableServletHttpRequest(request); HttpExchange.Started startedHtppExchange = HttpExchange.start(sourceRequest); int status = HttpStatus.INTERNAL_SERVER_ERROR.value(); try { @@ -90,7 +90,7 @@ public class HttpExchangesFilter extends OncePerRequestFilter implements Ordered status = response.getStatus(); } finally { - SourceServletHttpResponse sourceResponse = new SourceServletHttpResponse(response, status); + RecordableServletHttpResponse sourceResponse = new RecordableServletHttpResponse(response, status); HttpExchange finishedExchange = startedHtppExchange.finish(sourceResponse, request::getUserPrincipal, () -> getSessionId(request), this.includes); this.repository.add(finishedExchange); diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/ServletSourceHttpRequest.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequest.java similarity index 88% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/ServletSourceHttpRequest.java rename to spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequest.java index 24f00c296b..b42fad8355 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/ServletSourceHttpRequest.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequest.java @@ -27,20 +27,21 @@ import java.util.Map; import jakarta.servlet.http.HttpServletRequest; -import org.springframework.boot.actuate.web.exchanges.SourceHttpRequest; +import org.springframework.boot.actuate.web.exchanges.RecordableHttpRequest; import org.springframework.util.StringUtils; import org.springframework.web.util.UriUtils; /** - * An adapter that exposes an {@link HttpServletRequest} as a {@link SourceHttpRequest}. + * An adapter that exposes an {@link HttpServletRequest} as a + * {@link RecordableHttpRequest}. * * @author Andy Wilkinson */ -final class ServletSourceHttpRequest implements SourceHttpRequest { +final class RecordableServletHttpRequest implements RecordableHttpRequest { private final HttpServletRequest request; - ServletSourceHttpRequest(HttpServletRequest request) { + RecordableServletHttpRequest(HttpServletRequest request) { this.request = request; } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/SourceServletHttpResponse.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpResponse.java similarity index 80% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/SourceServletHttpResponse.java rename to spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpResponse.java index 6b5f2c5d3a..52f56b231e 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/SourceServletHttpResponse.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpResponse.java @@ -23,20 +23,21 @@ import java.util.Map; import jakarta.servlet.http.HttpServletResponse; -import org.springframework.boot.actuate.web.exchanges.SourceHttpResponse; +import org.springframework.boot.actuate.web.exchanges.RecordableHttpResponse; /** - * An adapter that exposes an {@link HttpServletResponse} as a {@link SourceHttpResponse}. + * An adapter that exposes an {@link HttpServletResponse} as a + * {@link RecordableHttpResponse}. * * @author Andy Wilkinson */ -final class SourceServletHttpResponse implements SourceHttpResponse { +final class RecordableServletHttpResponse implements RecordableHttpResponse { private final HttpServletResponse delegate; private final int status; - SourceServletHttpResponse(HttpServletResponse response, int status) { + RecordableServletHttpResponse(HttpServletResponse response, int status) { this.delegate = response; this.status = status; } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/HttpExchangeTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/HttpExchangeTests.java index 6048821350..bec552feab 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/HttpExchangeTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/HttpExchangeTests.java @@ -293,12 +293,12 @@ class HttpExchangeTests { assertThat(exchange.getResponse().getHeaders()).containsOnlyKeys(HttpHeaders.CONTENT_LENGTH); } - private SourceHttpRequest createRequest() { + private RecordableHttpRequest createRequest() { return createRequest(Collections.singletonMap(HttpHeaders.ACCEPT, Arrays.asList("application/json"))); } - private SourceHttpRequest createRequest(Map> headers) { - SourceHttpRequest request = mock(SourceHttpRequest.class); + private RecordableHttpRequest createRequest(Map> headers) { + RecordableHttpRequest request = mock(RecordableHttpRequest.class); given(request.getMethod()).willReturn("GET"); given(request.getUri()).willReturn(URI.create("https://api.example.com")); given(request.getHeaders()).willReturn(new HashMap<>(headers)); @@ -306,12 +306,12 @@ class HttpExchangeTests { return request; } - private SourceHttpResponse createResponse() { + private RecordableHttpResponse createResponse() { return createResponse(Collections.singletonMap(HttpHeaders.CONTENT_TYPE, Arrays.asList("application/json"))); } - private SourceHttpResponse createResponse(Map> headers) { - SourceHttpResponse response = mock(SourceHttpResponse.class); + private RecordableHttpResponse createResponse(Map> headers) { + RecordableHttpResponse response = mock(RecordableHttpResponse.class); given(response.getStatus()).willReturn(204); given(response.getHeaders()).willReturn(new HashMap<>(headers)); return response; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/HttpExchangesEndpointTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/HttpExchangesEndpointTests.java index 2f4ee56f57..ffb649cb90 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/HttpExchangesEndpointTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/HttpExchangesEndpointTests.java @@ -48,14 +48,14 @@ class HttpExchangesEndpointTests { assertThat(exchange.getRequest().getMethod()).isEqualTo("GET"); } - private SourceHttpRequest createRequest(String method) { - SourceHttpRequest request = mock(SourceHttpRequest.class); + private RecordableHttpRequest createRequest(String method) { + RecordableHttpRequest request = mock(RecordableHttpRequest.class); given(request.getMethod()).willReturn(method); return request; } - private SourceHttpResponse createResponse() { - return mock(SourceHttpResponse.class); + private RecordableHttpResponse createResponse() { + return mock(RecordableHttpResponse.class); } } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/InMemoryHttpExchangeRepositoryTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/InMemoryHttpExchangeRepositoryTests.java index 9ba1c616f0..fd95c230ff 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/InMemoryHttpExchangeRepositoryTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/InMemoryHttpExchangeRepositoryTests.java @@ -66,9 +66,9 @@ class InMemoryHttpExchangeRepositoryTests { } private HttpExchange createHttpExchange(String method) { - SourceHttpRequest request = mock(SourceHttpRequest.class); + RecordableHttpRequest request = mock(RecordableHttpRequest.class); given(request.getMethod()).willReturn(method); - SourceHttpResponse response = mock(SourceHttpResponse.class); + RecordableHttpResponse response = mock(RecordableHttpResponse.class); return HttpExchange.start(request).finish(response, NO_PRINCIPAL, NO_SESSION_ID); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/SourceServerHttpRequestTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequestTests.java similarity index 83% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/SourceServerHttpRequestTests.java rename to spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequestTests.java index 98c48b79d5..9a0962cec6 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/SourceServerHttpRequestTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequestTests.java @@ -34,11 +34,11 @@ import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; /** - * Tests for {@link SourceServerHttpRequest}. + * Tests for {@link RecordableServerHttpRequest}. * * @author Dmytro Nosan */ -class SourceServerHttpRequestTests { +class RecordableServerHttpRequestTests { private ServerWebExchange exchange; @@ -54,7 +54,7 @@ class SourceServerHttpRequestTests { @Test void getMethod() { - SourceServerHttpRequest sourceRequest = new SourceServerHttpRequest(this.request); + RecordableServerHttpRequest sourceRequest = new RecordableServerHttpRequest(this.request); assertThat(sourceRequest.getMethod()).isEqualTo("GET"); } @@ -62,7 +62,7 @@ class SourceServerHttpRequestTests { void getUri() { URI uri = URI.create("http://localhost:8080/"); given(this.request.getURI()).willReturn(uri); - SourceServerHttpRequest sourceRequest = new SourceServerHttpRequest(this.request); + RecordableServerHttpRequest sourceRequest = new RecordableServerHttpRequest(this.request); assertThat(sourceRequest.getUri()).isSameAs(uri); } @@ -71,7 +71,7 @@ class SourceServerHttpRequestTests { HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.add("name", "value"); given(this.request.getHeaders()).willReturn(httpHeaders); - SourceServerHttpRequest sourceRequest = new SourceServerHttpRequest(this.request); + RecordableServerHttpRequest sourceRequest = new RecordableServerHttpRequest(this.request); assertThat(sourceRequest.getHeaders()).containsOnly(entry("name", Collections.singletonList("value"))); } @@ -79,7 +79,7 @@ class SourceServerHttpRequestTests { void getUnresolvedRemoteAddress() { InetSocketAddress socketAddress = InetSocketAddress.createUnresolved("unresolved.example.com", 8080); given(this.request.getRemoteAddress()).willReturn(socketAddress); - SourceServerHttpRequest sourceRequest = new SourceServerHttpRequest(this.request); + RecordableServerHttpRequest sourceRequest = new RecordableServerHttpRequest(this.request); assertThat(sourceRequest.getRemoteAddress()).isNull(); } @@ -87,7 +87,7 @@ class SourceServerHttpRequestTests { void getRemoteAddress() { InetSocketAddress socketAddress = new InetSocketAddress(0); given(this.request.getRemoteAddress()).willReturn(socketAddress); - SourceServerHttpRequest sourceRequest = new SourceServerHttpRequest(this.request); + RecordableServerHttpRequest sourceRequest = new RecordableServerHttpRequest(this.request); assertThat(sourceRequest.getRemoteAddress()).isEqualTo(socketAddress.getAddress().toString()); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/ServletSourceHttpRequestTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequestTests.java similarity index 90% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/ServletSourceHttpRequestTests.java rename to spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequestTests.java index 67b5fea261..4f76d5d3f8 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/ServletSourceHttpRequestTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequestTests.java @@ -24,11 +24,11 @@ import org.springframework.mock.web.MockHttpServletRequest; import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link ServletSourceHttpRequest}. + * Tests for {@link RecordableServletHttpRequest}. * * @author Madhura Bhave */ -class ServletSourceHttpRequestTests { +class RecordableServletHttpRequestTests { private MockHttpServletRequest request; @@ -61,7 +61,7 @@ class ServletSourceHttpRequestTests { } private void validate(String expectedUri) { - ServletSourceHttpRequest sourceRequest = new ServletSourceHttpRequest(this.request); + RecordableServletHttpRequest sourceRequest = new RecordableServletHttpRequest(this.request); assertThat(sourceRequest.getUri().toString()).isEqualTo(expectedUri); } diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/http-exchanges.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/http-exchanges.adoc index a9a8969aca..e5fe03528b 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/http-exchanges.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/http-exchanges.adoc @@ -12,6 +12,6 @@ You can use the `httpexchanges` endpoint to obtain information about the request [[actuator.http-exchanges.custom]] === Custom HTTP Exchange Recording -To customize the items that are included in each recorded exchange, use the configprop:management.httpexchanges.include[] configuration property. +To customize the items that are included in each recorded exchange, use the configprop:management.httpexchanges.recording.include[] configuration property. -To disable recoding entirely, set configprop:management.httpexchanges.record[] to `false`. +To disable recoding entirely, set configprop:management.httpexchanges.recording.enabled[] to `false`. diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/resources/application.properties b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/resources/application.properties index ead47936e9..2a05e8284e 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/resources/application.properties +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/resources/application.properties @@ -17,7 +17,7 @@ spring.jmx.enabled=true spring.jackson.serialization.write_dates_as_timestamps=false -management.httpexchanges.include=request-headers,response-headers,principal,remote-address,session-id +management.httpexchanges.recording.include=request-headers,response-headers,principal,remote-address,session-id management.endpoint.health.show-details=always management.endpoint.health.group.ready.include=db,diskSpace