Browse Source

Polish

pull/1418/head
Rossen Stoyanchev 9 years ago
parent
commit
4db1eb1e4e
  1. 8
      spring-test/src/main/java/org/springframework/test/web/reactive/server/AbstractMockServerSpec.java
  2. 12
      spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java
  3. 10
      spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClientBuilder.java
  4. 34
      spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeMutatingWebFilter.java
  5. 9
      spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java

8
spring-test/src/main/java/org/springframework/test/web/reactive/server/AbstractMockServerSpec.java

@ -35,19 +35,19 @@ import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
abstract class AbstractMockServerSpec<B extends WebTestClient.MockServerSpec<B>> abstract class AbstractMockServerSpec<B extends WebTestClient.MockServerSpec<B>>
implements WebTestClient.MockServerSpec<B> { implements WebTestClient.MockServerSpec<B> {
private final ExchangeMutatorWebFilter exchangeMutatorFilter = new ExchangeMutatorWebFilter(); private final ExchangeMutatingWebFilter exchangeMutatingWebFilter = new ExchangeMutatingWebFilter();
private final List<WebFilter> filters = new ArrayList<>(4); private final List<WebFilter> filters = new ArrayList<>(4);
AbstractMockServerSpec() { AbstractMockServerSpec() {
this.filters.add(this.exchangeMutatorFilter); this.filters.add(this.exchangeMutatingWebFilter);
} }
@Override @Override
public <T extends B> T exchangeMutator(UnaryOperator<ServerWebExchange> mutator) { public <T extends B> T exchangeMutator(UnaryOperator<ServerWebExchange> mutator) {
this.exchangeMutatorFilter.register(mutator); this.exchangeMutatingWebFilter.registerGlobalMutator(mutator);
return self(); return self();
} }
@ -67,7 +67,7 @@ abstract class AbstractMockServerSpec<B extends WebTestClient.MockServerSpec<B>>
public WebTestClient.Builder configureClient() { public WebTestClient.Builder configureClient() {
WebHttpHandlerBuilder builder = initHttpHandlerBuilder(); WebHttpHandlerBuilder builder = initHttpHandlerBuilder();
filtersInReverse().forEach(builder::prependFilter); filtersInReverse().forEach(builder::prependFilter);
return new DefaultWebTestClientBuilder(builder.build(), this.exchangeMutatorFilter); return new DefaultWebTestClientBuilder(builder.build(), this.exchangeMutatingWebFilter);
} }
/** /**

12
spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java

@ -69,7 +69,7 @@ class DefaultWebTestClient implements WebTestClient {
private final WiretapConnector wiretapConnector; private final WiretapConnector wiretapConnector;
private final ExchangeMutatorWebFilter exchangeMutatorWebFilter; private final ExchangeMutatingWebFilter exchangeMutatingWebFilter;
private final Duration timeout; private final Duration timeout;
@ -77,20 +77,20 @@ class DefaultWebTestClient implements WebTestClient {
DefaultWebTestClient(WebClient.Builder webClientBuilder, ClientHttpConnector connector, DefaultWebTestClient(WebClient.Builder webClientBuilder, ClientHttpConnector connector,
ExchangeMutatorWebFilter webFilter, Duration timeout) { ExchangeMutatingWebFilter exchangeMutatingWebFilter, Duration timeout) {
Assert.notNull(webClientBuilder, "WebClient.Builder is required"); Assert.notNull(webClientBuilder, "WebClient.Builder is required");
this.wiretapConnector = new WiretapConnector(connector); this.wiretapConnector = new WiretapConnector(connector);
this.webClient = webClientBuilder.clientConnector(this.wiretapConnector).build(); this.webClient = webClientBuilder.clientConnector(this.wiretapConnector).build();
this.exchangeMutatorWebFilter = webFilter; this.exchangeMutatingWebFilter = exchangeMutatingWebFilter;
this.timeout = (timeout != null ? timeout : Duration.ofSeconds(5)); this.timeout = (timeout != null ? timeout : Duration.ofSeconds(5));
} }
private DefaultWebTestClient(DefaultWebTestClient webTestClient, ExchangeFilterFunction filter) { private DefaultWebTestClient(DefaultWebTestClient webTestClient, ExchangeFilterFunction filter) {
this.webClient = webTestClient.webClient.filter(filter); this.webClient = webTestClient.webClient.filter(filter);
this.wiretapConnector = webTestClient.wiretapConnector; this.wiretapConnector = webTestClient.wiretapConnector;
this.exchangeMutatorWebFilter = webTestClient.exchangeMutatorWebFilter; this.exchangeMutatingWebFilter = webTestClient.exchangeMutatingWebFilter;
this.timeout = webTestClient.timeout; this.timeout = webTestClient.timeout;
} }
@ -150,13 +150,13 @@ class DefaultWebTestClient implements WebTestClient {
@Override @Override
public WebTestClient exchangeMutator(UnaryOperator<ServerWebExchange> mutator) { public WebTestClient exchangeMutator(UnaryOperator<ServerWebExchange> mutator) {
Assert.notNull(this.exchangeMutatorWebFilter, Assert.notNull(this.exchangeMutatingWebFilter,
"This option is applicable only for tests without an actual running server"); "This option is applicable only for tests without an actual running server");
return filter((request, next) -> { return filter((request, next) -> {
String requestId = request.headers().getFirst(WiretapConnector.REQUEST_ID_HEADER_NAME); String requestId = request.headers().getFirst(WiretapConnector.REQUEST_ID_HEADER_NAME);
Assert.notNull(requestId, "No request-id header"); Assert.notNull(requestId, "No request-id header");
this.exchangeMutatorWebFilter.register(requestId, mutator); this.exchangeMutatingWebFilter.registerPerRequestMutator(requestId, mutator);
return next.exchange(request); return next.exchange(request);
}); });
} }

10
spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClientBuilder.java

@ -37,7 +37,7 @@ class DefaultWebTestClientBuilder implements WebTestClient.Builder {
private final ClientHttpConnector connector; private final ClientHttpConnector connector;
private final ExchangeMutatorWebFilter exchangeMutatorFilter; private final ExchangeMutatingWebFilter exchangeMutatingWebFilter;
private Duration responseTimeout; private Duration responseTimeout;
@ -48,12 +48,12 @@ class DefaultWebTestClientBuilder implements WebTestClient.Builder {
DefaultWebTestClientBuilder(ClientHttpConnector connector) { DefaultWebTestClientBuilder(ClientHttpConnector connector) {
this.connector = connector; this.connector = connector;
this.exchangeMutatorFilter = null; this.exchangeMutatingWebFilter = null;
} }
DefaultWebTestClientBuilder(HttpHandler httpHandler, ExchangeMutatorWebFilter exchangeMutatorFilter) { DefaultWebTestClientBuilder(HttpHandler httpHandler, ExchangeMutatingWebFilter exchangeMutatingWebFilter) {
this.connector = new HttpHandlerConnector(httpHandler); this.connector = new HttpHandlerConnector(httpHandler);
this.exchangeMutatorFilter = exchangeMutatorFilter; this.exchangeMutatingWebFilter = exchangeMutatingWebFilter;
} }
@ -96,7 +96,7 @@ class DefaultWebTestClientBuilder implements WebTestClient.Builder {
@Override @Override
public WebTestClient build() { public WebTestClient build() {
return new DefaultWebTestClient(this.webClientBuilder, this.connector, return new DefaultWebTestClient(this.webClientBuilder, this.connector,
this.exchangeMutatorFilter, this.responseTimeout); this.exchangeMutatingWebFilter, this.responseTimeout);
} }
} }

34
spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeMutatorWebFilter.java → spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeMutatingWebFilter.java

@ -29,15 +29,18 @@ import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain; import org.springframework.web.server.WebFilterChain;
/** /**
* WebFilter that applies global and request-specific transformation on * WebFilter for applying global and per-request transformations to a
* {@link ServerWebExchange}. * {@link ServerWebExchange}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 5.0 * @since 5.0
*/ */
class ExchangeMutatorWebFilter implements WebFilter { class ExchangeMutatingWebFilter implements WebFilter {
private volatile Function<ServerWebExchange, ServerWebExchange> globalMutator; private static final Function<ServerWebExchange, ServerWebExchange> NO_OP_MUTATOR = e -> e;
private volatile Function<ServerWebExchange, ServerWebExchange> globalMutator = NO_OP_MUTATOR;
private final Map<String, Function<ServerWebExchange, ServerWebExchange>> perRequestMutators = private final Map<String, Function<ServerWebExchange, ServerWebExchange>> perRequestMutators =
new ConcurrentHashMap<>(4); new ConcurrentHashMap<>(4);
@ -47,9 +50,9 @@ class ExchangeMutatorWebFilter implements WebFilter {
* Register a global transformation function to apply to all requests. * Register a global transformation function to apply to all requests.
* @param mutator the transformation function * @param mutator the transformation function
*/ */
public void register(UnaryOperator<ServerWebExchange> mutator) { public void registerGlobalMutator(UnaryOperator<ServerWebExchange> mutator) {
Assert.notNull(mutator, "'mutator' is required"); Assert.notNull(mutator, "'mutator' is required");
this.globalMutator = this.globalMutator != null ? this.globalMutator.andThen(mutator) : mutator; this.globalMutator = this.globalMutator.andThen(mutator);
} }
/** /**
@ -57,7 +60,7 @@ class ExchangeMutatorWebFilter implements WebFilter {
* @param requestId the "request-id" header value identifying the request * @param requestId the "request-id" header value identifying the request
* @param mutator the transformation function * @param mutator the transformation function
*/ */
public void register(String requestId, UnaryOperator<ServerWebExchange> mutator) { public void registerPerRequestMutator(String requestId, UnaryOperator<ServerWebExchange> mutator) {
this.perRequestMutators.compute(requestId, this.perRequestMutators.compute(requestId,
(s, value) -> value != null ? value.andThen(mutator) : mutator); (s, value) -> value != null ? value.andThen(mutator) : mutator);
} }
@ -65,18 +68,15 @@ class ExchangeMutatorWebFilter implements WebFilter {
@Override @Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
exchange = this.globalMutator.apply(exchange);
if (this.globalMutator != null) { exchange = getMutatorFor(exchange).apply(exchange);
exchange = this.globalMutator.apply(exchange);
}
String requestId = WiretapConnector.getRequestId(exchange.getRequest().getHeaders());
Function<ServerWebExchange, ServerWebExchange> mutator = this.perRequestMutators.remove(requestId);
if (mutator != null) {
exchange = mutator.apply(exchange);
}
return chain.filter(exchange); return chain.filter(exchange);
} }
private Function<ServerWebExchange, ServerWebExchange> getMutatorFor(ServerWebExchange exchange) {
String id = WiretapConnector.getRequestId(exchange.getRequest().getHeaders());
Function<ServerWebExchange, ServerWebExchange> mutator = this.perRequestMutators.remove(id);
return mutator != null ? mutator : NO_OP_MUTATOR;
}
} }

9
spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java

@ -375,22 +375,23 @@ public interface WebClient {
* Exchange the request for a {@code ClientResponse} with full access * Exchange the request for a {@code ClientResponse} with full access
* to the response status and headers before extracting the body. * to the response status and headers before extracting the body.
* *
* <p>Use {@link Mono#then(Function)} or {@link Mono#flatMap(Function)} * <p>Use {@link Mono#flatMap(Function)} or
* to compose further on the response: * {@link Mono#flatMapMany(Function)} to compose further on the response:
* *
* <pre> * <pre>
* Mono&lt;Pojo&gt; mono = client.get().uri("/") * Mono&lt;Pojo&gt; mono = client.get().uri("/")
* .accept(MediaType.APPLICATION_JSON) * .accept(MediaType.APPLICATION_JSON)
* .exchange() * .exchange()
* .then(response -> response.bodyToMono(Pojo.class)); * .flatMap(response -> response.bodyToMono(Pojo.class));
* *
* Flux&lt;Pojo&gt; flux = client.get().uri("/") * Flux&lt;Pojo&gt; flux = client.get().uri("/")
* .accept(MediaType.APPLICATION_STREAM_JSON) * .accept(MediaType.APPLICATION_STREAM_JSON)
* .exchange() * .exchange()
* .then(response -> response.bodyToFlux(Pojo.class)); * .flatMapMany(response -> response.bodyToFlux(Pojo.class));
* </pre> * </pre>
* *
* @return a {@code Mono} with the response * @return a {@code Mono} with the response
* @see #retrieve()
*/ */
Mono<ClientResponse> exchange(); Mono<ClientResponse> exchange();

Loading…
Cancel
Save