Search in sources :

Example 1 with TracingState

use of com.nike.wingtips.util.TracingState in project riposte by Nike-Inc.

the class RiposteHandlerInternalUtil method createRequestInfoFromNettyHttpRequestAndHandleStateSetupIfNecessary.

@NotNull
RequestInfo<?> createRequestInfoFromNettyHttpRequestAndHandleStateSetupIfNecessary(@NotNull HttpRequest httpRequest, @NotNull HttpProcessingState state) {
    // If the HttpProcessingState already has a RequestInfo then we should just use that.
    RequestInfo<?> requestInfo = state.getRequestInfo();
    if (requestInfo != null) {
        return requestInfo;
    }
    // No RequestInfo has been created yet. Check for an invalid Netty HttpRequest. If it's invalid, then default
    // to RequestInfoImpl.dummyInstanceForUnknownRequests(). Otherwise, generate a new RequestInfo based on
    // the Netty HttpRequest.
    // In either case, set the RequestInfo on our HttpProcessingState.
    Throwable decoderFailureCause = getDecoderFailure(httpRequest);
    if (decoderFailureCause == null) {
        // No decoder failure (so far), so create a new RequestInfoImpl based on the Netty HttpRequest object.
        try {
            requestInfo = new RequestInfoImpl<>(httpRequest);
        } catch (Throwable t) {
            // Something couldn't be parsed properly, likely an improperly escaped URL. We'll force-set a
            // DecoderFailure on the Netty HttpRequest.
            decoderFailureCause = t;
            httpRequest.setDecoderResult(DecoderResult.failure(t));
        }
    }
    // Check for DecoderFailure again, since the new RequestInfoImpl might have blown up.
    if (decoderFailureCause != null) {
        // A decoder failure occurred, which means the original request is not valid HTTP. So we'll create a dummy
        // RequestInfo and log a warning.
        requestInfo = RequestInfoImpl.dummyInstanceForUnknownRequests();
        Throwable decoderFailureCauseForLogging = decoderFailureCause;
        // Use the current tracing state if there's one on this thread, otherwise try grabbing tracing state
        // from the HttpProcessingState.
        TracingState tracingStateForLogMsg = (Tracer.getInstance().getCurrentSpan() == null) ? new TracingState(state.getDistributedTraceStack(), state.getLoggerMdcContextMap()) : TracingState.getCurrentThreadTracingState();
        // Log a warning about this message explaining why we're using a dummy RequestInfo.
        runnableWithTracingAndMdc(() -> logger.info("The Netty HttpRequest was invalid - defaulting to a synthetic RequestInfo indicating an error. " + "This usually happens when the request cannot be decoded as a valid HTTP request " + "(i.e. bad caller).", new Exception("This exception is for logging only, to see who called this method. See this exception's " + "cause for details on the HTTP object decoder failure.", decoderFailureCauseForLogging)), tracingStateForLogMsg).run();
    }
    state.setRequestInfo(requestInfo);
    return requestInfo;
}
Also used : InvalidHttpRequestException(com.nike.riposte.server.error.exception.InvalidHttpRequestException) TracingState(com.nike.wingtips.util.TracingState) NotNull(org.jetbrains.annotations.NotNull)

Example 2 with TracingState

use of com.nike.wingtips.util.TracingState in project riposte by Nike-Inc.

the class NonblockingEndpointExecutionHandlerTest method doChannelRead_performs_endpoint_timing_span_annotations_depending_on_tracing_config.

@UseDataProvider("endpointTimingScenarioDataProvider")
@Test
public void doChannelRead_performs_endpoint_timing_span_annotations_depending_on_tracing_config(EndpointTimingScenario scenario) {
    // given
    Span spanMock = mock(Span.class);
    Tracer.getInstance().registerWithThread(new ArrayDeque<>(Collections.singleton(spanMock)));
    assertThat(Tracer.getInstance().getCurrentSpan()).isEqualTo(spanMock);
    // Internal Tracer stuff
    verify(spanMock).getTraceId();
    TracingState tracingStateForTest = TracingState.getCurrentThreadTracingState();
    doReturn(tracingStateForTest.getLeft()).when(stateMock).getDistributedTraceStack();
    doReturn(tracingStateForTest.getRight()).when(stateMock).getLoggerMdcContextMap();
    doReturn(scenario.addStartAnnotation).when(taggingStrategySpy).shouldAddEndpointStartAnnotation();
    doReturn(scenario.startAnnotationName).when(taggingStrategySpy).endpointStartAnnotationName();
    doReturn(scenario.addFinishAnnotation).when(taggingStrategySpy).shouldAddEndpointFinishAnnotation();
    doReturn(scenario.finishAnnotationName).when(taggingStrategySpy).endpointFinishAnnotationName();
    // when
    handlerSpy.doChannelRead(ctxMock, msg);
    // then
    {
        VerificationMode startAnnotationVerification = (scenario.addStartAnnotation) ? times(1) : never();
        verify(spanMock, startAnnotationVerification).addTimestampedAnnotationForCurrentTime(scenario.startAnnotationName);
        // Internal Tracer stuff
        verify(spanMock, atLeastOnce()).getTraceId();
        verifyNoMoreInteractions(spanMock);
    }
    // and when
    futureThatWillBeAttachedToSpy.complete(mock(ResponseInfo.class));
    // then
    {
        VerificationMode finishAnnotationVerification = (scenario.addFinishAnnotation) ? times(1) : never();
        verify(spanMock, finishAnnotationVerification).addTimestampedAnnotationForCurrentTime(scenario.finishAnnotationName);
        verifyNoMoreInteractions(spanMock);
    }
}
Also used : ResponseInfo(com.nike.riposte.server.http.ResponseInfo) LastOutboundMessageSendFullResponseInfo(com.nike.riposte.server.channelpipeline.message.LastOutboundMessageSendFullResponseInfo) Span(com.nike.wingtips.Span) VerificationMode(org.mockito.verification.VerificationMode) TracingState(com.nike.wingtips.util.TracingState) Test(org.junit.Test) UseDataProvider(com.tngtech.java.junit.dataprovider.UseDataProvider)

