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;
}
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);
}
}
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);
}
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.
}
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);
}
Aggregations