Java Code Examples for com.nike.wingtips.Span#close()

The following examples show how to use com.nike.wingtips.Span#close() . 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: WingtipsClientHttpRequestInterceptor.java    From wingtips with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a subspan (or new trace if no current span exists) to surround the HTTP request, then returns the
 * result of calling {@link #propagateTracingHeadersAndExecuteRequest(HttpRequestWrapperWithModifiableHeaders,
 * byte[], ClientHttpRequestExecution)} to actually execute the request. Span naming and tagging is done here using
 * {@link #tagAndNamingStrategy} and {@link #tagAndNamingAdapter}.
 *
 * @return The result of calling {@link
 * #propagateTracingHeadersAndExecuteRequest(HttpRequestWrapperWithModifiableHeaders, byte[],
 * ClientHttpRequestExecution)} after surrounding the request with a subspan (or new trace if no current span
 * exists).
 */
protected ClientHttpResponse createNewSpanAndExecuteRequest(
    HttpRequestWrapperWithModifiableHeaders wrapperRequest, byte[] body, ClientHttpRequestExecution execution
) throws IOException {
    // Will start a new trace if necessary, or a subspan if a trace is already in progress.
    Span spanAroundCall = Tracer.getInstance().startSpanInCurrentContext(
        getSubspanSpanName(wrapperRequest, tagAndNamingStrategy, tagAndNamingAdapter),
        SpanPurpose.CLIENT
    );

    Throwable errorForTagging = null;
    ClientHttpResponse response = null;
    try {
        tagAndNamingStrategy.handleRequestTagging(spanAroundCall, wrapperRequest, tagAndNamingAdapter);
        response = propagateTracingHeadersAndExecuteRequest(wrapperRequest, body, execution);

        return response;
    } catch(Throwable exception) {
        errorForTagging = exception;
        throw exception;
    }
    finally {
        try {
            // Handle response/error tagging and final span name.
            tagAndNamingStrategy.handleResponseTaggingAndFinalSpanName(
                spanAroundCall, wrapperRequest, response, errorForTagging, tagAndNamingAdapter
            );
        }
        finally {
            // Span.close() contains the span-finishing logic we want - if the spanAroundCall was an overall span
            //      (new trace) then tracer.completeRequestSpan() will be called, otherwise it's a subspan and
            //      tracer.completeSubSpan() will be called.
            spanAroundCall.close();
        }
    }
}
 
Example 2
Source File: WingtipsToLightStepLifecycleListenerTest.java    From wingtips with Apache License 2.0 5 votes vote down vote up
@Test
public void spanCompleted_does_not_propagate_unexpected_exception() {
    // given
    doThrow(new RuntimeException("intentional test exception")).when(jreTracerMock).buildSpan(anyString());
    Span completedSpan = Span.newBuilder("fooSpan", Span.SpanPurpose.CLIENT).build();
    completedSpan.close();

    // when
    Throwable ex = catchThrowable(() -> listener.spanCompleted(completedSpan));

    // then
    verify(jreTracerMock).buildSpan(anyString());
    assertThat(ex).isNull();
}
 