Example 3 with TracingState

use of com.nike.wingtips.util.TracingState in project riposte by Nike-Inc.

the class RiposteHandlerInternalUtilTest method createRequestInfoFromNettyHttpRequestAndHandleStateSetupIfNecessary_creates_dummy_ResultInfo_when_decoder_failure_exists.

@DataProvider(value = { "true", "false" })
@Test
public void createRequestInfoFromNettyHttpRequestAndHandleStateSetupIfNecessary_creates_dummy_ResultInfo_when_decoder_failure_exists(boolean tracingExistsOnCurrentThread) {
    // given
    Throwable decoderFailureEx = new RuntimeException("intentional exception");
    nettyRequest.setDecoderResult(DecoderResult.failure(decoderFailureEx));
    RequestInfo<?> dummyRequestInfo = RequestInfoImpl.dummyInstanceForUnknownRequests();
    assertThat(stateSpy.getRequestInfo()).isNull();
    Tracer.getInstance().startRequestWithRootSpan("foo");
    TracingState tracingState = TracingState.getCurrentThreadTracingState();
    stateSpy.setDistributedTraceStack(tracingState.spanStack);
    stateSpy.setLoggerMdcContextMap(tracingState.mdcInfo);
    if (!tracingExistsOnCurrentThread) {
        Tracer.getInstance().unregisterFromThread();
        assertThat(Tracer.getInstance().getCurrentSpan()).isNull();
    } else {
        assertThat(Tracer.getInstance().getCurrentSpan()).isNotNull();
    }
    // when
    RequestInfo<?> result = implSpy.createRequestInfoFromNettyHttpRequestAndHandleStateSetupIfNecessary(nettyRequest, stateSpy);
    // then
    assertThat(result).isNotNull();
    assertThat(result.getUri()).isEqualTo(dummyRequestInfo.getUri());
    verify(stateSpy).setRequestInfo(result);
    assertThat(stateSpy.getRequestInfo()).isSameAs(result);
}
Also used : Assertions.catchThrowable(org.assertj.core.api.Assertions.catchThrowable) TracingState(com.nike.wingtips.util.TracingState) DataProvider(com.tngtech.java.junit.dataprovider.DataProvider) UseDataProvider(com.tngtech.java.junit.dataprovider.UseDataProvider) Test(org.junit.Test)

Example 4 with TracingState

use of com.nike.wingtips.util.TracingState in project riposte by Nike-Inc.

the class NonblockingEndpointExecutionHandlerTest method doChannelRead_does_not_propagate_errors_if_unexpected_exceptions_occur_during_endpoint_timing_annotations.

@Test
public void doChannelRead_does_not_propagate_errors_if_unexpected_exceptions_occur_during_endpoint_timing_annotations() {
    // given
    Span spanMock = mock(Span.class);
    Tracer.getInstance().registerWithThread(new ArrayDeque<>(Collections.singleton(spanMock)));
    assertThat(Tracer.getInstance().getCurrentSpan()).isEqualTo(spanMock);
    TracingState tracingStateForTest = TracingState.getCurrentThreadTracingState();
    doReturn(tracingStateForTest.getLeft()).when(stateMock).getDistributedTraceStack();
    doReturn(tracingStateForTest.getRight()).when(stateMock).getLoggerMdcContextMap();
    doReturn(true).when(taggingStrategySpy).shouldAddEndpointStartAnnotation();
    doThrow(new RuntimeException("intentional exception")).when(taggingStrategySpy).endpointStartAnnotationName();
    doReturn(true).when(taggingStrategySpy).shouldAddEndpointFinishAnnotation();
    doThrow(new RuntimeException("intentional exception")).when(taggingStrategySpy).endpointFinishAnnotationName();
    ResponseInfo<?> responseInfoMock = mock(ResponseInfo.class);
    // when
    handlerSpy.doChannelRead(ctxMock, msg);
    futureThatWillBeAttachedToSpy.complete(responseInfoMock);
    Object result = futureThatWillBeAttachedToSpy.join();
    // then
    verify(taggingStrategySpy).endpointStartAnnotationName();
    verify(taggingStrategySpy).endpointFinishAnnotationName();
    assertThat(result).isSameAs(responseInfoMock);
// We verified that the methods were called that would have thrown exceptions, and nothing propagated. So
// we're good.
}
Also used : Span(com.nike.wingtips.Span) TracingState(com.nike.wingtips.util.TracingState) Test(org.junit.Test)

