Example usage for org.springframework.web.reactive.function.client ExchangeFunction exchange

List of usage examples for org.springframework.web.reactive.function.client ExchangeFunction exchange

Introduction

In this page you can find the example usage for org.springframework.web.reactive.function.client ExchangeFunction exchange.

Prototype

Mono<ClientResponse> exchange(ClientRequest request);

Source Link

Document

Exchange the given request for a response mono.

Usage

From source file:org.springframework.cloud.sleuth.instrument.web.client.TraceWebClientBeanPostProcessor.java

@Override
public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next) {
    final ClientRequest.Builder builder = ClientRequest.from(request);
    Mono<ClientResponse> exchange = Mono.defer(() -> next.exchange(builder.build())).cast(Object.class)
            .onErrorResume(Mono::just).zipWith(Mono.subscriberContext()).flatMap(anyAndContext -> {
                Object any = anyAndContext.getT1();
                Span clientSpan = anyAndContext.getT2().get(CLIENT_SPAN_KEY);
                Mono<ClientResponse> continuation;
                final Tracer.SpanInScope ws = tracer().withSpanInScope(clientSpan);
                if (any instanceof Throwable) {
                    continuation = Mono.error((Throwable) any);
                } else {
                    continuation = Mono.just((ClientResponse) any);
                }/*from  www .j  a  va2s.  co m*/
                return continuation.doAfterSuccessOrError((clientResponse, throwable1) -> {
                    Throwable throwable = throwable1;
                    if (clientResponse == null || clientResponse.statusCode() == null) {
                        if (log.isDebugEnabled()) {
                            log.debug("No response was returned. Will close the span [" + clientSpan + "]");
                        }
                        handleReceive(clientSpan, ws, clientResponse, throwable);
                        return;
                    }
                    boolean error = clientResponse.statusCode().is4xxClientError()
                            || clientResponse.statusCode().is5xxServerError();
                    if (error) {
                        if (log.isDebugEnabled()) {
                            log.debug(
                                    "Non positive status code was returned from the call. Will close the span ["
                                            + clientSpan + "]");
                        }
                        throwable = new RestClientException("Status code of the response is ["
                                + clientResponse.statusCode().value() + "] and the reason is ["
                                + clientResponse.statusCode().getReasonPhrase() + "]");
                    }
                    handleReceive(clientSpan, ws, clientResponse, throwable);
                });
            }).subscriberContext(c -> {
                if (log.isDebugEnabled()) {
                    log.debug("Instrumenting WebClient call");
                }
                Span parent = c.getOrDefault(Span.class, null);
                Span clientSpan = handler().handleSend(injector(), builder, request, tracer().nextSpan());
                if (log.isDebugEnabled()) {
                    log.debug("Handled send of " + clientSpan);
                }
                if (parent == null) {
                    c = c.put(Span.class, clientSpan);
                    if (log.isDebugEnabled()) {
                        log.debug("Reactor Context got injected with the client span " + clientSpan);
                    }
                }
                return c.put(CLIENT_SPAN_KEY, clientSpan);
            });
    return exchange;
}