Example 3
Source File: AsyncCompletionHandlerWithTracingAndMdcSupport.java    From riposte with Apache License 2.0 4 votes vote down vote up
@Override
public Response onCompleted(Response response) {
    Pair<Deque<Span>, Map<String, String>> originalThreadInfo = null;

    try {
        // Link up the distributed tracing and MDC information to the current thread
        originalThreadInfo = linkTracingAndMdcToCurrentThread(distributedTraceStackToUse, mdcContextToUse);

        // Notify the circuit breaker of an event.
        try {
            circuitBreakerManualTask.ifPresent(cb -> cb.handleEvent(response));
        } catch (Throwable t) {
            logger.error(
                    "Circuit breaker threw an exception during handleEvent. This should never happen and means the "
                            + "CircuitBreaker is malfunctioning. Ignoring exception.", t
            );
        }

        // If a subspan was started for the downstream call, it should now be completed
        if (performSubSpanAroundDownstreamCalls) {
            Span spanAroundCall = Tracer.getInstance().getCurrentSpan();

            // Handle the final span naming and response tagging.
            tagAndNamingStrategy.handleResponseTaggingAndFinalSpanName(
                    spanAroundCall, rbwCopyWithHttpMethodAndUrlOnly, response, null
            );

            // The Span.close() method will do the right thing whether or not this is an overall request span or
            //      subspan.
            spanAroundCall.close();
        }

        // If the completableFutureResponse is already done it means we were cancelled or some other error occurred,
        //      and we should not do any more processing here.
        if (completableFutureResponse.isDone())
            return response;

        // Pass the response to our responseHandlerFunction to get the resulting object to complete the
        //      completableFutureResponse with.
        try {
            O responseInfo = responseHandlerFunction.handleResponse(response);
            completableFutureResponse.complete(responseInfo);
        } catch (Throwable throwable) {
            // responseHandlerFunction threw an error. Complete completableFutureResponse exceptionally.
            completableFutureResponse.completeExceptionally(throwable);
        }

        return response;
    } finally {
        AsyncNettyHelper.unlinkTracingAndMdcFromCurrentThread(originalThreadInfo);
    }
}
 
Example 4
Source File: AsyncCompletionHandlerWithTracingAndMdcSupport.java    From riposte with Apache License 2.0 4 votes vote down vote up
@Override
public void onThrowable(Throwable t) {
    Pair<Deque<Span>, Map<String, String>> originalThreadInfo = null;

    try {
        // Link up the distributed trace and MDC information to the current thread
        originalThreadInfo =
                linkTracingAndMdcToCurrentThread(distributedTraceStackToUse, mdcContextToUse);

        // Notify the circuit breaker of an exception.
        try {
            circuitBreakerManualTask.ifPresent(cb -> cb.handleException(t));
        } catch (Throwable cbError) {
            logger.error(
                    "Circuit breaker threw an exception during handleException. This should never happen and means the "
                            + "CircuitBreaker is malfunctioning. Ignoring exception.", cbError
            );
        }

        // If a subspan was started for the downstream call, it should now be completed
        if (performSubSpanAroundDownstreamCalls) {
            Span spanAroundCall = Tracer.getInstance().getCurrentSpan();

            // Handle the final span naming and response tagging.
            tagAndNamingStrategy.handleResponseTaggingAndFinalSpanName(
                    spanAroundCall, rbwCopyWithHttpMethodAndUrlOnly, null, t
            );

            // The Span.close() method will do the right thing whether or not this is an overall request span or
            //      subspan.
            spanAroundCall.close();
        }

        // If the completableFutureResponse is already done it means we were cancelled or some other error occurred,
        //      and we should not do any more processing here.
        if (completableFutureResponse.isDone())
            return;

        // Complete the completableFutureResponse with the exception.
        completableFutureResponse.completeExceptionally(t);
    } finally {
        AsyncNettyHelper.unlinkTracingAndMdcFromCurrentThread(originalThreadInfo);
    }
}
 
