/** * Handling exceptional situations. * * @param throwable * Throwable */ private void handleThrowable(Throwable throwable) { spanStore.finishSpan(new ThrowableAwareResponseAdapter(throwable.getClass().getSimpleName())); }
@Test public void spanIsNull() { spanStore.storeSpan(null); boolean result = spanStore.finishSpan(); assertThat(result, is(false)); verifyZeroInteractions(span); }
/** * Request committed event. This is earliest place we can start a span. * * @throws IOException * IOException */ @ProxyMethod() public void onRequestCommitted() throws IOException { spanStore.startSpan(); if (null != originalListener) { WHttpEventListenerWrapper.ON_REQUEST_COMMITED.call(originalListener); } }
/** * Handles the {@link ClientRequestAdapter}. This method should be called when new client * request is created. * * @param <C> * type of carrier adapter is providing * @param requestAdapter * {@link ClientRequestAdapter} providing necessary information. * @return Created span */ public <C> SpanImpl handleAsyncRequest(AsyncClientRequestAdapter<C> requestAdapter) { SpanBuilderImpl builder = handleRequestInternal(requestAdapter); // nothing to do if builder was not created if (null == builder) { return null; } // just build the span and store it for later start SpanImpl span = builder.build(); SpanStore spanStore = new SpanStore(); spanStore.storeSpan(span); requestAdapter.getSpanStoreAdapter().setSpanStore(spanStore); // inject here as the context is created when span is started tracer.inject(span.context(), requestAdapter.getFormat(), requestAdapter.getCarrier()); return span; }
@Test public void consecutiveCalls() throws Exception { SpanStore spanStore = mock(SpanStore.class); Object[] parameters = new Object[] { spanStore }; SpanBuilderImpl builder = mock(SpanBuilderImpl.class); SpanImpl span = mock(SpanImpl.class); SpanContextImpl spanContext = mock(SpanContextImpl.class); when(span.context()).thenReturn(spanContext); when(tracer.buildSpan(null, References.FOLLOWS_FROM, true)).thenReturn(builder); when(builder.build()).thenReturn(span); when(tracer.isCurrentContextExisting()).thenReturn(true); hook.beforeBody(1L, 2L, targetObject, parameters, rsc); hook.firstAfterBody(1L, 2L, targetObject, parameters, result, false, rsc); hook.secondAfterBody(null, 1L, 2L, targetObject, parameters, spanContext, false, rsc); hook.beforeBody(1L, 2L, targetObject, parameters, rsc); hook.firstAfterBody(1L, 2L, targetObject, parameters, result, false, rsc); hook.secondAfterBody(null, 1L, 2L, targetObject, parameters, spanContext, false, rsc); verify(tracer, times(2)).buildSpan(null, References.FOLLOWS_FROM, true); verify(builder, times(2)).withTag(ExtraTags.PROPAGATION_TYPE, PropagationType.PROCESS.toString()); verify(builder, times(2)).withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER); verify(builder, times(2)).withTag(ExtraTags.INSPECTT_METHOD_ID, 1L); verify(builder, times(2)).withTag(ExtraTags.INSPECTT_SENSOR_ID, 2L); verify(builder, times(2)).build(); verify(spanStore, times(2)).storeSpan(span); verify(asyncListener, times(2)).asyncSpanContextCreated(spanContext); verifyNoMoreInteractions(tracer, builder, spanStore, asyncListener); } }
@Test public void successful() { SpanStore spanStore = new SpanStore(); Object[] parameters = new Object[] { new Object(), new Object(), httpContext, mock(FutureCallback.class) }; when(runtimeLinker.createProxy(eq(FutureCallbackProxy.class), Mockito.<FutureCallbackProxy> any(), Mockito.<ClassLoader> any())).thenReturn(futureCallback); when(httpContext.getAttribute(SpanStoreAdapter.Constants.ID)).thenReturn(spanStore); ArgumentCaptor<FutureCallbackProxy> proxyCaptor = ArgumentCaptor.forClass(FutureCallbackProxy.class); Object result = hook.beforeBody(METHOD_ID, object, parameters, ssc); verify(runtimeLinker).createProxy(eq(FutureCallbackProxy.class), proxyCaptor.capture(), Mockito.<ClassLoader> any()); verifyNoMoreInteractions(runtimeLinker, httpContext); verifyZeroInteractions(ssc, object, futureCallback, httpContext); assertThat(result, is(nullValue())); assertThat(parameters[3], is(theInstance((Object) futureCallback))); }
@Test public void propagationNull() { when(requestAdapter.startClientSpan()).thenReturn(true); when(requestAdapter.getPropagationType()).thenReturn(null); when(requestAdapter.getReferenceType()).thenReturn(References.FOLLOWS_FROM); SpanImpl result = interceptor.handleAsyncRequest(requestAdapter); assertThat(result, is(span)); verify(tracer).buildSpan(null, References.FOLLOWS_FROM, true); verify(tracer).inject(context, Format.Builtin.TEXT_MAP, carrier); verify(spanBuilder).withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT); verify(spanBuilder).build(); verify(span).context(); ArgumentCaptor<SpanStore> spanStoreCaptor = ArgumentCaptor.forClass(SpanStore.class); verify(spanStoreAdapter).setSpanStore(spanStoreCaptor.capture()); assertThat(spanStoreCaptor.getValue().getSpan(), is(span)); verifyNoMoreInteractions(tracer, spanBuilder, span); verifyZeroInteractions(context); } }
@Test public void tagsSpanIsNull() { when(adapter.getTags()).thenReturn(Collections.singletonMap("key", "value")); spanStore.storeSpan(null); boolean result = spanStore.finishSpan(adapter); assertThat(result, is(false)); verifyZeroInteractions(span); } }
/** * {@inheritDoc} */ @Override public void beforeBody(long methodId, long sensorTypeId, Object object, Object[] parameters, RegisteredSensorConfig rsc) { Object httpContext = REFLECTION_CACHE.getField(object.getClass(), "localContext", object, null); if (httpContext != null) { SpanStoreAdapter spanStoreAdapter = new ApacheHttpContextSpanStoreAdapter(httpContext); SpanStore spanStore = spanStoreAdapter.getSpanStore(); if (spanStore != null) { spanStore.startSpan(); } } }
@Test public void successful() throws Exception { SpanStore spanStore = mock(SpanStore.class); Object[] parameters = new Object[] { spanStore }; SpanBuilderImpl builder = mock(SpanBuilderImpl.class); SpanImpl span = mock(SpanImpl.class); SpanContextImpl spanContext = mock(SpanContextImpl.class); when(span.context()).thenReturn(spanContext); when(tracer.buildSpan(null, References.FOLLOWS_FROM, true)).thenReturn(builder); when(builder.build()).thenReturn(span); when(tracer.isCurrentContextExisting()).thenReturn(true); hook.beforeBody(1L, 2L, targetObject, parameters, rsc); hook.firstAfterBody(1L, 2L, targetObject, parameters, result, false, rsc); hook.secondAfterBody(null, 1L, 2L, targetObject, parameters, spanContext, false, rsc); verify(tracer).buildSpan(null, References.FOLLOWS_FROM, true); verify(builder).withTag(ExtraTags.PROPAGATION_TYPE, PropagationType.PROCESS.toString()); verify(builder).withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER); verify(builder).withTag(ExtraTags.INSPECTT_METHOD_ID, 1L); verify(builder).withTag(ExtraTags.INSPECTT_SENSOR_ID, 2L); verify(builder).build(); verify(spanStore).storeSpan(span); verify(asyncListener).asyncSpanContextCreated(spanContext); verifyNoMoreInteractions(tracer, builder, spanStore, asyncListener); }
@Test public void tagsNull() { when(requestAdapter.startClientSpan()).thenReturn(true); when(requestAdapter.getTags()).thenReturn(null); when(requestAdapter.getPropagationType()).thenReturn(PropagationType.HTTP); when(requestAdapter.getReferenceType()).thenReturn(References.FOLLOWS_FROM); SpanImpl result = interceptor.handleAsyncRequest(requestAdapter); assertThat(result, is(span)); verify(tracer).buildSpan(null, References.FOLLOWS_FROM, true); verify(tracer).inject(context, Format.Builtin.TEXT_MAP, carrier); verify(spanBuilder).withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT); verify(spanBuilder).withTag(ExtraTags.PROPAGATION_TYPE, PropagationType.HTTP.toString()); verify(spanBuilder).build(); verify(span).context(); ArgumentCaptor<SpanStore> spanStoreCaptor = ArgumentCaptor.forClass(SpanStore.class); verify(spanStoreAdapter).setSpanStore(spanStoreCaptor.capture()); assertThat(spanStoreCaptor.getValue().getSpan(), is(span)); verifyNoMoreInteractions(tracer, spanBuilder, span); verifyZeroInteractions(context); }
/** * Failed method of FutureCallback. * * @param exception * Exception thrown when the request failed. */ @ProxyMethod(parameterTypes = { "java.lang.Exception" }) public void failed(Object exception) { try { SpanStore spanStore = spanStoreAdapter.getSpanStore(); if (spanStore != null) { spanStore.finishSpan(new ThrowableAwareResponseAdapter(exception.getClass().getSimpleName())); } } finally { if (originalCallback != null) { WFutureCallback.failed.callSafe(originalCallback, exception); } } }
@Test public void happyPath() throws IOException { proxy.onRequestCommitted(); verify(spanStore).startSpan(); } }
@Test public void nestedCalls() throws Exception { SpanStore spanStore = mock(SpanStore.class); Object[] parameters = new Object[] { spanStore }; SpanBuilderImpl builder = mock(SpanBuilderImpl.class); SpanImpl span = mock(SpanImpl.class); SpanContextImpl spanContext = mock(SpanContextImpl.class); when(span.context()).thenReturn(spanContext); when(tracer.buildSpan(null, References.FOLLOWS_FROM, true)).thenReturn(builder); when(builder.build()).thenReturn(span); when(tracer.isCurrentContextExisting()).thenReturn(true); hook.beforeBody(1L, 2L, targetObject, parameters, rsc); hook.beforeBody(1L, 2L, targetObject, parameters, rsc); hook.firstAfterBody(1L, 2L, targetObject, parameters, result, false, rsc); hook.secondAfterBody(null, 1L, 2L, targetObject, parameters, spanContext, false, rsc); hook.firstAfterBody(1L, 2L, targetObject, parameters, result, false, rsc); hook.secondAfterBody(null, 1L, 2L, targetObject, parameters, spanContext, false, rsc); verify(tracer).buildSpan(null, References.FOLLOWS_FROM, true); verify(builder).withTag(ExtraTags.PROPAGATION_TYPE, PropagationType.PROCESS.toString()); verify(builder).withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER); verify(builder).withTag(ExtraTags.INSPECTT_METHOD_ID, 1L); verify(builder).withTag(ExtraTags.INSPECTT_SENSOR_ID, 2L); verify(builder).build(); verify(spanStore).storeSpan(span); verify(asyncListener).asyncSpanContextCreated(spanContext); verifyNoMoreInteractions(tracer, builder, spanStore, asyncListener); }
@Test public void happyPath() { when(requestAdapter.startClientSpan()).thenReturn(true); when(requestAdapter.getTags()).thenReturn(Collections.<String, String> singletonMap(Tags.HTTP_URL.getKey(), "value")); when(requestAdapter.getPropagationType()).thenReturn(PropagationType.HTTP); when(requestAdapter.getReferenceType()).thenReturn(References.FOLLOWS_FROM); SpanImpl result = interceptor.handleAsyncRequest(requestAdapter); assertThat(result, is(span)); verify(tracer).buildSpan(null, References.FOLLOWS_FROM, true); verify(tracer).inject(context, Format.Builtin.TEXT_MAP, carrier); verify(spanBuilder).withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT); verify(spanBuilder).withTag(ExtraTags.PROPAGATION_TYPE, PropagationType.HTTP.toString()); verify(spanBuilder).withTag(Tags.HTTP_URL.getKey(), "value"); verify(spanBuilder).build(); verify(span).context(); ArgumentCaptor<SpanStore> spanStoreCaptor = ArgumentCaptor.forClass(SpanStore.class); verify(spanStoreAdapter).setSpanStore(spanStoreCaptor.capture()); assertThat(spanStoreCaptor.getValue().getSpan(), is(span)); verifyNoMoreInteractions(tracer, spanBuilder, span); verifyZeroInteractions(context); }
/** * Response complete event. We can finish span here. * * @throws IOException * IOException */ @ProxyMethod public void onResponseComplete() throws IOException { spanStore.finishSpan(new HttpResponseAdapter(this)); if (null != originalListener) { WHttpEventListenerWrapper.ON_RESPONSE_COMPLETE.call(originalListener); } }
@Test public void alreadyStarted() { when(span.isStarted()).thenReturn(true); boolean result = spanStore.startSpan(); assertThat(result, is(false)); verify(span).isStarted(); verifyNoMoreInteractions(span); }
/** * {@inheritDoc} */ @Override public void beforeBody(long methodId, long sensorTypeId, Object object, Object[] parameters, RegisteredSensorConfig rsc) { if (!REF_MARKER.isMarkerSet()) { if ((parameters.length > 0) && (parameters[0] instanceof SpanStore)) { SpanBuilderImpl builder = tracer.buildSpan(null, References.FOLLOWS_FROM, true); builder.withTag(ExtraTags.PROPAGATION_TYPE, PropagationType.PROCESS.toString()); builder.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER); builder.withTag(ExtraTags.INSPECTT_METHOD_ID, methodId); builder.withTag(ExtraTags.INSPECTT_SENSOR_ID, sensorTypeId); SpanImpl span = builder.build(); SpanStore spanStore = (SpanStore) parameters[0]; spanStore.storeSpan(span); asyncSpanContextListener.asyncSpanContextCreated(span.context()); } } REF_MARKER.markCall(); }
@Test public void tagsAlreadyFinished() { when(adapter.getTags()).thenReturn(Collections.singletonMap("key", "value")); when(span.isFinished()).thenReturn(true); boolean result = spanStore.finishSpan(adapter); assertThat(result, is(false)); verify(span).isFinished(); verifyNoMoreInteractions(span); }