@Override public void onSuccess(ClientHttpResponse result) { finishCallSpan(result, null); }
@Override public ClientHttpResponse intercept( HttpRequest request, byte[] body, ClientHttpRequestExecution execution ) throws IOException { // We need to wrap the request with HttpRequestWrapperWithModifiableHeaders so that tracing info can be // propagated on the headers. HttpRequestWrapperWithModifiableHeaders wrapperRequest = new HttpRequestWrapperWithModifiableHeaders(request); if (surroundCallsWithSubspan) { return createNewSpanAndExecuteRequest(wrapperRequest, body, execution); } return propagateTracingHeadersAndExecuteRequest(wrapperRequest, body, execution); }
@Override @SuppressWarnings("deprecation") public ListenableFuture<ClientHttpResponse> intercept( HttpRequest request, byte[] body, AsyncClientHttpRequestExecution execution ) throws IOException { // We need to wrap the request with HttpRequestWrapperWithModifiableHeaders so that tracing info can be // propagated on the headers. HttpRequestWrapperWithModifiableHeaders wrapperRequest = new HttpRequestWrapperWithModifiableHeaders(request); if (surroundCallsWithSubspan) { return createAsyncSubSpanAndExecute(wrapperRequest, body, execution); } return propagateTracingHeadersAndExecute(wrapperRequest, body, execution); }
@Test public void SpanAroundAsyncCallFinisher_finishCallSpan_does_nothing_if_spanAroundCallTracingState_is_null() { // given SpanAroundAsyncCallFinisher finisherSpy = spy(new SpanAroundAsyncCallFinisher( null, requestMock, tagAndNamingStrategy, tagAndNamingAdapterMock )); ClientHttpResponse responseMock = mock(ClientHttpResponse.class); Throwable errorMock = mock(Throwable.class); // when finisherSpy.finishCallSpan(responseMock, errorMock); // then verify(finisherSpy).finishCallSpan(responseMock, errorMock); verifyNoMoreInteractions(finisherSpy); verifyZeroInteractions(responseMock, errorMock); } }
@Test public void default_constructor_creates_instance_with_subspan_option_on() { // when WingtipsAsyncClientHttpRequestInterceptor interceptor = new WingtipsAsyncClientHttpRequestInterceptor(); // then assertThat(interceptor.surroundCallsWithSubspan).isTrue(); assertThat(interceptor.tagAndNamingStrategy).isSameAs(ZipkinHttpTagStrategy.getDefaultInstance()); assertThat(interceptor.tagAndNamingAdapter).isSameAs(SpringHttpClientTagAdapter.getDefaultInstance()); }
/** * @param surroundCallsWithSubspan Pass in true to have the returned {@link RestTemplate} surround all calls with * a subspan and propagate the subspan's tracing info, or false to have only the current span propagated at the * time of the call (no subspan). * @return A new {@link RestTemplate} instance with a {@link WingtipsClientHttpRequestInterceptor} already added * and with the subspan option on or off depending on the value of the {@code surroundCallsWithSubspan} argument, * and using the default {@link HttpTagAndSpanNamingStrategy} and {@link HttpTagAndSpanNamingAdapter} * ({@link ZipkinHttpTagStrategy} and {@link SpringHttpClientTagAdapter}). */ public static RestTemplate createTracingEnabledRestTemplate(boolean surroundCallsWithSubspan) { RestTemplate restTemplate = new RestTemplate(); restTemplate.getInterceptors().add( new WingtipsClientHttpRequestInterceptor(surroundCallsWithSubspan) ); return restTemplate; }
/** * @param surroundCallsWithSubspan Pass in true to have the returned {@link AsyncRestTemplate} surround all calls * with a subspan and propagate the subspan's tracing info, or false to have only the current span propagated at * the time of the call (no subspan). * @return A new {@link AsyncRestTemplate} instance with a {@link WingtipsAsyncClientHttpRequestInterceptor} * already added and with the subspan option on or off depending on the value of the {@code * surroundCallsWithSubspan} argument, and using the default {@link HttpTagAndSpanNamingStrategy} and * {@link HttpTagAndSpanNamingAdapter} ({@link ZipkinHttpTagStrategy} and {@link SpringHttpClientTagAdapter}). */ public static AsyncRestTemplate createTracingEnabledAsyncRestTemplate(boolean surroundCallsWithSubspan) { AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate(); asyncRestTemplate.getInterceptors().add( new WingtipsAsyncClientHttpRequestInterceptor(surroundCallsWithSubspan) ); return asyncRestTemplate; }
@Override @SuppressWarnings("deprecation") public ListenableFuture<ClientHttpResponse> intercept( HttpRequest request, byte[] body, AsyncClientHttpRequestExecution execution ) throws IOException { // We need to wrap the request with HttpRequestWrapperWithModifiableHeaders so that tracing info can be // propagated on the headers. HttpRequestWrapperWithModifiableHeaders wrapperRequest = new HttpRequestWrapperWithModifiableHeaders(request); if (surroundCallsWithSubspan) { return createAsyncSubSpanAndExecute(wrapperRequest, body, execution); } return propagateTracingHeadersAndExecute(wrapperRequest, body, execution); }
/** * @param surroundCallsWithSubspan Pass in true to have the returned {@link RestTemplate} surround all calls with * a subspan and propagate the subspan's tracing info, or false to have only the current span propagated at the * time of the call (no subspan). * @return A new {@link RestTemplate} instance with a {@link WingtipsClientHttpRequestInterceptor} already added * and with the subspan option on or off depending on the value of the {@code surroundCallsWithSubspan} argument, * and using the default {@link HttpTagAndSpanNamingStrategy} and {@link HttpTagAndSpanNamingAdapter} * ({@link ZipkinHttpTagStrategy} and {@link SpringHttpClientTagAdapter}). */ public static RestTemplate createTracingEnabledRestTemplate(boolean surroundCallsWithSubspan) { RestTemplate restTemplate = new RestTemplate(); restTemplate.getInterceptors().add( new WingtipsClientHttpRequestInterceptor(surroundCallsWithSubspan) ); return restTemplate; }
/** * @param surroundCallsWithSubspan Pass in true to have the returned {@link AsyncRestTemplate} surround all calls * with a subspan and propagate the subspan's tracing info, or false to have only the current span propagated at * the time of the call (no subspan). * @return A new {@link AsyncRestTemplate} instance with a {@link WingtipsAsyncClientHttpRequestInterceptor} * already added and with the subspan option on or off depending on the value of the {@code * surroundCallsWithSubspan} argument, and using the default {@link HttpTagAndSpanNamingStrategy} and * {@link HttpTagAndSpanNamingAdapter} ({@link ZipkinHttpTagStrategy} and {@link SpringHttpClientTagAdapter}). */ public static AsyncRestTemplate createTracingEnabledAsyncRestTemplate(boolean surroundCallsWithSubspan) { AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate(); asyncRestTemplate.getInterceptors().add( new WingtipsAsyncClientHttpRequestInterceptor(surroundCallsWithSubspan) ); return asyncRestTemplate; }
@Override public void onFailure(Throwable ex) { finishCallSpan(null, ex); }
@Override public ClientHttpResponse intercept( HttpRequest request, byte[] body, ClientHttpRequestExecution execution ) throws IOException { // We need to wrap the request with HttpRequestWrapperWithModifiableHeaders so that tracing info can be // propagated on the headers. HttpRequestWrapperWithModifiableHeaders wrapperRequest = new HttpRequestWrapperWithModifiableHeaders(request); if (surroundCallsWithSubspan) { return createNewSpanAndExecuteRequest(wrapperRequest, body, execution); } return propagateTracingHeadersAndExecuteRequest(wrapperRequest, body, execution); }
/** * @param tagAndNamingStrategy The span tag and naming strategy to use - cannot be null. If you really want no * tag and naming strategy, then pass in {@link NoOpHttpTagStrategy#getDefaultInstance()}. * @param tagAndNamingAdapter The tag and naming adapter to use - cannot be null. If you really want no tag and * naming adapter, then pass in {@link NoOpHttpTagAdapter#getDefaultInstance()}. * @return A new {@link RestTemplate} instance with a {@link WingtipsClientHttpRequestInterceptor} * already added, and with the subspan option and tag/naming strategy and adapter set to the given arguments. */ public static RestTemplate createTracingEnabledRestTemplate( boolean surroundCallsWithSubspan, HttpTagAndSpanNamingStrategy<HttpRequest, ClientHttpResponse> tagAndNamingStrategy, HttpTagAndSpanNamingAdapter<HttpRequest, ClientHttpResponse> tagAndNamingAdapter ) { RestTemplate restTemplate = new RestTemplate(); restTemplate.getInterceptors().add( new WingtipsClientHttpRequestInterceptor( surroundCallsWithSubspan, tagAndNamingStrategy, tagAndNamingAdapter ) ); return restTemplate; }
/** * @param tagAndNamingStrategy The span tag and naming strategy to use - cannot be null. If you really want no * tag and naming strategy, then pass in {@link NoOpHttpTagStrategy#getDefaultInstance()}. * @param tagAndNamingAdapter The tag and naming adapter to use - cannot be null. If you really want no tag and * naming adapter, then pass in {@link NoOpHttpTagAdapter#getDefaultInstance()}. * @return A new {@link AsyncRestTemplate} instance with a {@link WingtipsAsyncClientHttpRequestInterceptor} * already added, and with the subspan option and tag/naming strategy and adapter set to the given arguments. */ public static AsyncRestTemplate createTracingEnabledAsyncRestTemplate( boolean surroundCallsWithSubspan, HttpTagAndSpanNamingStrategy<HttpRequest, ClientHttpResponse> tagAndNamingStrategy, HttpTagAndSpanNamingAdapter<HttpRequest, ClientHttpResponse> tagAndNamingAdapter ) { AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate(); asyncRestTemplate.getInterceptors().add( new WingtipsAsyncClientHttpRequestInterceptor( surroundCallsWithSubspan, tagAndNamingStrategy, tagAndNamingAdapter ) ); return asyncRestTemplate; }
@Override public void onSuccess(ClientHttpResponse result) { finishCallSpan(result, null); }
/** * @param tagAndNamingStrategy The span tag and naming strategy to use - cannot be null. If you really want no * tag and naming strategy, then pass in {@link NoOpHttpTagStrategy#getDefaultInstance()}. * @param tagAndNamingAdapter The tag and naming adapter to use - cannot be null. If you really want no tag and * naming adapter, then pass in {@link NoOpHttpTagAdapter#getDefaultInstance()}. * @return A new {@link RestTemplate} instance with a {@link WingtipsClientHttpRequestInterceptor} * already added, and with the subspan option and tag/naming strategy and adapter set to the given arguments. */ public static RestTemplate createTracingEnabledRestTemplate( boolean surroundCallsWithSubspan, HttpTagAndSpanNamingStrategy<HttpRequest, ClientHttpResponse> tagAndNamingStrategy, HttpTagAndSpanNamingAdapter<HttpRequest, ClientHttpResponse> tagAndNamingAdapter ) { RestTemplate restTemplate = new RestTemplate(); restTemplate.getInterceptors().add( new WingtipsClientHttpRequestInterceptor( surroundCallsWithSubspan, tagAndNamingStrategy, tagAndNamingAdapter ) ); return restTemplate; }
/** * @param tagAndNamingStrategy The span tag and naming strategy to use - cannot be null. If you really want no * tag and naming strategy, then pass in {@link NoOpHttpTagStrategy#getDefaultInstance()}. * @param tagAndNamingAdapter The tag and naming adapter to use - cannot be null. If you really want no tag and * naming adapter, then pass in {@link NoOpHttpTagAdapter#getDefaultInstance()}. * @return A new {@link AsyncRestTemplate} instance with a {@link WingtipsAsyncClientHttpRequestInterceptor} * already added, and with the subspan option and tag/naming strategy and adapter set to the given arguments. */ public static AsyncRestTemplate createTracingEnabledAsyncRestTemplate( boolean surroundCallsWithSubspan, HttpTagAndSpanNamingStrategy<HttpRequest, ClientHttpResponse> tagAndNamingStrategy, HttpTagAndSpanNamingAdapter<HttpRequest, ClientHttpResponse> tagAndNamingAdapter ) { AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate(); asyncRestTemplate.getInterceptors().add( new WingtipsAsyncClientHttpRequestInterceptor( surroundCallsWithSubspan, tagAndNamingStrategy, tagAndNamingAdapter ) ); return asyncRestTemplate; }
@Override public void onFailure(Throwable ex) { finishCallSpan(null, ex); }
@DataProvider(value = { "NULL_STRATEGY_ARG", "NULL_ADAPTER_ARG" }) @Test public void constructor_with_tag_and_span_naming_args_throws_IllegalArgumentException_if_passed_null_args( NullConstructorArgsScenario scenario ) { // when Throwable ex = catchThrowable( () -> new WingtipsClientHttpRequestInterceptor(true, scenario.strategy, scenario.adapter) ); // then assertThat(ex) .isInstanceOf(IllegalArgumentException.class) .hasMessage(scenario.expectedExceptionMessage); }
@DataProvider(value = { "NULL_STRATEGY_ARG", "NULL_ADAPTER_ARG" }) @Test public void constructor_with_tag_and_span_naming_args_throws_IllegalArgumentException_if_passed_null_args( NullConstructorArgsScenario scenario ) { // when Throwable ex = catchThrowable( () -> new WingtipsAsyncClientHttpRequestInterceptor(true, scenario.strategy, scenario.adapter) ); // then assertThat(ex) .isInstanceOf(IllegalArgumentException.class) .hasMessage(scenario.expectedExceptionMessage); }