Example 5
Source File: AsyncCompletionHandlerWithTracingAndMdcSupport.java    From riposte with Apache License 2.0 4 votes vote down vote up
@Override
public Response onCompleted(Response response) {
    Pair<Deque<Span>, Map<String, String>> originalThreadInfo = null;

    try {
        // Link up the distributed tracing and MDC information to the current thread
        originalThreadInfo = linkTracingAndMdcToCurrentThread(distributedTraceStackToUse, mdcContextToUse);

        // Notify the circuit breaker of an event.
        try {
            circuitBreakerManualTask.ifPresent(cb -> cb.handleEvent(response));
        }
        catch (Throwable t) {
            logger.error(
                "Circuit breaker threw an exception during handleEvent. This should never happen and means the "
                + "CircuitBreaker is malfunctioning. Ignoring exception.", t
            );
        }

        // If a subspan was started for the downstream call, it should now be completed
        if (performSubSpanAroundDownstreamCalls) {
            Span spanAroundCall = Tracer.getInstance().getCurrentSpan();

            // Handle the final span naming and response tagging.
            tagAndNamingStrategy.handleResponseTaggingAndFinalSpanName(
                spanAroundCall, rbwCopyWithHttpMethodAndUrlOnly, response, null
            );

            // The Span.close() method will do the right thing whether or not this is an overall request span or
            //      subspan.
            spanAroundCall.close();
        }

        // If the completableFutureResponse is already done it means we were cancelled or some other error occurred,
        //      and we should not do any more processing here.
        if (completableFutureResponse.isDone())
            return response;

        // Pass the response to our responseHandlerFunction to get the resulting object to complete the
        //      completableFutureResponse with.
        try {
            O responseInfo = responseHandlerFunction.handleResponse(response);
            completableFutureResponse.complete(responseInfo);
        }
        catch (Throwable throwable) {
            // responseHandlerFunction threw an error. Complete completableFutureResponse exceptionally.
            completableFutureResponse.completeExceptionally(throwable);
        }

        return response;
    }
    finally {
        AsyncNettyHelper.unlinkTracingAndMdcFromCurrentThread(originalThreadInfo);
    }
}
 
Example 6
Source File: AsyncCompletionHandlerWithTracingAndMdcSupport.java    From riposte with Apache License 2.0 4 votes vote down vote up
@Override
public void onThrowable(Throwable t) {
    Pair<Deque<Span>, Map<String, String>> originalThreadInfo = null;

    try {
        // Link up the distributed trace and MDC information to the current thread
        originalThreadInfo =
            linkTracingAndMdcToCurrentThread(distributedTraceStackToUse, mdcContextToUse);

        // Notify the circuit breaker of an exception.
        try {
            circuitBreakerManualTask.ifPresent(cb -> cb.handleException(t));
        }
        catch (Throwable cbError) {
            logger.error(
                "Circuit breaker threw an exception during handleException. This should never happen and means the "
                + "CircuitBreaker is malfunctioning. Ignoring exception.", cbError
            );
        }

        // If a subspan was started for the downstream call, it should now be completed
        if (performSubSpanAroundDownstreamCalls) {
            Span spanAroundCall = Tracer.getInstance().getCurrentSpan();

            // Handle the final span naming and response tagging.
            tagAndNamingStrategy.handleResponseTaggingAndFinalSpanName(
                spanAroundCall, rbwCopyWithHttpMethodAndUrlOnly, null, t
            );

            // The Span.close() method will do the right thing whether or not this is an overall request span or
            //      subspan.
            spanAroundCall.close();
        }

        // If the completableFutureResponse is already done it means we were cancelled or some other error occurred,
        //      and we should not do any more processing here.
        if (completableFutureResponse.isDone())
            return;

        // Complete the completableFutureResponse with the exception.
        completableFutureResponse.completeExceptionally(t);
    }
    finally {
        AsyncNettyHelper.unlinkTracingAndMdcFromCurrentThread(originalThreadInfo);
    }
}
 
Example 7
Source File: WingtipsSpringWebfluxExchangeFilterFunction.java    From wingtips with Apache License 2.0 4 votes vote down vote up
/**
 * Helper method that completes whatever span is currently attached to the caller's thread ({@link
 * Tracer#getCurrentSpan()}) at the time this method is called. This is expected to be the subspan around the
 * WebClient call.
 *
 * <p>If the current span is null, or if it's already been completed, then this method will do nothing.
 *
 * @param request The request.
 * @param response The response (if any) - may be null.
 * @param error The error associated with the subspan (if any) - may be null.
 * @param tagAndNamingStrategy The tag strategy to use to handle the response tagging and final span name on
 * the subspan.
 * @param tagAndNamingAdapter The tag adapter to use to handle the response tagging and final span name on
 * the subspan.
 * @param extraCustomTags Any extra custom tags you want added to the subspan beyond what the tag strategy
 * will do - may be null or empty.
 */