Example 5 with TracingState

use of com.nike.wingtips.util.TracingState in project riposte by Nike-Inc.

the class ResponseSenderHandlerTest method sendResponse_adds_error_tag_to_current_span_when_response_sending_has_already_started_but_only_if_error_tag_does_not_already_exist.

@DataProvider(value = { "true   |   true", "true   |   false", "false  |   true", "false  |   false" }, splitBy = "\\|")
@Test
public void sendResponse_adds_error_tag_to_current_span_when_response_sending_has_already_started_but_only_if_error_tag_does_not_already_exist(boolean errorTagAlreadyExists, boolean exceptionHasMessage) throws JsonProcessingException {
    // given
    Object msg = new Object();
    RuntimeException expectedExceptionFromDoSendResponse = (exceptionHasMessage) ? new RuntimeException("intentional test exception") : new RuntimeException();
    doThrow(expectedExceptionFromDoSendResponse).when(handlerSpy).doSendResponse(any(), any());
    doReturn(true).when(stateMock).isResponseSendingStarted();
    Span currentSpan = Tracer.getInstance().startRequestWithRootSpan("fooSpan");
    TracingState tracingState = TracingState.getCurrentThreadTracingState();
    doReturn(tracingState.spanStack).when(stateMock).getDistributedTraceStack();
    doReturn(tracingState.mdcInfo).when(stateMock).getLoggerMdcContextMap();
    String addedErrorTagValue = (exceptionHasMessage) ? "intentional test exception" : expectedExceptionFromDoSendResponse.getClass().getSimpleName();
    String preexistingErrorTagValue = UUID.randomUUID().toString();
    if (errorTagAlreadyExists) {
        currentSpan.putTag(KnownZipkinTags.ERROR, preexistingErrorTagValue);
    }
    String expectedErrorTagValue = (errorTagAlreadyExists) ? preexistingErrorTagValue : addedErrorTagValue;
    // when
    Throwable propagatedEx = catchThrowable(() -> handlerSpy.sendResponse(ctxMock, msg, false));
    // then
    // Standard assertions for this method call.
    assertThat(propagatedEx).isSameAs(expectedExceptionFromDoSendResponse);
    verify(handlerSpy, times(1)).doSendResponse(any(), any());
    verify(stateMock).isResponseSendingStarted();
    verify(proxyStateMock).cancelRequestStreaming(expectedExceptionFromDoSendResponse, ctxMock);
    verify(proxyStateMock).cancelDownstreamRequest(expectedExceptionFromDoSendResponse);
    verify(channelMock).close();
    // What we're actually testing in this test.
    assertThat(currentSpan.getTags().get(KnownZipkinTags.ERROR)).isEqualTo(expectedErrorTagValue);
}
Also used : Assertions.catchThrowable(org.assertj.core.api.Assertions.catchThrowable) Span(com.nike.wingtips.Span) TracingState(com.nike.wingtips.util.TracingState) DataProvider(com.tngtech.java.junit.dataprovider.DataProvider) UseDataProvider(com.tngtech.java.junit.dataprovider.UseDataProvider) Test(org.junit.Test)

Aggregations

TracingState (com.nike.wingtips.util.TracingState)6 Test (org.junit.Test)4 Span (com.nike.wingtips.Span)3 UseDataProvider (com.tngtech.java.junit.dataprovider.UseDataProvider)3 DataProvider (com.tngtech.java.junit.dataprovider.DataProvider)2 Assertions.catchThrowable (org.assertj.core.api.Assertions.catchThrowable)2 LastOutboundMessageSendFullResponseInfo (com.nike.riposte.server.channelpipeline.message.LastOutboundMessageSendFullResponseInfo)1 DistributedTracingConfig (com.nike.riposte.server.config.distributedtracing.DistributedTracingConfig)1 InvalidHttpRequestException (com.nike.riposte.server.error.exception.InvalidHttpRequestException)1 HttpProcessingState (com.nike.riposte.server.http.HttpProcessingState)1 ProxyRouterProcessingState (com.nike.riposte.server.http.ProxyRouterProcessingState)1 RequestInfo (com.nike.riposte.server.http.RequestInfo)1 ResponseInfo (com.nike.riposte.server.http.ResponseInfo)1 StandardEndpoint (com.nike.riposte.server.http.StandardEndpoint)1 Channel (io.netty.channel.Channel)1 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)1 EventLoop (io.netty.channel.EventLoop)1 Attribute (io.netty.util.Attribute)1 EventExecutor (io.netty.util.concurrent.EventExecutor)1 CompletableFuture (java.util.concurrent.CompletableFuture)1