diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java index 179964cd94..729d0a1d13 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java @@ -180,7 +180,7 @@ class DefaultWebTestClient implements WebTestClient { DefaultRequestBodySpec(WebClient.RequestBodySpec spec) { this.bodySpec = spec; this.requestId = String.valueOf(requestIndex.incrementAndGet()); - this.bodySpec.header(WiretapConnector.REQUEST_ID_HEADER_NAME, this.requestId); + this.bodySpec.header(WebTestClient.WEBTESTCLIENT_REQUEST_ID, this.requestId); } diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/MockServerExchangeMutator.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/MockServerExchangeMutator.java index ce6b64e2c3..3ebebfc4af 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/MockServerExchangeMutator.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/MockServerExchangeMutator.java @@ -23,6 +23,7 @@ import java.util.function.UnaryOperator; import reactor.core.publisher.Mono; +import org.springframework.http.HttpHeaders; import org.springframework.util.Assert; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilter; @@ -82,9 +83,15 @@ public class MockServerExchangeMutator implements WebFilter { } private Function getMutatorsFor(ServerWebExchange exchange) { - String id = WiretapConnector.getRequestIdHeader(exchange.getRequest().getHeaders()); - Function m = this.perRequestMutators.remove(id); - return (m != null ? this.mutator.andThen(m) : this.mutator); + String id = getRequestId(exchange.getRequest().getHeaders()); + Function clientMutator = this.perRequestMutators.remove(id); + return (clientMutator != null ? this.mutator.andThen(clientMutator) : this.mutator); + } + + private String getRequestId(HttpHeaders headers) { + String id = headers.getFirst(WebTestClient.WEBTESTCLIENT_REQUEST_ID); + Assert.notNull(id, "No \"" + WebTestClient.WEBTESTCLIENT_REQUEST_ID + "\" header"); + return id; } @@ -103,8 +110,7 @@ public class MockServerExchangeMutator implements WebFilter { UnaryOperator mutator, UnaryOperator... mutators) { return client.filter((request, next) -> { - String id = request.headers().getFirst(WiretapConnector.REQUEST_ID_HEADER_NAME); - Assert.notNull(id, "No request-id header"); + String id = getRequestId(request.headers()); registerPerRequestMutator(id, mutator); for (UnaryOperator current : mutators) { registerPerRequestMutator(id, current); diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java index aa3df2dfb3..cb4f223a2e 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java @@ -75,6 +75,16 @@ import org.springframework.web.util.UriBuilderFactory; */ public interface WebTestClient { + /** + * The name of a request header used to assign a unique id to every request + * performed through the {@code WebTestClient}. This can be useful for + * storing contextual information at all phases of request processing (e.g. + * from a server-side component) under that id and later to look up + * that information once an {@link ExchangeResult} is available. + */ + String WEBTESTCLIENT_REQUEST_ID = "WebTestClient-Request-Id"; + + /** * Prepare an HTTP GET request. * @return a spec for specifying the target URL diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapConnector.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapConnector.java index 6ce1a1cefa..a99154639a 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapConnector.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapConnector.java @@ -24,7 +24,6 @@ import java.util.function.Function; import reactor.core.publisher.Mono; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.client.reactive.ClientHttpConnector; import org.springframework.http.client.reactive.ClientHttpRequest; @@ -42,15 +41,12 @@ import org.springframework.util.Assert; */ class WiretapConnector implements ClientHttpConnector { - public static final String REQUEST_ID_HEADER_NAME = "webtestclient-request-id"; - - private final ClientHttpConnector delegate; private final Map exchanges = new ConcurrentHashMap<>(); - public WiretapConnector(ClientHttpConnector delegate) { + WiretapConnector(ClientHttpConnector delegate) { this.delegate = delegate; } @@ -69,7 +65,8 @@ class WiretapConnector implements ClientHttpConnector { }) .map(response -> { WiretapClientHttpRequest wrappedRequest = requestRef.get(); - String requestId = getRequestIdHeader(wrappedRequest.getHeaders()); + String requestId = wrappedRequest.getHeaders().getFirst(WebTestClient.WEBTESTCLIENT_REQUEST_ID); + Assert.notNull(requestId, "No \"" + WebTestClient.WEBTESTCLIENT_REQUEST_ID + "\" header"); WiretapClientHttpResponse wrappedResponse = new WiretapClientHttpResponse(response); ExchangeResult result = new ExchangeResult(wrappedRequest, wrappedResponse); this.exchanges.put(requestId, result); @@ -77,18 +74,12 @@ class WiretapConnector implements ClientHttpConnector { }); } - public static String getRequestIdHeader(HttpHeaders headers) { - String requestId = headers.getFirst(REQUEST_ID_HEADER_NAME); - Assert.notNull(requestId, "No \"" + REQUEST_ID_HEADER_NAME + "\" header"); - return requestId; - } - /** * Retrieve the {@code ExchangeResult} for the given "request-id" header value. */ public ExchangeResult claimRequest(String requestId) { ExchangeResult result = this.exchanges.get(requestId); - Assert.notNull(result, "No match for request with header " + REQUEST_ID_HEADER_NAME + "=" + requestId); + Assert.notNull(result, "No match for " + WebTestClient.WEBTESTCLIENT_REQUEST_ID + "=" + requestId); return result; } diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/WebTestClientConnectorTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/WebTestClientConnectorTests.java index 81ef71ec3b..efac941808 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/WebTestClientConnectorTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/WebTestClientConnectorTests.java @@ -50,7 +50,7 @@ public class WebTestClientConnectorTests { ClientHttpConnector connector = (method, uri, fn) -> fn.apply(request).then(Mono.just(response)); ClientRequest clientRequest = ClientRequest.method(HttpMethod.GET, URI.create("/test")) - .header(WiretapConnector.REQUEST_ID_HEADER_NAME, "1").build(); + .header(WebTestClient.WEBTESTCLIENT_REQUEST_ID, "1").build(); WiretapConnector wiretapConnector = new WiretapConnector(connector); ExchangeFunction function = ExchangeFunctions.create(wiretapConnector);