@SafeVarargs
protected static void completeSubspanAttachedToCurrentThread(
    @NotNull ClientRequest request,
    @Nullable ClientResponse response,
    @Nullable Throwable error,
    @NotNull HttpTagAndSpanNamingStrategy<ClientRequest, ClientResponse> tagAndNamingStrategy,
    @NotNull HttpTagAndSpanNamingAdapter<ClientRequest, ClientResponse> tagAndNamingAdapter,
    Pair<String, String>... extraCustomTags
) {
    Span span = Tracer.getInstance().getCurrentSpan();

    // This method should never be called with a null current span, but if it does happen then there's nothing
    //      for us to do.
    if (span == null) {
        return;
    }

    // Do nothing if the span is already completed - should never happen in reality, but if it does we'll avoid
    //      headaches by short circuiting.
    if (span.isCompleted()) {
        return;
    }

    try {
        // Add any extra custom tags.
        if (extraCustomTags != null) {
            for (Pair<String, String> tag : extraCustomTags) {
                span.putTag(tag.getKey(), tag.getValue());
            }
        }

        // Handle response/error tagging and final span name.
        tagAndNamingStrategy.handleResponseTaggingAndFinalSpanName(
            span, request, response, error, tagAndNamingAdapter
        );
    }
    finally {
        // Span.close() contains the logic we want - if the span around the WebClient call was an overall span
        //      (new trace) then tracer.completeRequestSpan() will be called, otherwise it's
        //      a subspan and tracer.completeSubSpan() will be called.
        span.close();
    }
}
 
Example 8
Source File: WingtipsSpringWebfluxComponentTest.java    From wingtips with Apache License 2.0 4 votes vote down vote up
@UseDataProvider("baseTracingStateWithSubspanOptionScenarioDataProvider")
@Test
public void verify_webflux_WebClient_with_WingtipsSpringWebfluxExchangeFilterFunction_traced_correctly(
    BaseTracingStateScenario baseTracingStateScenario, boolean subspanOptionOn
) {
    // given
    TracingState baseTracingState = baseTracingStateScenario.setupBaseTracingState();
    Span parent = (baseTracingState == null) ? null : baseTracingState.spanStack.getFirst();

    String pathTemplateForTags = "/some/path/template/" + UUID.randomUUID().toString();

    WebClient webClientWithWingtips = WebClient
        .builder()
        .filter(
            new WingtipsSpringWebfluxExchangeFilterFunction(
                subspanOptionOn,
                SpringWebfluxClientRequestZipkinTagStrategy.getDefaultInstance(),
                new SpringHttpClientTagAdapterWithHttpRouteKnowledge(pathTemplateForTags)
            )
        )
        .build();

    // We always expect at least one span to be completed as part of the call: the server span.
    //      We may or may not have a second span completed depending on the value of subspanOptionOn.
    int expectedNumSpansCompleted = (subspanOptionOn) ? 2 : 1;

    String fullRequestUrl = "http://localhost:" + SERVER_PORT + BASIC_ENDPOINT_PATH + "?foo=bar";

    // when
    ClientResponse response = webClientWithWingtips
        .get()
        .uri(fullRequestUrl)
        .attributes(baseTracingStateScenario.tracingStateAttrSetup(baseTracingState))
        .exchange()
        .block();

    // then
    assertThat(response.statusCode().value()).isEqualTo(200);
    assertThat(response.bodyToMono(String.class).block()).isEqualTo(BASIC_ENDPOINT_PAYLOAD);
    verifySpansCompletedAndReturnedInResponse(
        response, SLEEP_TIME_MILLIS, expectedNumSpansCompleted, parent, subspanOptionOn
    );

    if (subspanOptionOn) {
        Span clientSpan = findWebfluxWebClientSpanFromCompletedSpans();
        verifySpanNameAndTags(
            clientSpan,
            "GET " + pathTemplateForTags,
            null,
            "GET",
            BASIC_ENDPOINT_PATH,
            fullRequestUrl,
            pathTemplateForTags,
            response.statusCode().value(),
            null,
            "spring.webflux.client"
        );
        assertThat(clientSpan.getTags().get("webflux_log_id")).isNotEmpty();
    }

    if (parent != null) {
        parent.close();
    }
}
 
Example 9
Source File: WingtipsSpringWebfluxComponentTest.java    From wingtips with Apache License 2.0 4 votes vote down vote up
@UseDataProvider("baseTracingStateWithSubspanOptionScenarioDataProvider")
@Test
public void verify_webflux_WebClient_call_with_error_in_Mono_of_ClientResponse_traced_correctly(
        BaseTracingStateScenario baseTracingStateScenario, boolean subspanOptionOn
) {
    // given
    TracingState baseTracingState = baseTracingStateScenario.setupBaseTracingState();
    Span parent = (baseTracingState == null) ? null : baseTracingState.spanStack.getFirst();

    String pathTemplateForTags = "/some/path/template/" + UUID.randomUUID().toString();

    WebClient webClientWithWingtips = WebClient
        .builder()
        .filter(
            new WingtipsSpringWebfluxExchangeFilterFunction(
                subspanOptionOn,
                SpringWebfluxClientRequestZipkinTagStrategy.getDefaultInstance(),
                new SpringHttpClientTagAdapterWithHttpRouteKnowledge(pathTemplateForTags)
            )
        )
        .build();

    // The call will never make it to the server, so we only expect one or zero spans completed,
    //      depending on the value of subspanOptionOn.
    int expectedNumSpansCompleted = (subspanOptionOn) ? 1 : 0;

    String fullRequestUrl = "http://localhost:1234567890" + BASIC_ENDPOINT_PATH + "?foo=bar";

    // when
    Throwable ex = catchThrowable(
        () -> webClientWithWingtips
            .get()
            .uri(fullRequestUrl)
            .attributes(baseTracingStateScenario.tracingStateAttrSetup(baseTracingState))
            .exchange()
            .block()
    );

    // then
    Throwable unwrappedEx = Exceptions.unwrap(ex);
    assertThat(unwrappedEx).isInstanceOf(UnknownHostException.class);
    waitUntilSpanRecorderHasExpectedNumSpans(expectedNumSpansCompleted);
    assertThat(spanRecorder.completedSpans).hasSize(expectedNumSpansCompleted);
    if (expectedNumSpansCompleted > 0) {
        Span errorSpan = spanRecorder.completedSpans.get(0);

        if (parent == null) {
            assertThat(errorSpan.getParentSpanId()).isNull();
        }
        else {
            assertThat(errorSpan.getTraceId()).isEqualTo(parent.getTraceId());
            assertThat(errorSpan.getParentSpanId()).isEqualTo(parent.getSpanId());
        }

        verifySpanNameAndTags(
            errorSpan,
            "GET " + pathTemplateForTags,
            null,
            "GET",
            BASIC_ENDPOINT_PATH,
            fullRequestUrl,
            pathTemplateForTags,
            null,
            unwrappedEx.getMessage(),
            "spring.webflux.client"
        );
        assertThat(errorSpan.getTags().get("webflux_log_id")).isNotEmpty();
    }

    if (parent != null) {
        parent.close();
    }
}
 
Example 10
Source File: WingtipsSpringWebfluxComponentTest.java    From wingtips with Apache License 2.0 4 votes vote down vote up
@UseDataProvider("baseTracingStateWithSubspanOptionScenarioDataProvider")
@Test
public void verify_webflux_WebClient_call_with_error_thrown_in_sub_filter_traced_correctly(
    BaseTracingStateScenario baseTracingStateScenario, boolean subspanOptionOn
) {
    // given
    TracingState baseTracingState = baseTracingStateScenario.setupBaseTracingState();
    Span parent = (baseTracingState == null) ? null : baseTracingState.spanStack.getFirst();

    String pathTemplateForTags = "/some/path/template/" + UUID.randomUUID().toString();

    RuntimeException subFilterEx = new RuntimeException(
        "Intentional test exception in secondary WebClient filter."
    );
    WebClient webClientWithWingtips = WebClient
        .builder()
        .filter(
            new WingtipsSpringWebfluxExchangeFilterFunction(
                subspanOptionOn,
                SpringWebfluxClientRequestZipkinTagStrategy.getDefaultInstance(),
                new SpringHttpClientTagAdapterWithHttpRouteKnowledge(pathTemplateForTags)
            )
        )
        .filter((request, next) -> {
            throw subFilterEx;
        })
        .build();

    // The call will never make it to the server, so we only expect one or zero spans completed,
    //      depending on the value of subspanOptionOn.
    int expectedNumSpansCompleted = (subspanOptionOn) ? 1 : 0;

    String fullRequestUrl = "http://localhost:1234567890" + BASIC_ENDPOINT_PATH + "?foo=bar";

    // when
    Throwable ex = catchThrowable(
        () -> webClientWithWingtips
            .get()
            .uri(fullRequestUrl)
            .attributes(baseTracingStateScenario.tracingStateAttrSetup(baseTracingState))
            .exchange()
            .block()
    );

    // then
    Throwable unwrappedEx = Exceptions.unwrap(ex);
    assertThat(unwrappedEx).isSameAs(subFilterEx);
    waitUntilSpanRecorderHasExpectedNumSpans(expectedNumSpansCompleted);
    assertThat(spanRecorder.completedSpans).hasSize(expectedNumSpansCompleted);
    if (expectedNumSpansCompleted > 0) {
        Span errorSpan = spanRecorder.completedSpans.get(0);

        if (parent == null) {
            assertThat(errorSpan.getParentSpanId()).isNull();
        }
        else {
            assertThat(errorSpan.getTraceId()).isEqualTo(parent.getTraceId());
            assertThat(errorSpan.getParentSpanId()).isEqualTo(parent.getSpanId());
        }

        verifySpanNameAndTags(
            errorSpan,
            "GET " + pathTemplateForTags,
            null,
            "GET",
            BASIC_ENDPOINT_PATH,
            fullRequestUrl,
            pathTemplateForTags,
            null,
            unwrappedEx.getMessage(),
            "spring.webflux.client"
        );
        assertThat(errorSpan.getTags().get("webflux_log_id")).isNotEmpty();
    }

    if (parent != null) {
        parent.close();
    }
}
 
Example 11
Source File: SpringAsyncAndBlockingRestTemplateWithWingtipsComponentTest.java    From wingtips with Apache License 2.0 4 votes vote down vote up
@DataProvider(value = {
    "true   |   true",
    "true   |   false",
    "false  |   true",
    "false  |   false"
}, splitBy = "\\|")
@Test
public void verify_blocking_RestTemplate_with_Wingtips_interceptor_traced_correctly(
    boolean spanAlreadyExistsBeforeCall, boolean subspanOptionOn
) {
    // given
    Span parent = null;
    if (spanAlreadyExistsBeforeCall) {
        parent = Tracer.getInstance().startRequestWithRootSpan("somePreexistingParentSpan");
    }

    String pathTemplateForTags = "/some/path/template/" + UUID.randomUUID().toString();

    RestTemplate restTemplateWithWingtips = WingtipsSpringUtil.createTracingEnabledRestTemplate(
        subspanOptionOn,
        ZipkinHttpTagStrategy.getDefaultInstance(),
        new SpringHttpClientTagAdapterWithHttpRouteKnowledge(pathTemplateForTags)
    );

    // We always expect at least one span to be completed as part of the call: the server span.
    //      We may or may not have a second span completed depending on the value of subspanOptionOn.
    int expectedNumSpansCompleted = (subspanOptionOn) ? 2 : 1;

    String fullRequestUrl = "http://localhost:" + SERVER_PORT + ENDPOINT_PATH + "?foo=bar";

    // when
    ResponseEntity<String> response = restTemplateWithWingtips.exchange(
        fullRequestUrl, HttpMethod.GET, null, String.class
    );

    // then
    assertThat(response.getStatusCode().value()).isEqualTo(200);
    assertThat(response.getBody()).isEqualTo(ENDPOINT_PAYLOAD);
    verifySpansCompletedAndReturnedInResponse(
        response, SLEEP_TIME_MILLIS, expectedNumSpansCompleted, parent, subspanOptionOn
    );

    if (subspanOptionOn) {
        verifySpanNameAndTags(
            findSpringRestTemplateSpanFromCompletedSpans(false),
            "GET " + pathTemplateForTags,
            "GET",
            ENDPOINT_PATH,
            fullRequestUrl,
            pathTemplateForTags,
            response.getStatusCode().value(),
            "spring.resttemplate"
        );
    }

    if (parent != null) {
        parent.close();
    }
}
 
Example 12
Source File: SpringAsyncAndBlockingRestTemplateWithWingtipsComponentTest.java    From wingtips with Apache License 2.0 4 votes vote down vote up
@DataProvider(value = {
    "true   |   true",
    "true   |   false",
    "false  |   true",
    "false  |   false"
}, splitBy = "\\|")
@Test
public void verify_AsyncRestTemplate_with_Wingtips_interceptor_traced_correctly(
    boolean spanAlreadyExistsBeforeCall, boolean subspanOptionOn
) throws ExecutionException, InterruptedException {
    // given
    Span parent = null;
    if (spanAlreadyExistsBeforeCall) {
        parent = Tracer.getInstance().startRequestWithRootSpan("somePreexistingParentSpan");
    }

    String pathTemplateForTags = "/some/path/template/" + UUID.randomUUID().toString();

    AsyncRestTemplate asyncRestTemplateWithWingtips = WingtipsSpringUtil.createTracingEnabledAsyncRestTemplate(
        subspanOptionOn,
        ZipkinHttpTagStrategy.getDefaultInstance(),
        new SpringHttpClientTagAdapterWithHttpRouteKnowledge(pathTemplateForTags)
    );

    // We always expect at least one span to be completed as part of the call: the server span.
    //      We may or may not have a second span completed depending on the value of subspanOptionOn.
    int expectedNumSpansCompleted = (subspanOptionOn) ? 2 : 1;

    String fullRequestUrl = "http://localhost:" + SERVER_PORT + ENDPOINT_PATH + "?foo=bar";

    // when
    ListenableFuture<ResponseEntity<String>> responseFuture = asyncRestTemplateWithWingtips.exchange(
        fullRequestUrl, HttpMethod.GET, null, String.class
    );
    ResponseEntity<String> response = responseFuture.get();

    // then
    assertThat(response.getStatusCode().value()).isEqualTo(200);
    assertThat(response.getBody()).isEqualTo(ENDPOINT_PAYLOAD);
    verifySpansCompletedAndReturnedInResponse(
        response, SLEEP_TIME_MILLIS, expectedNumSpansCompleted, parent, subspanOptionOn
    );

    if (subspanOptionOn) {
        verifySpanNameAndTags(
            findSpringRestTemplateSpanFromCompletedSpans(true),
            "GET " + pathTemplateForTags,
            "GET",
            ENDPOINT_PATH,
            fullRequestUrl,
            pathTemplateForTags,
            response.getStatusCode().value(),
            "spring.asyncresttemplate"
        );
    }

    if (parent != null) {
        parent.close();
    }
}
 
Example 13
Source File: ApacheHttpClientWithWingtipsComponentTest.java    From wingtips with Apache License 2.0 4 votes vote down vote up
@DataProvider(value = {
    "true   |   true",
    "true   |   false",
    "false  |   true",
    "false  |   false"
}, splitBy = "\\|")
@Test
public void verify_HttpClient_from_WingtipsHttpClientBuilder_traced_correctly(
    boolean spanAlreadyExistsBeforeCall, boolean subspanOptionOn
) throws IOException {

    // given
    Span parent = null;
    if (spanAlreadyExistsBeforeCall) {
        parent = Tracer.getInstance().startRequestWithRootSpan("somePreexistingParentSpan");
    }

    String pathTemplateForTags = "/some/path/template/" + UUID.randomUUID().toString();

    WingtipsHttpClientBuilder builder = WingtipsHttpClientBuilder.create(
        subspanOptionOn,
        ZipkinHttpTagStrategy.getDefaultInstance(),
        new ApacheHttpClientTagAdapterWithHttpRouteKnowledge(pathTemplateForTags)
    );
    HttpClient httpClient = builder.build();

    // We always expect at least one span to be completed as part of the call: the server span.
    //      We may or may not have a second span completed depending on the value of subspanOptionOn.
    int expectedNumSpansCompleted = (subspanOptionOn) ? 2 : 1;

    String fullRequestUrl = "http://localhost:" + SERVER_PORT + ENDPOINT_PATH + "?foo=bar";

    // when
    HttpResponse response = httpClient.execute(
        new HttpGet(fullRequestUrl)
    );

    // then
    assertThat(response.getStatusLine().getStatusCode()).isEqualTo(200);
    assertThat(responsePayloadToString(response)).isEqualTo(ENDPOINT_PAYLOAD);
    verifySpansCompletedAndReturnedInResponse(
        response, SLEEP_TIME_MILLIS, expectedNumSpansCompleted, parent, subspanOptionOn
    );

    if (subspanOptionOn) {
        verifySpanNameAndTags(
            findApacheHttpClientSpanFromCompletedSpans(),
            "GET " + pathTemplateForTags,
            "GET",
            ENDPOINT_PATH,
            fullRequestUrl,
            pathTemplateForTags,
            response.getStatusLine().getStatusCode(),
            "apache.httpclient"
        );
    }

    if (parent != null) {
        parent.close();
    }
}
 
Example 14
Source File: ApacheHttpClientWithWingtipsComponentTest.java    From wingtips with Apache License 2.0 4 votes vote down vote up
@DataProvider(value = {
    "true   |   true",
    "true   |   false",
    "false  |   true",
    "false  |   false"
}, splitBy = "\\|")
@Test
public void verify_HttpClient_with_WingtipsApacheHttpClientInterceptor_traced_correctly(
    boolean spanAlreadyExistsBeforeCall, boolean subspanOptionOn
) throws IOException {

    // given
    String pathTemplateForTags = "/some/path/template/" + UUID.randomUUID().toString();

    WingtipsApacheHttpClientInterceptor interceptor = new WingtipsApacheHttpClientInterceptor(
        subspanOptionOn,
        ZipkinHttpTagStrategy.getDefaultInstance(),
        new ApacheHttpClientTagAdapterWithHttpRouteKnowledge(pathTemplateForTags)
    );

    Span parent = null;
    if (spanAlreadyExistsBeforeCall) {
        parent = Tracer.getInstance().startRequestWithRootSpan("somePreexistingParentSpan");
    }

    HttpClient httpClient = HttpClientBuilder
        .create()
        .addInterceptorFirst((HttpRequestInterceptor) interceptor)
        .addInterceptorLast((HttpResponseInterceptor) interceptor)
        .build();

    // We always expect at least one span to be completed as part of the call: the server span.
    //      We may or may not have a second span completed depending on the value of subspanOptionOn.
    int expectedNumSpansCompleted = (subspanOptionOn) ? 2 : 1;

    String fullRequestUrl = "http://localhost:" + SERVER_PORT + ENDPOINT_PATH;

    // when
    HttpResponse response = httpClient.execute(new HttpGet(fullRequestUrl));

    // then
    assertThat(response.getStatusLine().getStatusCode()).isEqualTo(200);
    assertThat(responsePayloadToString(response)).isEqualTo(ENDPOINT_PAYLOAD);
    verifySpansCompletedAndReturnedInResponse(
        response, SLEEP_TIME_MILLIS, expectedNumSpansCompleted, parent, subspanOptionOn
    );

    if (subspanOptionOn) {
        verifySpanNameAndTags(
            findApacheHttpClientSpanFromCompletedSpans(),
            "GET " + pathTemplateForTags,
            "GET",
            ENDPOINT_PATH,
            fullRequestUrl,
            pathTemplateForTags,
            response.getStatusLine().getStatusCode(),
            "apache.httpclient"
        );
    }

    if (parent != null) {
        parent.close();
    }
}