use of org.springframework.web.reactive.function.client.ClientRequest in project spring-boot by spring-projects.
the class MetricsWebClientFilterFunctionTests method filterWhenCancelThrownShouldRecordTimer.
@Test
void filterWhenCancelThrownShouldRecordTimer() {
ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("https://example.com/projects/spring-boot")).build();
given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value());
Mono<ClientResponse> filter = this.filterFunction.filter(request, this.exchange);
StepVerifier.create(filter).thenCancel().verify(Duration.ofSeconds(5));
assertThat(this.registry.get("http.client.requests").tags("method", "GET", "uri", "/projects/spring-boot", "status", "CLIENT_ERROR").timer().count()).isEqualTo(1);
assertThatThrownBy(() -> this.registry.get("http.client.requests").tags("method", "GET", "uri", "/projects/spring-boot", "status", "200").timer()).isInstanceOf(MeterNotFoundException.class);
}
use of org.springframework.web.reactive.function.client.ClientRequest 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.ClientRequest in project spring-boot by spring-projects.
the class DefaultWebClientExchangeTagsProviderTests method tagsWhenNoUriTemplateShouldProvideUriPath.
@Test
void tagsWhenNoUriTemplateShouldProvideUriPath() {
ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("https://example.org/projects/spring-boot")).build();
Iterable<Tag> tags = this.tagsProvider.tags(request, this.response, null);
assertThat(tags).containsExactlyInAnyOrder(Tag.of("method", "GET"), Tag.of("uri", "/projects/spring-boot"), Tag.of("clientName", "example.org"), Tag.of("status", "200"), Tag.of("outcome", "SUCCESS"));
}
use of org.springframework.web.reactive.function.client.ClientRequest 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);
}
use of org.springframework.web.reactive.function.client.ClientRequest in project spring-boot by spring-projects.
the class MetricsWebClientFilterFunctionTests method filterWhenUriTemplatePresentShouldRecordTimer.
@Test
void filterWhenUriTemplatePresentShouldRecordTimer() {
ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("https://example.com/projects/spring-boot")).attribute(URI_TEMPLATE_ATTRIBUTE, "/projects/{project}").build();
given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value());
this.filterFunction.filter(request, this.exchange).block(Duration.ofSeconds(5));
assertThat(this.registry.get("http.client.requests").tags("method", "GET", "uri", "/projects/{project}", "status", "200").timer().count()).isEqualTo(1);
}
Aggregations