use of org.springframework.web.reactive.function.client.ExchangeFunction in project spring-cloud-sleuth by spring-cloud.
the class TraceExchangeFilterFunction method filter.
@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);
}
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("Created a client span for the WebClient " + 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;
}
use of org.springframework.web.reactive.function.client.ExchangeFunction in project spring-boot by spring-projects.
the class MetricsWebClientFilterFunctionTests method filterWhenExceptionAndRetryShouldNotAccumulateRecordTime.
@Test
void filterWhenExceptionAndRetryShouldNotAccumulateRecordTime() {
ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("https://example.com/projects/spring-boot")).build();
ExchangeFunction exchange = (r) -> Mono.error(new IllegalArgumentException()).delaySubscription(Duration.ofMillis(1000)).cast(ClientResponse.class);
this.filterFunction.filter(request, exchange).retry(1).onErrorResume(IllegalArgumentException.class, (t) -> Mono.empty()).block(Duration.ofSeconds(5));
Timer timer = this.registry.get("http.client.requests").tags("method", "GET", "uri", "/projects/spring-boot", "status", "CLIENT_ERROR").timer();
assertThat(timer.count()).isEqualTo(2);
assertThat(timer.max(TimeUnit.MILLISECONDS)).isLessThan(2000);
}
Aggregations