Polish
This commit is contained in:
parent
2515134f8e
commit
262e5f783d
|
|
@ -300,10 +300,8 @@ class DefaultWebTestClient implements WebTestClient {
|
|||
}
|
||||
|
||||
public EntityExchangeResult<Void> consumeEmpty() {
|
||||
assertWithDiagnostics(() -> {
|
||||
DataBuffer buffer = this.response.body(toDataBuffers()).blockFirst(getTimeout());
|
||||
assertTrue("Expected empty body", buffer == null);
|
||||
});
|
||||
DataBuffer buffer = this.response.body(toDataBuffers()).blockFirst(getTimeout());
|
||||
assertWithDiagnostics(() -> assertTrue("Expected empty body", buffer == null));
|
||||
return new EntityExchangeResult<>(this, null);
|
||||
}
|
||||
}
|
||||
|
|
@ -344,10 +342,8 @@ class DefaultWebTestClient implements WebTestClient {
|
|||
|
||||
@Override
|
||||
public ResponseSpec consumeWith(Consumer<ExchangeResult> consumer) {
|
||||
return this.result.assertWithDiagnosticsAndReturn(() -> {
|
||||
consumer.accept(this.result);
|
||||
return this;
|
||||
});
|
||||
this.result.assertWithDiagnostics(() -> consumer.accept(this.result));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -402,10 +398,9 @@ class DefaultWebTestClient implements WebTestClient {
|
|||
|
||||
@Override
|
||||
public <T> EntityExchangeResult<T> isEqualTo(T expected) {
|
||||
return this.result.assertWithDiagnosticsAndReturn(() -> {
|
||||
assertEquals("Response body", expected, this.result.getResponseBody());
|
||||
return returnResult();
|
||||
});
|
||||
Object actual = this.result.getResponseBody();
|
||||
this.result.assertWithDiagnostics(() -> assertEquals("Response body", expected, actual));
|
||||
return returnResult();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
@ -427,10 +422,9 @@ class DefaultWebTestClient implements WebTestClient {
|
|||
|
||||
@Override
|
||||
public <T> EntityExchangeResult<List<T>> isEqualTo(List<T> expected) {
|
||||
return this.result.assertWithDiagnosticsAndReturn(() -> {
|
||||
assertEquals("Response body", expected, this.result.getResponseBody());
|
||||
return returnResult();
|
||||
});
|
||||
List<?> actual = this.result.getResponseBody();
|
||||
this.result.assertWithDiagnostics(() -> assertEquals("Response body", expected, actual));
|
||||
return returnResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -440,21 +434,19 @@ class DefaultWebTestClient implements WebTestClient {
|
|||
|
||||
@Override
|
||||
public ListBodySpec contains(Object... elements) {
|
||||
this.result.assertWithDiagnostics(() -> {
|
||||
List<Object> elementList = Arrays.asList(elements);
|
||||
String message = "Response body does not contain " + elementList;
|
||||
assertTrue(message, this.result.getResponseBody().containsAll(elementList));
|
||||
});
|
||||
List<?> expected = Arrays.asList(elements);
|
||||
List<?> actual = this.result.getResponseBody();
|
||||
String message = "Response body does not contain " + expected;
|
||||
this.result.assertWithDiagnostics(() -> assertTrue(message, actual.containsAll(expected)));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListBodySpec doesNotContain(Object... elements) {
|
||||
this.result.assertWithDiagnostics(() -> {
|
||||
List<Object> elementList = Arrays.asList(elements);
|
||||
String message = "Response body should have contained " + elementList;
|
||||
assertTrue(message, !this.result.getResponseBody().containsAll(Arrays.asList(elements)));
|
||||
});
|
||||
List<?> expected = Arrays.asList(elements);
|
||||
List<?> actual = this.result.getResponseBody();
|
||||
String message = "Response body should have contained " + expected;
|
||||
this.result.assertWithDiagnostics(() -> assertTrue(message, !actual.containsAll(expected)));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -507,43 +499,38 @@ class DefaultWebTestClient implements WebTestClient {
|
|||
|
||||
@Override
|
||||
public <K, V> EntityExchangeResult<Map<K, V>> isEqualTo(Map<K, V> expected) {
|
||||
return this.result.assertWithDiagnosticsAndReturn(() -> {
|
||||
assertEquals("Response body map", expected, getBody());
|
||||
return returnResult();
|
||||
});
|
||||
String message = "Response body map";
|
||||
this.result.assertWithDiagnostics(() -> assertEquals(message, expected, getBody()));
|
||||
return returnResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapBodySpec hasSize(int size) {
|
||||
return this.result.assertWithDiagnosticsAndReturn(() -> {
|
||||
assertEquals("Response body map size", size, getBody().size());
|
||||
return this;
|
||||
});
|
||||
String message = "Response body map size";
|
||||
this.result.assertWithDiagnostics(() -> assertEquals(message, size, getBody().size()));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapBodySpec contains(Object key, Object value) {
|
||||
return this.result.assertWithDiagnosticsAndReturn(() -> {
|
||||
assertEquals("Response body map value for key " + key, value, getBody().get(key));
|
||||
return this;
|
||||
});
|
||||
String message = "Response body map value for key " + key;
|
||||
this.result.assertWithDiagnostics(() -> assertEquals(message, value, getBody().get(key)));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapBodySpec containsKeys(Object... keys) {
|
||||
return this.result.assertWithDiagnosticsAndReturn(() -> {
|
||||
List<?> missing = Arrays.stream(keys).filter(k -> !getBody().containsKey(k)).collect(toList());
|
||||
assertTrue("Response body map does not contain keys " + missing, missing.isEmpty());
|
||||
return this;
|
||||
});
|
||||
List<?> missing = Arrays.stream(keys).filter(k -> !getBody().containsKey(k)).collect(toList());
|
||||
String message = "Response body map does not contain keys " + missing;
|
||||
this.result.assertWithDiagnostics(() -> assertTrue(message, missing.isEmpty()));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapBodySpec containsValues(Object... values) {
|
||||
this.result.assertWithDiagnostics(() -> {
|
||||
List<?> missing = Arrays.stream(values).filter(v -> !getBody().containsValue(v)).collect(toList());
|
||||
assertTrue("Response body map does not contain values " + missing, missing.isEmpty());
|
||||
});
|
||||
List<?> missing = Arrays.stream(values).filter(v -> !getBody().containsValue(v)).collect(toList());
|
||||
String message = "Response body map does not contain values " + missing;
|
||||
this.result.assertWithDiagnostics(() -> assertTrue(message, missing.isEmpty()));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import java.nio.charset.Charset;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import reactor.core.publisher.MonoProcessor;
|
||||
|
|
@ -33,16 +32,17 @@ import org.springframework.http.ResponseCookie;
|
|||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
/**
|
||||
* Simple container for request and response details from an exchange performed
|
||||
* Provides access to request and response details from an exchange performed
|
||||
* through the {@link WebTestClient}.
|
||||
*
|
||||
* <p>When an {@code ExchangeResult} is first created it has only the status and
|
||||
* headers of the response available. When the response body is extracted, the
|
||||
* {@code ExchangeResult} is re-created as either {@link EntityExchangeResult}
|
||||
* or {@link FluxExchangeResult} that further expose extracted entities.
|
||||
* <p>When an {@code ExchangeResult} is first created it has the status and the
|
||||
* headers of the response ready. Later when the response body is extracted,
|
||||
* the {@code ExchangeResult} is re-created as {@link EntityExchangeResult} or
|
||||
* {@link FluxExchangeResult} also exposing the extracted entities.
|
||||
*
|
||||
* <p>Raw request and response content may also be accessed once complete via
|
||||
* {@link #getRequestContent()} or {@link #getResponseContent()}.
|
||||
* <p>Serialized request and response content may also be accessed through the
|
||||
* methods {@link #getRequestContent()} and {@link #getResponseContent()} after
|
||||
* that content has been fully read or written.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
|
|
@ -137,8 +137,9 @@ public class ExchangeResult {
|
|||
|
||||
|
||||
/**
|
||||
* Execute the given Runnable in the context of "this" instance and decorate
|
||||
* any {@link AssertionError}s raised with request and response details.
|
||||
* Execute the given Runnable, catch any {@link AssertionError}, decorate
|
||||
* with {@code AssertionError} containing diagnostic information about the
|
||||
* request and response, and then re-throw.
|
||||
*/
|
||||
public void assertWithDiagnostics(Runnable assertion) {
|
||||
try {
|
||||
|
|
@ -149,32 +150,19 @@ public class ExchangeResult {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of {@link #assertWithDiagnostics(Runnable)} that passes through
|
||||
* a return value from the assertion code.
|
||||
*/
|
||||
public <T> T assertWithDiagnosticsAndReturn(Supplier<T> assertion) {
|
||||
try {
|
||||
return assertion.get();
|
||||
}
|
||||
catch (AssertionError ex) {
|
||||
throw new AssertionError("Assertion failed on the following exchange:" + this, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "\n" +
|
||||
"> " + getMethod() + " " + getUrl() + "\n" +
|
||||
"> " + formatHeaders("> ", getRequestHeaders()) + "\n" +
|
||||
"> " + formatHeaders(getRequestHeaders(), "\n> ") + "\n" +
|
||||
"\n" +
|
||||
formatContent(getRequestHeaders().getContentType(), getRequestContent()) + "\n" +
|
||||
formatBody(getRequestHeaders().getContentType(), getRequestContent()) + "\n" +
|
||||
"\n" +
|
||||
"< " + getStatus() + " " + getStatusReason() + "\n" +
|
||||
"< " + formatHeaders("< ", getResponseHeaders()) + "\n" +
|
||||
"< " + formatHeaders(getResponseHeaders(), "\n< ") + "\n" +
|
||||
"\n" +
|
||||
formatContent(getResponseHeaders().getContentType(), getResponseContent()) + "\n\n";
|
||||
formatBody(getResponseHeaders().getContentType(), getResponseContent()) + "\n\n";
|
||||
}
|
||||
|
||||
private String getStatusReason() {
|
||||
|
|
@ -185,13 +173,13 @@ public class ExchangeResult {
|
|||
return reason;
|
||||
}
|
||||
|
||||
private String formatHeaders(String linePrefix, HttpHeaders headers) {
|
||||
private String formatHeaders(HttpHeaders headers, String delimiter) {
|
||||
return headers.entrySet().stream()
|
||||
.map(entry -> entry.getKey() + ": " + entry.getValue())
|
||||
.collect(Collectors.joining("\n" + linePrefix));
|
||||
.collect(Collectors.joining(delimiter));
|
||||
}
|
||||
|
||||
private String formatContent(MediaType contentType, MonoProcessor<byte[]> body) {
|
||||
private String formatBody(MediaType contentType, MonoProcessor<byte[]> body) {
|
||||
if (body.isSuccess()) {
|
||||
byte[] bytes = body.blockMillis(0);
|
||||
if (bytes.length == 0) {
|
||||
|
|
|
|||
|
|
@ -60,13 +60,12 @@ public class HeaderAssertions {
|
|||
* @param pattern String pattern to pass to {@link Pattern#compile(String)}
|
||||
*/
|
||||
public WebTestClient.ResponseSpec valueMatches(String name, String pattern) {
|
||||
return this.exchangeResult.assertWithDiagnosticsAndReturn(() -> {
|
||||
String value = getHeaders().getFirst(name);
|
||||
assertTrue(getMessage(name) + " not found", value != null);
|
||||
boolean match = Pattern.compile(pattern).matcher(value).matches();
|
||||
assertTrue(getMessage(name) + "=\'" + value + "\' does not match \'" + pattern + "\'", match);
|
||||
return this.responseSpec;
|
||||
});
|
||||
String value = getHeaders().getFirst(name);
|
||||
assertTrue(getMessage(name) + " not found", value != null);
|
||||
boolean match = Pattern.compile(pattern).matcher(value).matches();
|
||||
String message = getMessage(name) + "=\'" + value + "\' does not match \'" + pattern + "\'";
|
||||
this.exchangeResult.assertWithDiagnostics(() -> assertTrue(message, match));
|
||||
return this.responseSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -123,10 +122,8 @@ public class HeaderAssertions {
|
|||
}
|
||||
|
||||
private WebTestClient.ResponseSpec assertHeader(String name, Object expected, Object actual) {
|
||||
return this.exchangeResult.assertWithDiagnosticsAndReturn(() -> {
|
||||
assertEquals(getMessage(name), expected, actual);
|
||||
return this.responseSpec;
|
||||
});
|
||||
this.exchangeResult.assertWithDiagnostics(() -> assertEquals(getMessage(name), expected, actual));
|
||||
return this.responseSpec;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,10 +51,9 @@ public class StatusAssertions {
|
|||
* Assert the response status as an integer.
|
||||
*/
|
||||
public WebTestClient.ResponseSpec isEqualTo(int status) {
|
||||
return this.exchangeResult.assertWithDiagnosticsAndReturn(() -> {
|
||||
assertEquals("Status", status, this.exchangeResult.getStatus().value());
|
||||
return this.responseSpec;
|
||||
});
|
||||
int actual = this.exchangeResult.getStatus().value();
|
||||
this.exchangeResult.assertWithDiagnostics(() -> assertEquals("Status", status, actual));
|
||||
return this.responseSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -146,11 +145,10 @@ public class StatusAssertions {
|
|||
* Assert the response error message.
|
||||
*/
|
||||
public WebTestClient.ResponseSpec reasonEquals(String reason) {
|
||||
return this.exchangeResult.assertWithDiagnosticsAndReturn(() -> {
|
||||
HttpStatus status = this.exchangeResult.getStatus();
|
||||
assertEquals("Response status reason", reason, status.getReasonPhrase());
|
||||
return this.responseSpec;
|
||||
});
|
||||
String actual = this.exchangeResult.getStatus().getReasonPhrase();
|
||||
String message = "Response status reason";
|
||||
this.exchangeResult.assertWithDiagnostics(() -> assertEquals(message, reason, actual));
|
||||
return this.responseSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -192,19 +190,16 @@ public class StatusAssertions {
|
|||
// Private methods
|
||||
|
||||
private WebTestClient.ResponseSpec assertStatusAndReturn(HttpStatus expected) {
|
||||
return this.exchangeResult.assertWithDiagnosticsAndReturn(() -> {
|
||||
assertEquals("Status", expected, this.exchangeResult.getStatus());
|
||||
return this.responseSpec;
|
||||
});
|
||||
HttpStatus actual = this.exchangeResult.getStatus();
|
||||
this.exchangeResult.assertWithDiagnostics(() -> assertEquals("Status", expected, actual));
|
||||
return this.responseSpec;
|
||||
}
|
||||
|
||||
private WebTestClient.ResponseSpec assertSeriesAndReturn(HttpStatus.Series expected) {
|
||||
return this.exchangeResult.assertWithDiagnosticsAndReturn(() -> {
|
||||
HttpStatus status = this.exchangeResult.getStatus();
|
||||
String message = "Range for response status value " + status;
|
||||
assertEquals(message, expected, status.series());
|
||||
return this.responseSpec;
|
||||
});
|
||||
HttpStatus status = this.exchangeResult.getStatus();
|
||||
String message = "Range for response status value " + status;
|
||||
this.exchangeResult.assertWithDiagnostics(() -> assertEquals(message, expected, status.series()));
|
||||
return this.responseSpec;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -512,9 +512,10 @@ public interface WebTestClient {
|
|||
ListBodySpec list(int elementCount);
|
||||
|
||||
/**
|
||||
* Return request and response details from the exchange including the
|
||||
* response body as a {@code Flux<T>} and available for example for use
|
||||
* with a {@code StepVerifier} from Project Reactor.
|
||||
* Return request and response details for the exchange incluidng the
|
||||
* response body decoded as {@code Flux<T>} where {@code <T>} is the
|
||||
* expected element type. The returned {@code Flux} may for example be
|
||||
* verified with the Reactor {@code StepVerifier}.
|
||||
*/
|
||||
<T> FluxExchangeResult<T> returnResult();
|
||||
}
|
||||
|
|
@ -530,7 +531,7 @@ public interface WebTestClient {
|
|||
<T> EntityExchangeResult<T> isEqualTo(T expected);
|
||||
|
||||
/**
|
||||
* Return request and response details from the exchange including the
|
||||
* Return request and response details for the exchange including the
|
||||
* extracted response body.
|
||||
*/
|
||||
<T> EntityExchangeResult<T> returnResult();
|
||||
|
|
@ -565,7 +566,7 @@ public interface WebTestClient {
|
|||
ListBodySpec doesNotContain(Object... elements);
|
||||
|
||||
/**
|
||||
* Return request and response details from the exchange including the
|
||||
* Return request and response details for the exchange including the
|
||||
* extracted response body.
|
||||
*/
|
||||
<T> EntityExchangeResult<List<T>> returnResult();
|
||||
|
|
@ -630,7 +631,7 @@ public interface WebTestClient {
|
|||
MapBodySpec containsValues(Object... values);
|
||||
|
||||
/**
|
||||
* Return request and response details from the exchange including the
|
||||
* Return request and response details for the exchange including the
|
||||
* extracted response body.
|
||||
*/
|
||||
<K, V> EntityExchangeResult<Map<K, V>> returnResult();
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ import org.springframework.http.client.reactive.ClientHttpRequest;
|
|||
import org.springframework.http.client.reactive.ClientHttpRequestDecorator;
|
||||
|
||||
/**
|
||||
* Client HTTP request decorator that saves the content written to the server.
|
||||
* Client HTTP request decorator that intercepts and saves content written to
|
||||
* the server.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
|
|
@ -49,7 +50,7 @@ class WiretapClientHttpRequest extends ClientHttpRequestDecorator {
|
|||
|
||||
|
||||
/**
|
||||
* Return a "promise" for the request body content.
|
||||
* Return a "promise" with the request body content written to the server.
|
||||
*/
|
||||
public MonoProcessor<byte[]> getBodyContent() {
|
||||
return this.body;
|
||||
|
|
@ -60,39 +61,39 @@ class WiretapClientHttpRequest extends ClientHttpRequestDecorator {
|
|||
public Mono<Void> writeWith(Publisher<? extends DataBuffer> publisher) {
|
||||
return super.writeWith(
|
||||
Flux.from(publisher)
|
||||
.doOnNext(this::handleBuffer)
|
||||
.doOnError(this::handleErrorSignal)
|
||||
.doOnCancel(this::handleCompleteSignal)
|
||||
.doOnComplete(this::handleCompleteSignal));
|
||||
.doOnNext(this::handleOnNext)
|
||||
.doOnError(this::handleError)
|
||||
.doOnCancel(this::handleOnComplete)
|
||||
.doOnComplete(this::handleOnComplete));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> publisher) {
|
||||
return super.writeAndFlushWith(
|
||||
Flux.from(publisher)
|
||||
.map(p -> Flux.from(p).doOnNext(this::handleBuffer).doOnError(this::handleErrorSignal))
|
||||
.doOnError(this::handleErrorSignal)
|
||||
.doOnCancel(this::handleCompleteSignal)
|
||||
.doOnComplete(this::handleCompleteSignal));
|
||||
.map(p -> Flux.from(p).doOnNext(this::handleOnNext).doOnError(this::handleError))
|
||||
.doOnError(this::handleError)
|
||||
.doOnCancel(this::handleOnComplete)
|
||||
.doOnComplete(this::handleOnComplete));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> setComplete() {
|
||||
handleCompleteSignal();
|
||||
handleOnComplete();
|
||||
return super.setComplete();
|
||||
}
|
||||
|
||||
private void handleBuffer(DataBuffer buffer) {
|
||||
private void handleOnNext(DataBuffer buffer) {
|
||||
this.buffer.write(buffer);
|
||||
}
|
||||
|
||||
private void handleErrorSignal(Throwable ex) {
|
||||
private void handleError(Throwable ex) {
|
||||
if (!this.body.isTerminated()) {
|
||||
this.body.onError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleCompleteSignal() {
|
||||
private void handleOnComplete() {
|
||||
if (!this.body.isTerminated()) {
|
||||
byte[] bytes = new byte[this.buffer.readableByteCount()];
|
||||
this.buffer.read(bytes);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ import org.springframework.http.client.reactive.ClientHttpResponse;
|
|||
import org.springframework.http.client.reactive.ClientHttpResponseDecorator;
|
||||
|
||||
/**
|
||||
* Client HTTP response decorator that saves the content read from the server.
|
||||
* Client HTTP response decorator that interceptrs and saves the content read
|
||||
* from the server.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
|
|
@ -47,7 +48,7 @@ class WiretapClientHttpResponse extends ClientHttpResponseDecorator {
|
|||
|
||||
|
||||
/**
|
||||
* Return a "promise" for the response body content.
|
||||
* Return a "promise" with the response body content read from the server.
|
||||
*/
|
||||
public MonoProcessor<byte[]> getBodyContent() {
|
||||
return this.body;
|
||||
|
|
@ -58,11 +59,11 @@ class WiretapClientHttpResponse extends ClientHttpResponseDecorator {
|
|||
return super.getBody()
|
||||
.doOnNext(buffer::write)
|
||||
.doOnError(body::onError)
|
||||
.doOnCancel(this::handleCompleteSignal)
|
||||
.doOnComplete(this::handleCompleteSignal);
|
||||
.doOnCancel(this::handleOnComplete)
|
||||
.doOnComplete(this::handleOnComplete);
|
||||
}
|
||||
|
||||
private void handleCompleteSignal() {
|
||||
private void handleOnComplete() {
|
||||
if (!this.body.isTerminated()) {
|
||||
byte[] bytes = new byte[this.buffer.readableByteCount()];
|
||||
this.buffer.read(bytes);
|
||||
|
|
|
|||
|
|
@ -30,12 +30,13 @@ import org.springframework.http.client.reactive.ClientHttpResponse;
|
|||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Decorate any other {@link ClientHttpConnector} with the purpose of
|
||||
* intercepting, capturing, and exposing actual request and response content
|
||||
* Decorate another {@link ClientHttpConnector} with the purpose of
|
||||
* intercepting, capturing, and exposing actual request and response data
|
||||
* transmitted to and received from the server.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
*
|
||||
* @see HttpHandlerConnector
|
||||
*/
|
||||
class WiretapConnector implements ClientHttpConnector {
|
||||
|
|
@ -45,7 +46,7 @@ class WiretapConnector implements ClientHttpConnector {
|
|||
|
||||
private final ClientHttpConnector delegate;
|
||||
|
||||
private final Map<String, ExchangeResult> capturedExchanges = new ConcurrentHashMap<>();
|
||||
private final Map<String, ExchangeResult> exchanges = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
public WiretapConnector(ClientHttpConnector delegate) {
|
||||
|
|
@ -66,21 +67,21 @@ class WiretapConnector implements ClientHttpConnector {
|
|||
return requestCallback.apply(wrapped);
|
||||
})
|
||||
.map(response -> {
|
||||
WiretapClientHttpRequest request = requestRef.get();
|
||||
String requestId = request.getHeaders().getFirst(REQUEST_ID_HEADER_NAME);
|
||||
WiretapClientHttpRequest wrappedRequest = requestRef.get();
|
||||
String requestId = wrappedRequest.getHeaders().getFirst(REQUEST_ID_HEADER_NAME);
|
||||
Assert.notNull(requestId, "No request-id header");
|
||||
WiretapClientHttpResponse wrapped = new WiretapClientHttpResponse(response);
|
||||
ExchangeResult result = new ExchangeResult(request, wrapped);
|
||||
this.capturedExchanges.put(requestId, result);
|
||||
return wrapped;
|
||||
WiretapClientHttpResponse wrappedResponse = new WiretapClientHttpResponse(response);
|
||||
ExchangeResult result = new ExchangeResult(wrappedRequest, wrappedResponse);
|
||||
this.exchanges.put(requestId, result);
|
||||
return wrappedResponse;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the request with the given "request-id" header.
|
||||
* Retrieve the {@code ExchangeResult} for the given "request-id" header value.
|
||||
*/
|
||||
public ExchangeResult claimRequest(String requestId) {
|
||||
ExchangeResult result = this.capturedExchanges.get(requestId);
|
||||
ExchangeResult result = this.exchanges.get(requestId);
|
||||
Assert.notNull(result, "No match for request with id [" + requestId + "]");
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue