org.springframework.web.reactive.function.client.ClientRequest Java Examples

The following examples show how to use org.springframework.web.reactive.function.client.ClientRequest. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: InstanceExchangeFilterFunctions.java    From Moss with Apache License 2.0 7 votes vote down vote up
public static ExchangeFilterFunction convertLegacyEndpoint(LegacyEndpointConverter converter) {
    return (ClientRequest request, ExchangeFunction next) -> {
        Mono<ClientResponse> clientResponse = next.exchange(request);
        if (request.attribute(ATTRIBUTE_ENDPOINT).map(converter::canConvert).orElse(false)) {
            return clientResponse.flatMap(response -> {
                if (response.headers()
                            .contentType()
                            .map(t -> ACTUATOR_V1_MEDIATYPE.isCompatibleWith(t) ||
                                      APPLICATION_JSON.isCompatibleWith(t))
                            .orElse(false)) {
                    return convertClientResponse(converter::convert, ACTUATOR_V2_MEDIATYPE).apply(response);
                }
                return Mono.just(response);
            });
        }
        return clientResponse;
    };
}
 
Example #2
Source File: TracingClientResponseMono.java    From java-spring-web with Apache License 2.0 6 votes vote down vote up
@Override
public void subscribe(final CoreSubscriber<? super ClientResponse> subscriber) {
    final Context context = subscriber.currentContext();
    final Span parentSpan = context.<Span>getOrEmpty(Span.class).orElseGet(tracer::activeSpan);

    final Span span = tracer.buildSpan(request.method().toString())
            .asChildOf(parentSpan)
            .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)
            .start();

    try (final Scope scope = tracer.scopeManager().activate(span)) {
        final ClientRequest.Builder requestBuilder = ClientRequest.from(request);
        requestBuilder.headers(httpHeaders ->
                tracer.inject(span.context(), Format.Builtin.HTTP_HEADERS, new HttpHeadersCarrier(httpHeaders)));
        final ClientRequest mutatedRequest = requestBuilder.build();

        next.exchange(mutatedRequest).subscribe(
                new TracingClientResponseSubscriber(subscriber, mutatedRequest, context, span, spanDecorators)
        );
    }
}
 
Example #3
Source File: InstanceExchangeFilterFunctionsTest.java    From Moss with Apache License 2.0 6 votes vote down vote up
@Test
public void should_retry_using_endpoint_value_default() {
    ExchangeFilterFunction filter = InstanceExchangeFilterFunctions.retry(0, singletonMap("test", 1));

    ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("/test"))
                                         .attribute(ATTRIBUTE_ENDPOINT, "test")
                                         .build();
    ClientResponse response = mock(ClientResponse.class);

    AtomicLong invocationCount = new AtomicLong(0L);
    ExchangeFunction exchange = r -> Mono.fromSupplier(() -> {
        if (invocationCount.getAndIncrement() == 0) {
            throw new IllegalStateException("Test");
        }
        return response;
    });

    StepVerifier.create(filter.filter(request, exchange)).expectNext(response).verifyComplete();
    assertThat(invocationCount.get()).isEqualTo(2);
}
 
Example #4
Source File: InstanceExchangeFilterFunctionsTest.java    From Moss with Apache License 2.0 6 votes vote down vote up
@Test
public void should_not_convert_v2_actuator() {
    ExchangeFilterFunction filter = InstanceExchangeFilterFunctions.convertLegacyEndpoint(new TestLegacyEndpointConverter());

    ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("/test"))
                                         .attribute(ATTRIBUTE_ENDPOINT, "test")
                                         .build();
    ClientResponse response = ClientResponse.create(HttpStatus.OK)
                                            .header(CONTENT_TYPE, ActuatorMediaType.V2_JSON)
                                            .body(Flux.just(ORIGINAL))
                                            .build();

    Mono<ClientResponse> convertedResponse = filter.filter(request, r -> Mono.just(response));

    StepVerifier.create(convertedResponse)
                .assertNext(r -> StepVerifier.create(r.body(BodyExtractors.toDataBuffers()))
                                             .expectNext(ORIGINAL)
                                             .verifyComplete())
                .verifyComplete();
}
 
Example #5
Source File: InstanceExchangeFilterFunctionsTest.java    From Moss with Apache License 2.0 6 votes vote down vote up
@Test
public void should_convert_json() {
    ExchangeFilterFunction filter = InstanceExchangeFilterFunctions.convertLegacyEndpoint(new TestLegacyEndpointConverter());

    ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("/test"))
                                         .attribute(ATTRIBUTE_ENDPOINT, "test")
                                         .build();
    ClientResponse response = ClientResponse.create(HttpStatus.OK)
                                            .header(CONTENT_TYPE, APPLICATION_JSON_VALUE)
                                            .body(Flux.just(ORIGINAL))
                                            .build();

    Mono<ClientResponse> convertedResponse = filter.filter(request, r -> Mono.just(response));

    StepVerifier.create(convertedResponse)
                .assertNext(r -> StepVerifier.create(r.body(BodyExtractors.toDataBuffers()))
                                             .expectNext(CONVERTED)
                                             .verifyComplete())
                .verifyComplete();
}
 
Example #6
Source File: InstanceExchangeFilterFunctionsTest.java    From Moss with Apache License 2.0 6 votes vote down vote up
@Test
public void should_convert_v1_actuator() {
    ExchangeFilterFunction filter = InstanceExchangeFilterFunctions.convertLegacyEndpoint(new TestLegacyEndpointConverter());

    ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("/test"))
                                         .attribute(ATTRIBUTE_ENDPOINT, "test")
                                         .build();
    ClientResponse response = ClientResponse.create(HttpStatus.OK)
                                            .header(CONTENT_TYPE, ActuatorMediaType.V1_JSON)
                                            .body(Flux.just(ORIGINAL))
                                            .build();

    Mono<ClientResponse> convertedResponse = filter.filter(request, r -> Mono.just(response));

    StepVerifier.create(convertedResponse)
                .assertNext(r -> StepVerifier.create(r.body(BodyExtractors.toDataBuffers()))
                                             .expectNext(CONVERTED)
                                             .verifyComplete())
                .verifyComplete();
}
 
Example #7
Source File: WiretapConnectorTests.java    From spring-analysis-note with MIT License 6 votes vote down vote up
@Test
public void captureAndClaim() {
	ClientHttpRequest request = new MockClientHttpRequest(HttpMethod.GET, "/test");
	ClientHttpResponse response = new MockClientHttpResponse(HttpStatus.OK);
	ClientHttpConnector connector = (method, uri, fn) -> fn.apply(request).then(Mono.just(response));

	ClientRequest clientRequest = ClientRequest.create(HttpMethod.GET, URI.create("/test"))
			.header(WebTestClient.WEBTESTCLIENT_REQUEST_ID, "1").build();

	WiretapConnector wiretapConnector = new WiretapConnector(connector);
	ExchangeFunction function = ExchangeFunctions.create(wiretapConnector);
	function.exchange(clientRequest).block(ofMillis(0));

	WiretapConnector.Info actual = wiretapConnector.claimRequest("1");
	ExchangeResult result = actual.createExchangeResult(Duration.ZERO, null);
	assertEquals(HttpMethod.GET, result.getMethod());
	assertEquals("/test", result.getUrl().toString());
}
 
Example #8
Source File: WingtipsSpringWebfluxExchangeFilterFunction.java    From wingtips with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the name that should be used for the subspan surrounding the call. Defaults to whatever {@link
 * HttpTagAndSpanNamingStrategy#getInitialSpanName(Object, HttpTagAndSpanNamingAdapter)} returns, with a fallback
 * of {@link HttpRequestTracingUtils#getFallbackSpanNameForHttpRequest(String, String)} if the naming strategy
 * returned null or blank string. You can override this method to return something else if you want different
 * behavior and you don't want to adjust the naming strategy or adapter.
 *
 * @param request The request that is about to be executed.
 * @param namingStrategy The {@link HttpTagAndSpanNamingStrategy} being used.
 * @param adapter The {@link HttpTagAndSpanNamingAdapter} being used.
 * @return The name that should be used for the subspan surrounding the call.
 */
protected @NotNull String getSubspanSpanName(
    @NotNull ClientRequest request,
    @NotNull HttpTagAndSpanNamingStrategy<ClientRequest, ?> namingStrategy,
    @NotNull HttpTagAndSpanNamingAdapter<ClientRequest, ?> adapter
) {
    // Try the naming strategy first.
    String subspanNameFromStrategy = namingStrategy.getInitialSpanName(request, adapter);

    if (StringUtils.isNotBlank(subspanNameFromStrategy)) {
        return subspanNameFromStrategy;
    }

    // The naming strategy didn't have anything for us. Fall back to something reasonable.
    return HttpRequestTracingUtils.getFallbackSpanNameForHttpRequest(
        "webflux_downstream_call", getRequestMethodAsString(request.method())
    );
}
 
Example #9
Source File: InstanceExchangeFilterFunctionsTest.java    From spring-boot-admin with Apache License 2.0 6 votes vote down vote up
@Test
void should_convert_json() {
	ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("/test"))
			.attribute(ATTRIBUTE_ENDPOINT, "test").build();
	ClientResponse legacyResponse = ClientResponse.create(HttpStatus.OK)
			.header(CONTENT_TYPE, APPLICATION_JSON_VALUE)
			.header(CONTENT_LENGTH, Integer.toString(this.original.readableByteCount()))
			.body(Flux.just(this.original)).build();

	Mono<ClientResponse> response = this.filter.filter(INSTANCE, request, (r) -> Mono.just(legacyResponse));

	StepVerifier.create(response).assertNext((r) -> {
		assertThat(r.headers().contentType()).hasValue(MediaType.valueOf(ActuatorMediaType.V2_JSON));
		assertThat(r.headers().contentLength()).isEmpty();
		StepVerifier.create(r.body(BodyExtractors.toDataBuffers())).expectNext(this.converted).verifyComplete();
	}).verifyComplete();
}
 
Example #10
Source File: WingtipsSpringWebfluxExchangeFilterFunction.java    From wingtips with Apache License 2.0 6 votes vote down vote up
/**
 * Helper method that calls {@link #completeSubspanAttachedToCurrentThread(ClientRequest, ClientResponse,
 * Throwable, HttpTagAndSpanNamingStrategy, HttpTagAndSpanNamingAdapter, Pair[])} after attaching the given
 * {@link TracingState} for the subspan to the current thread. If that tracing state is null, then this
 * method does nothing.
 *
 * @param spanAroundCallTracingState The tracing state for the subspan.
 * @param request The request.
 * @param response The response (may be null).
 * @param error The error that occurred (may be null).
 */
@SuppressWarnings("SameParameterValue")
protected void completeSubspan(
    @Nullable TracingState spanAroundCallTracingState,
    @NotNull ClientRequest request,
    @Nullable ClientResponse response,
    @Nullable Throwable error
) {
    if (spanAroundCallTracingState != null) {
        runnableWithTracing(
            () -> completeSubspanAttachedToCurrentThread(
                request, response, error, tagAndNamingStrategy, tagAndNamingAdapter
            ),
            spanAroundCallTracingState
        ).run();
    }
}
 
Example #11
Source File: WingtipsSpringWebfluxExchangeFilterFunction.java    From wingtips with Apache License 2.0 6 votes vote down vote up
@Override
public @NotNull Mono<ClientResponse> filter(
    @NotNull ClientRequest request, @NotNull ExchangeFunction next
) {
    // Try to get the base tracing state from the request attributes first.
    Optional<TracingState> tcFromRequestAttributesOpt = request
        .attribute(TracingState.class.getName())
        .map(o -> (TracingState)o);

    // If the request attributes contains a TracingState, then that's what we should use for the request.
    //      Otherwise, we'll just go with whatever's on the current thread.
    Supplier<Mono<ClientResponse>> resultSupplier = () -> doFilterForCurrentThreadTracingState(request, next);
    return tcFromRequestAttributesOpt.map(
        tcFromRequestAttributes -> supplierWithTracing(
            resultSupplier,
            tcFromRequestAttributes
        ).get()
    ).orElseGet(
        resultSupplier
    );
}
 
Example #12
Source File: InstanceExchangeFilterFunctionsTest.java    From spring-boot-admin with Apache License 2.0 6 votes vote down vote up
@Test
void should_not_convert_v2_actuator() {
	InstanceExchangeFilterFunction filter = InstanceExchangeFilterFunctions.convertLegacyEndpoints(
			singletonList(new LegacyEndpointConverter("test", (from) -> Flux.just(this.converted)) {
			}));

	ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("/test"))
			.attribute(ATTRIBUTE_ENDPOINT, "test").build();
	ClientResponse response = ClientResponse.create(HttpStatus.OK)
			.header(CONTENT_TYPE, ActuatorMediaType.V2_JSON)
			.header(CONTENT_LENGTH, Integer.toString(this.original.readableByteCount()))
			.body(Flux.just(this.original)).build();

	Mono<ClientResponse> convertedResponse = filter.filter(INSTANCE, request, (r) -> Mono.just(response));

	StepVerifier.create(convertedResponse).assertNext((r) -> {
		assertThat(r.headers().contentType()).hasValue(MediaType.valueOf(ActuatorMediaType.V2_JSON));
		assertThat(r.headers().contentLength()).hasValue(this.original.readableByteCount());
		StepVerifier.create(r.body(BodyExtractors.toDataBuffers())).expectNext(this.original).verifyComplete();
	}).verifyComplete();
}
 
Example #13
Source File: ApplicationTests.java    From Learning-Path-Spring-5-End-to-End-Programming with MIT License 6 votes vote down vote up
@Test
public void customArgument() throws Exception {
	ClientRequest<Void> request = ClientRequest
								.GET("http://localhost:{port}", this.port)
								.build();

	Mono<Greet> result = webClient
			   .exchange(request)
			   .then(response -> response.bodyToMono(Greet.class));
	
	//https://github.com/bclozel/spring-boot-web-reactive
	 
	result.subscribe(greet -> System.out.println(greet.getMessage()));
	
	ScriptedSubscriber.<Greet>create()
						.consumeNextWith(content -> {
						assertThat(content.getMessage()).contains("Hello World!");
						})
						.expectComplete()
						.verify(result);
}
 
Example #14
Source File: MainController.java    From keycloak-springsecurity5-sample with GNU General Public License v3.0 6 votes vote down vote up
private ExchangeFilterFunction oauth2Credentials(OAuth2AuthorizedClient authorizedClient) {
    return ExchangeFilterFunction.ofRequestProcessor(
        clientRequest -> {
            ClientRequest authorizedRequest = ClientRequest.from(clientRequest)
                .header(HttpHeaders.AUTHORIZATION, "Bearer " + authorizedClient.getAccessToken().getTokenValue())
                .build();
            return Mono.just(authorizedRequest);
        });
}
 
Example #15
Source File: InstanceExchangeFilterFunctionsTest.java    From spring-boot-admin with Apache License 2.0 6 votes vote down vote up
@Test
void should_not_convert_without_converter() {
	InstanceExchangeFilterFunction filter = InstanceExchangeFilterFunctions.convertLegacyEndpoints(
			singletonList(new LegacyEndpointConverter("test", (from) -> Flux.just(this.converted)) {
			}));

	ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("/unknown"))
			.attribute(ATTRIBUTE_ENDPOINT, "unknown").build();
	ClientResponse response = ClientResponse.create(HttpStatus.OK).header(CONTENT_TYPE, APPLICATION_JSON_VALUE)
			.header(CONTENT_LENGTH, Integer.toString(this.original.readableByteCount()))
			.body(Flux.just(this.original)).build();

	Mono<ClientResponse> convertedResponse = filter.filter(INSTANCE, request, (r) -> Mono.just(response));

	StepVerifier.create(convertedResponse).assertNext((r) -> {
		assertThat(r.headers().contentType()).hasValue(MediaType.APPLICATION_JSON);
		assertThat(r.headers().contentLength()).hasValue(this.original.readableByteCount());
		StepVerifier.create(r.body(BodyExtractors.toDataBuffers())).expectNext(this.original).verifyComplete();
	}).verifyComplete();
}
 
Example #16
Source File: InstanceExchangeFilterFunctionsTest.java    From spring-boot-admin with Apache License 2.0 6 votes vote down vote up
@Test
void should_retry_using_endpoint_value_default() {
	InstanceExchangeFilterFunction filter = InstanceExchangeFilterFunctions.retry(0, singletonMap("test", 1));

	ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("/test"))
			.attribute(ATTRIBUTE_ENDPOINT, "test").build();
	ClientResponse response = ClientResponse.create(HttpStatus.OK).build();

	AtomicLong invocationCount = new AtomicLong(0L);
	ExchangeFunction exchange = (r) -> Mono.fromSupplier(() -> {
		if (invocationCount.getAndIncrement() == 0) {
			throw new IllegalStateException("Test");
		}
		return response;
	});

	StepVerifier.create(filter.filter(INSTANCE, request, exchange)).expectNext(response).verifyComplete();
	assertThat(invocationCount.get()).isEqualTo(2);
}
 
Example #17
Source File: EurekaLoadBalancingExchangeFilterFunctionTest.java    From titus-control-plane with Apache License 2.0 6 votes vote down vote up
private ClientResponse execute(String eurekaUri) {
    EurekaLoadBalancingExchangeFilterFunction filter = new EurekaLoadBalancingExchangeFilterFunction(
            eurekaServer.getEurekaClient(), EurekaUris::getServiceName, titusRuntime
    );

    ClientRequest request = mock(ClientRequest.class);
    when(request.url()).thenReturn(URI.create(eurekaUri));
    when(request.method()).thenReturn(HttpMethod.GET);
    when(request.headers()).thenReturn(HttpHeaders.EMPTY);
    when(request.cookies()).thenReturn(HttpHeaders.EMPTY);

    ExchangeFunction next = mock(ExchangeFunction.class);
    when(next.exchange(any())).thenAnswer(invocation -> {
        ClientRequest rewrittenRequest = invocation.getArgument(0);
        ClientResponse clientResponse = mock(ClientResponse.class);
        if (rewrittenRequest.url().getHost().equals("1.0.0.1")) {
            when(clientResponse.statusCode()).thenReturn(HttpStatus.OK);
        } else {
            when(clientResponse.statusCode()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return Mono.just(clientResponse);
    });

    return filter.filter(request, next).block();
}
 
Example #18
Source File: EurekaLoadBalancingExchangeFilterFunction.java    From titus-control-plane with Apache License 2.0 6 votes vote down vote up
private Mono<ClientResponse> doExecute(InstanceInfo instance, ClientRequest request, ExchangeFunction next) {
    URI eurekaUri = request.url();
    URI rewrittenURI = rewrite(eurekaUri, instance);

    ClientRequest newRequest = ClientRequest.create(request.method(), rewrittenURI)
            .headers(headers -> headers.addAll(request.headers()))
            .cookies(cookies -> cookies.addAll(request.cookies()))
            .attributes(attributes -> attributes.putAll(request.attributes()))
            .body(request.body()).build();
    return next.exchange(newRequest)
            .doOnNext(response -> {
                if (response.statusCode().is5xxServerError()) {
                    loadBalancer.recordFailure(eurekaUri, instance);
                } else {
                    loadBalancer.recordSuccess(eurekaUri, instance);
                }
            })
            .doOnError(error -> loadBalancer.recordFailure(eurekaUri, instance));
}
 
Example #19
Source File: ReactorLoadBalancerExchangeFilterFunction.java    From spring-cloud-commons with Apache License 2.0 5 votes vote down vote up
private ClientRequest buildClientRequest(ClientRequest request, URI uri) {
	return ClientRequest.create(request.method(), uri)
			.headers(headers -> headers.addAll(request.headers()))
			.cookies(cookies -> cookies.addAll(request.cookies()))
			.attributes(attributes -> attributes.putAll(request.attributes()))
			.body(request.body()).build();
}
 
Example #20
Source File: InstanceExchangeFilterFunctionsTest.java    From spring-boot-admin with Apache License 2.0 5 votes vote down vote up
@Test
void should_add_default_accept_headers() {
	ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("/test")).build();

	Mono<ClientResponse> response = this.filter.filter(INSTANCE, request, (req) -> {
		assertThat(req.headers().getAccept()).containsExactly(ACTUATOR_V2_MEDIATYPE, ACTUATOR_V1_MEDIATYPE,
				MediaType.APPLICATION_JSON);
		return Mono.just(ClientResponse.create(HttpStatus.OK).build());
	});

	StepVerifier.create(response).expectNextCount(1).verifyComplete();
}
 
Example #21
Source File: RetryAttemptsResponseHeaderSetter.java    From charon-spring-boot-starter with Apache License 2.0 5 votes vote down vote up
@Override
public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next) {
    // Exceptions thrown before return WILL NOT trigger circuit breaker nor retryer.
    return next.exchange(request)
            .map(response -> from(response)
                    .headers(httpHeaders -> httpHeaders.set("Retry-Attempts", valueOf(attempt.incrementAndGet())))
                    .body(response.body(toDataBuffers())) // Need to consume body, otherwise the request will HANG after ReverseProxyFilter.
                    .build());
}
 
Example #22
Source File: ReactiveVaultTemplate.java    From spring-vault with Apache License 2.0 5 votes vote down vote up
private ExchangeFilterFunction getSessionFilter() {

		return ofRequestProcessor(request -> this.vaultTokenSupplier.getVaultToken().map(token -> {

			return ClientRequest.from(request).headers(headers -> {
				headers.set(VaultHttpHeaders.VAULT_TOKEN, token.getToken());
			}).build();
		}));
	}
 
Example #23
Source File: TraceWebClientBeanPostProcessor.java    From spring-cloud-sleuth with Apache License 2.0 5 votes vote down vote up
MonoWebClientTrace(ExchangeFunction next, ClientRequest request,
		TraceExchangeFilterFunction filterFunction) {
	this.next = next;
	this.request = request;
	this.handler = filterFunction.handler();
	this.currentTraceContext = filterFunction.currentTraceContext();
	this.scopePassingTransformer = filterFunction.scopePassingTransformer;
	this.parent = currentTraceContext.get();
}
 
Example #24
Source File: WingtipsSpringWebfluxExchangeFilterFunctionTest.java    From wingtips with Apache License 2.0 5 votes vote down vote up
NullConstructorArgScenario(
    HttpTagAndSpanNamingStrategy<ClientRequest, ClientResponse> tagAndNamingStrategy,
    HttpTagAndSpanNamingAdapter<ClientRequest, ClientResponse> tagAndNamingAdapter,
    String expectedErrorMessage
) {
    this.tagAndNamingStrategy = tagAndNamingStrategy;
    this.tagAndNamingAdapter = tagAndNamingAdapter;
    this.expectedErrorMessage = expectedErrorMessage;
}
 
Example #25
Source File: HttpRequestInterceptor.java    From charon-spring-boot-starter with Apache License 2.0 5 votes vote down vote up
@Override
public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction exchange) {
    HttpRequest httpRequest = request instanceof HttpRequest
            ? (HttpRequest) request
            : new HttpRequest(request);
    HttpRequestExecution requestExecution = exchange instanceof HttpRequestExecution
            ? (HttpRequestExecution) exchange
            : new HttpRequestExecution(mappingName, exchange);
    return requestForwardingInterceptor.forward(httpRequest, requestExecution).cast(ClientResponse.class);
}
 
Example #26
Source File: SpringWebfluxClientRequestTagAdapter.java    From wingtips with Apache License 2.0 5 votes vote down vote up
@Override
public @Nullable String getRequestHttpMethod(@Nullable ClientRequest request) {
    if (request == null || request.method() == null) {
        return null;
    }

    return request.method().name();
}
 
Example #27
Source File: InstanceExchangeFilterFunctions.java    From spring-boot-admin with Apache License 2.0 5 votes vote down vote up
public static InstanceExchangeFilterFunction rewriteEndpointUrl() {
	return (instance, request, next) -> {
		if (request.url().isAbsolute()) {
			log.trace("Absolute URL '{}' for instance {} not rewritten", request.url(), instance.getId());
			if (request.url().toString().equals(instance.getRegistration().getManagementUrl())) {
				request = ClientRequest.from(request).attribute(ATTRIBUTE_ENDPOINT, Endpoint.ACTUATOR_INDEX)
						.build();
			}
			return next.exchange(request);
		}

		UriComponents requestUrl = UriComponentsBuilder.fromUri(request.url()).build();
		if (requestUrl.getPathSegments().isEmpty()) {
			return Mono.error(new ResolveEndpointException("No endpoint specified"));
		}

		String endpointId = requestUrl.getPathSegments().get(0);
		Optional<Endpoint> endpoint = instance.getEndpoints().get(endpointId);

		if (!endpoint.isPresent()) {
			return Mono.error(new ResolveEndpointException("Endpoint '" + endpointId + "' not found"));
		}

		URI rewrittenUrl = rewriteUrl(requestUrl, endpoint.get().getUrl());
		log.trace("URL '{}' for Endpoint {} of instance {} rewritten to {}", requestUrl, endpoint.get().getId(),
				instance.getId(), rewrittenUrl);
		request = ClientRequest.from(request).attribute(ATTRIBUTE_ENDPOINT, endpoint.get().getId())
				.url(rewrittenUrl).build();
		return next.exchange(request);
	};
}
 
Example #28
Source File: WingtipsSpringWebfluxComponentTest.java    From wingtips with Apache License 2.0 5 votes vote down vote up
@Override
public @Nullable String getRequestUriPathTemplate(
    @Nullable ClientRequest request,
    @Nullable ClientResponse response
) {
    return httpRouteForAllRequests;
}
 
Example #29
Source File: SpringWebfluxClientRequestZipkinTagStrategyTest.java    From wingtips with Apache License 2.0 5 votes vote down vote up
@UseDataProvider("logPrefixScenarioDataProvider")
@Test
public void doHandleRequestTagging_adds_expected_zipkin_tags_and_spring_log_prefix_tag(
    LogPrefixScenario scenario
) {
    // given
    SpringWebfluxClientRequestZipkinTagStrategy impl = new SpringWebfluxClientRequestZipkinTagStrategy();
    Span span = Span.newBuilder("fooSpan", SpanPurpose.CLIENT).build();
    ClientRequest requestMock = mock(ClientRequest.class);
    @SuppressWarnings("unchecked")
    HttpTagAndSpanNamingAdapter<ClientRequest, ?> adapterMock = mock(HttpTagAndSpanNamingAdapter.class);

    String httpMethod = UUID.randomUUID().toString();
    String path = UUID.randomUUID().toString();
    String url = UUID.randomUUID().toString();
    String pathTemplate = UUID.randomUUID().toString();

    doReturn(httpMethod).when(adapterMock).getRequestHttpMethod(requestMock);
    doReturn(path).when(adapterMock).getRequestPath(requestMock);
    doReturn(url).when(adapterMock).getRequestUrl(requestMock);
    doReturn(pathTemplate).when(adapterMock).getRequestUriPathTemplate(requestMock, null);
    doReturn(scenario.logPrefix).when(requestMock).logPrefix();

    // when
    impl.doHandleRequestTagging(span, requestMock, adapterMock);

    // then
    assertThat(span.getTags().get(KnownZipkinTags.HTTP_METHOD)).isEqualTo(httpMethod);
    assertThat(span.getTags().get(KnownZipkinTags.HTTP_PATH)).isEqualTo(path);
    assertThat(span.getTags().get(KnownZipkinTags.HTTP_URL)).isEqualTo(url);
    assertThat(span.getTags().get(KnownZipkinTags.HTTP_ROUTE)).isEqualTo(pathTemplate);
    assertThat(span.getTags().get(SPRING_LOG_ID_TAG_KEY)).isEqualTo(scenario.expectedTagValue);
}
 
Example #30
Source File: SpringWebfluxClientRequestTagAdapter.java    From wingtips with Apache License 2.0 5 votes vote down vote up
@Override
public @Nullable String getRequestUrl(@Nullable ClientRequest request) {
    if (request == null || request.url() == null) {
        return null;
    }

    return request.url().toString();
}