From 1edc98bbc323f4bd7d9e3de8d1fff3018d937e2a Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Thu, 18 Oct 2018 12:06:28 +0800 Subject: [PATCH 1/3] Bumps to latest brave Notably, this fixes a bug in b3 single propagation when 128bit trace IDs are in use. --- pom.xml | 2 +- spring-cloud-sleuth-dependencies/pom.xml | 2 +- spring-cloud-sleuth-samples/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index b3db0928f..3bf35c217 100644 --- a/pom.xml +++ b/pom.xml @@ -273,7 +273,7 @@ Elmhurst.BUILD-SNAPSHOT 2.0.0.BUILD-SNAPSHOT 2.0.0.BUILD-SNAPSHOT - 5.4.2 + 5.4.3 2.0.0.RELEASE diff --git a/spring-cloud-sleuth-dependencies/pom.xml b/spring-cloud-sleuth-dependencies/pom.xml index 6e644a35a..ec1706c40 100644 --- a/spring-cloud-sleuth-dependencies/pom.xml +++ b/spring-cloud-sleuth-dependencies/pom.xml @@ -30,7 +30,7 @@ spring-cloud-sleuth-dependencies Spring Cloud Sleuth Dependencies - 0.33.3 + 0.33.4 diff --git a/spring-cloud-sleuth-samples/pom.xml b/spring-cloud-sleuth-samples/pom.xml index 8ecd671b6..2f9a9b77d 100644 --- a/spring-cloud-sleuth-samples/pom.xml +++ b/spring-cloud-sleuth-samples/pom.xml @@ -73,7 +73,7 @@ io.zipkin.zipkin2 zipkin - 2.11.6 + 2.11.7 From abccdf7b418edff19b56b4807b575130c95a501e Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 19 Oct 2018 11:43:17 +0200 Subject: [PATCH 2/3] Added back support for proxying of ExecutorService; fixes gh-1107 --- .../async/ExecutorBeanPostProcessor.java | 115 ++++++++++---- .../async/ExecutorBeanPostProcessorTests.java | 148 ++++++++++++++++-- 2 files changed, 218 insertions(+), 45 deletions(-) diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/ExecutorBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/ExecutorBeanPostProcessor.java index 904455a41..ab61452d2 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/ExecutorBeanPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/ExecutorBeanPostProcessor.java @@ -20,11 +20,15 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.function.Supplier; +import org.aopalliance.aop.Advice; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.aop.framework.AopConfigException; import org.springframework.aop.framework.ProxyFactoryBean; import org.springframework.beans.BeansException; @@ -63,50 +67,97 @@ class ExecutorBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof Executor && !(bean instanceof ThreadPoolTaskExecutor)) { - Method execute = ReflectionUtils.findMethod(bean.getClass(), "execute", Runnable.class); - boolean methodFinal = Modifier.isFinal(execute.getModifiers()); - boolean classFinal = Modifier.isFinal(bean.getClass().getModifiers()); - boolean cglibProxy = !methodFinal && !classFinal; - Executor executor = (Executor) bean; - try { - return createProxy(bean, cglibProxy, executor); - } catch (AopConfigException e) { - if (cglibProxy) { - if (log.isDebugEnabled()) { - log.debug("Exception occurred while trying to create a proxy, falling back to JDK proxy", e); - } - return createProxy(bean, false, executor); - } - throw e; - } - } else if (bean instanceof ThreadPoolTaskExecutor) { - boolean classFinal = Modifier.isFinal(bean.getClass().getModifiers()); - boolean cglibProxy = !classFinal; - ThreadPoolTaskExecutor executor = (ThreadPoolTaskExecutor) bean; - return createThreadPoolTaskExecutorProxy(bean, cglibProxy, executor); + if (bean instanceof ThreadPoolTaskExecutor) { + return wrapThreadPoolTaskExecutor(bean); + } else if (bean instanceof ExecutorService) { + return wrapExecutorService(bean); + } else if (bean instanceof Executor) { + return wrapExecutor(bean); } return bean; } + private Object wrapExecutor(Object bean) { + Method execute = ReflectionUtils.findMethod(bean.getClass(), "execute", + Runnable.class); + boolean methodFinal = Modifier.isFinal(execute.getModifiers()); + boolean classFinal = Modifier.isFinal(bean.getClass().getModifiers()); + boolean cglibProxy = !methodFinal && !classFinal; + Executor executor = (Executor) bean; + try { + return createProxy(bean, cglibProxy, + new ExecutorMethodInterceptor(executor, this.beanFactory)); + } + catch (AopConfigException ex) { + if (cglibProxy) { + if (log.isDebugEnabled()) { + log.debug( + "Exception occurred while trying to create a proxy, falling back to JDK proxy", + ex); + } + return createProxy(bean, false, new ExecutorMethodInterceptor(executor, this.beanFactory)); + } + throw ex; + } + } + + private Object wrapThreadPoolTaskExecutor(Object bean) { + boolean classFinal = Modifier.isFinal(bean.getClass().getModifiers()); + boolean cglibProxy = !classFinal; + ThreadPoolTaskExecutor executor = (ThreadPoolTaskExecutor) bean; + return createThreadPoolTaskExecutorProxy(bean, cglibProxy, executor); + } + + private Object wrapExecutorService(Object bean) { + boolean classFinal = Modifier.isFinal(bean.getClass().getModifiers()); + boolean cglibProxy = !classFinal; + ExecutorService executor = (ExecutorService) bean; + return createExecutorServiceProxy(bean, cglibProxy, executor); + } + Object createThreadPoolTaskExecutorProxy(Object bean, boolean cglibProxy, ThreadPoolTaskExecutor executor) { + return getProxiedObject(bean, cglibProxy, executor, + () -> new LazyTraceThreadPoolTaskExecutor(this.beanFactory, executor)); + } + + Object createExecutorServiceProxy(Object bean, boolean cglibProxy, + ExecutorService executor) { + return getProxiedObject(bean, cglibProxy, executor, + () -> new TraceableExecutorService(this.beanFactory, executor)); + } + + private Object getProxiedObject(Object bean, boolean cglibProxy, Executor executor, + Supplier supplier) { ProxyFactoryBean factory = new ProxyFactoryBean(); factory.setProxyTargetClass(cglibProxy); - factory.addAdvice(new ExecutorMethodInterceptor(executor, this.beanFactory) { - @Override Executor executor(BeanFactory beanFactory, ThreadPoolTaskExecutor executor) { - return new LazyTraceThreadPoolTaskExecutor(beanFactory, executor); + factory.addAdvice(new ExecutorMethodInterceptor(executor, + this.beanFactory) { + @Override + T executor(BeanFactory beanFactory, T executor) { + return (T) supplier.get(); } }); factory.setTarget(bean); + try { + return getObject(factory); + } catch (Exception e) { + if (log.isDebugEnabled()) { + log.debug("Exception occurred while trying to get a proxy. Will fallback to a different implementation", e); + } + return supplier.get(); + } + } + + Object getObject(ProxyFactoryBean factory) { return factory.getObject(); } @SuppressWarnings("unchecked") - Object createProxy(Object bean, boolean cglibProxy, Executor executor) { + Object createProxy(Object bean, boolean cglibProxy, Advice advice) { ProxyFactoryBean factory = new ProxyFactoryBean(); factory.setProxyTargetClass(cglibProxy); - factory.addAdvice(new ExecutorMethodInterceptor(executor, this.beanFactory)); + factory.addAdvice(advice); factory.setTarget(bean); return factory.getObject(); } @@ -122,9 +173,9 @@ class ExecutorMethodInterceptor implements MethodInterceptor this.beanFactory = beanFactory; } - @Override public Object invoke(MethodInvocation invocation) - throws Throwable { - Executor executor = executor(this.beanFactory, this.delegate); + @Override + public Object invoke(MethodInvocation invocation) throws Throwable { + T executor = executor(this.beanFactory, this.delegate); Method methodOnTracedBean = getMethod(invocation, executor); if (methodOnTracedBean != null) { try { @@ -144,7 +195,7 @@ class ExecutorMethodInterceptor implements MethodInterceptor .findMethod(object.getClass(), method.getName(), method.getParameterTypes()); } - Executor executor(BeanFactory beanFactory, T executor) { - return new LazyTraceExecutor(beanFactory, executor); + T executor(BeanFactory beanFactory, T executor) { + return (T) new LazyTraceExecutor(beanFactory, executor); } } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/ExecutorBeanPostProcessorTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/ExecutorBeanPostProcessorTests.java index 283c4ba73..d1b937d72 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/ExecutorBeanPostProcessorTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/ExecutorBeanPostProcessorTests.java @@ -16,19 +16,38 @@ package org.springframework.cloud.sleuth.instrument.async; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import brave.Tracer; import brave.Tracing; +import org.aopalliance.aop.Advice; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.BDDMockito; +import org.mockito.BDDMockito; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.aop.framework.AopConfigException; +import org.springframework.aop.framework.ProxyFactoryBean; +import org.springframework.aop.framework.ProxyFactoryBean; import org.springframework.beans.factory.BeanFactory; import org.springframework.cloud.sleuth.DefaultSpanNamer; import org.springframework.cloud.sleuth.SpanNamer; @@ -45,7 +64,23 @@ import static org.assertj.core.api.BDDAssertions.thenThrownBy; @RunWith(MockitoJUnitRunner.class) public class ExecutorBeanPostProcessorTests { - @Mock BeanFactory beanFactory; + @Mock + BeanFactory beanFactory; + Tracing tracing = Tracing.newBuilder().build(); + + + @Before + public void setup() { + Mockito.when(beanFactory.getBean(Tracing.class)) + .thenReturn(this.tracing); + Mockito.when(beanFactory.getBean(SpanNamer.class)) + .thenReturn(new DefaultSpanNamer()); + } + + @After + public void clear() { + this.tracing.close(); + } @Test public void should_create_a_cglib_proxy_by_default() throws Exception { @@ -63,30 +98,32 @@ public class ExecutorBeanPostProcessorTests { } @Test - public void should_create_jdk_proxy_when_cglib_fails_to_be_done() throws Exception { + public void should_fallback_to_sleuth_implementation_when_cglib_cannot_be_created() throws Exception { ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); Object o = new ExecutorBeanPostProcessor(this.beanFactory) .postProcessAfterInitialization(service, "foo"); - then(o).isInstanceOf(ScheduledExecutorService.class); - then(ClassUtils.isCglibProxy(o)).isFalse(); + then(o).isInstanceOf(TraceableExecutorService.class); service.shutdown(); } @Test - public void should_throw_exception_when_it_is_not_possible_to_create_any_proxy() throws Exception { + public void should_fallback_to_default_implementation_when_exception_thrown() + throws Exception { ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); ExecutorBeanPostProcessor bpp = new ExecutorBeanPostProcessor(this.beanFactory) { - @Override Object createProxy(Object bean, boolean cglibProxy, - Executor executor) { + + @Override + Object createProxy(Object bean, boolean cglibProxy, Advice advice) { throw new AopConfigException("foo"); } + }; - thenThrownBy(() -> bpp.postProcessAfterInitialization(service, "foo")) - .isInstanceOf(AopConfigException.class) - .hasMessage("foo"); + Object wrappedService = bpp.postProcessAfterInitialization(service, "foo"); + + then(wrappedService).isInstanceOf(TraceableExecutorService.class); service.shutdown(); } @@ -103,7 +140,8 @@ public class ExecutorBeanPostProcessorTests { } @Test - public void should_throw_exception_when_it_is_not_possible_to_create_any_proxyfor_ThreadPoolTaskExecutor() throws Exception { + public void should_throw_exception_when_it_is_not_possible_to_create_any_proxy_for_ThreadPoolTaskExecutor() + throws Exception { ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); ExecutorBeanPostProcessor bpp = new ExecutorBeanPostProcessor(this.beanFactory) { @Override Object createThreadPoolTaskExecutorProxy(Object bean, boolean cglibProxy, @@ -113,8 +151,92 @@ public class ExecutorBeanPostProcessorTests { }; thenThrownBy(() -> bpp.postProcessAfterInitialization(taskExecutor, "foo")) - .isInstanceOf(AopConfigException.class) - .hasMessage("foo"); + .isInstanceOf(AopConfigException.class).hasMessage("foo"); + } + + @Test + public void should_fallback_to_sleuth_impl_when_it_is_not_possible_to_create_any_proxy_for_ExecutorService() + throws Exception { + ExecutorService service = BDDMockito.mock(ExecutorService.class); + ExecutorBeanPostProcessor bpp = new ExecutorBeanPostProcessor(this.beanFactory) { + @Override + Object getObject(ProxyFactoryBean factory) { + throw new AopConfigException("foo"); + } + }; + + Object o = bpp.postProcessAfterInitialization(service, "foo"); + + then(o).isInstanceOf(TraceableExecutorService.class); + } + + private ExecutorService exceptionThrowingExecutorService() { + return new ExecutorService() { + @Override + public void execute(Runnable command) { + + } + + @Override + public void shutdown() { + + } + + @Override + public List shutdownNow() { + return null; + } + + @Override + public boolean isShutdown() { + return false; + } + + @Override + public boolean isTerminated() { + return false; + } + + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { + return false; + } + + @Override + public Future submit(Callable task) { + throw new IllegalStateException("foo"); + } + + @Override + public Future submit(Runnable task, T result) { + return null; + } + + @Override + public Future submit(Runnable task) { + return null; + } + + @Override + public List> invokeAll(Collection> tasks) throws InterruptedException { + return null; + } + + @Override + public List> invokeAll(Collection> tasks, long timeout, TimeUnit unit) throws InterruptedException { + return null; + } + + @Override + public T invokeAny(Collection> tasks) throws InterruptedException, ExecutionException { + return null; + } + + @Override + public T invokeAny(Collection> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + return null; + } + }; } @Test From a0dd612148298e29819342b5a8af946de408b274 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 22 Oct 2018 18:18:48 +0200 Subject: [PATCH 3/3] Fixed adding multiple headers for web client; fixes gh-1102 --- .../TraceWebClientBeanPostProcessor.java | 25 ++-- .../instrument/web/client/GH1102Tests.java | 127 ++++++++++++++++++ .../{GH846Test.java => GH846Tests.java} | 4 +- .../TraceWebClientBeanPostProcessorTest.java | 28 +++- 4 files changed, 163 insertions(+), 21 deletions(-) create mode 100644 spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH1102Tests.java rename spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/{GH846Test.java => GH846Tests.java} (95%) diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java index ec231112f..ca0f0165d 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java @@ -16,6 +16,7 @@ package org.springframework.cloud.sleuth.instrument.web.client; +import java.util.Collections; import java.util.List; import java.util.function.Consumer; @@ -27,6 +28,8 @@ import brave.propagation.Propagation; import brave.propagation.TraceContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import reactor.core.publisher.Mono; + import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.config.BeanPostProcessor; @@ -36,7 +39,6 @@ import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.ExchangeFilterFunction; import org.springframework.web.reactive.function.client.ExchangeFunction; import org.springframework.web.reactive.function.client.WebClient; -import reactor.core.publisher.Mono; /** * {@link BeanPostProcessor} to wrap a {@link WebClient} instance into @@ -93,7 +95,13 @@ class TraceExchangeFilterFunction implements ExchangeFilterFunction { static final Propagation.Setter SETTER = new Propagation.Setter() { @Override public void put(ClientRequest.Builder carrier, String key, String value) { - carrier.header(key, value); + carrier.headers(httpHeaders -> { + if (log.isTraceEnabled()) { + log.trace("Replacing [" + key + "] with value [" + value + "]"); + } + httpHeaders.merge(key, Collections + .singletonList(value), (oldValue, newValue) -> newValue); + }); } @Override public String toString() { @@ -101,16 +109,6 @@ class TraceExchangeFilterFunction implements ExchangeFilterFunction { } }; - static final Propagation.Getter GETTER = new Propagation.Getter() { - @Override public String get(ClientRequest carrier, String key) { - return carrier.headers().getFirst(key); - } - - @Override public String toString() { - return "HttpHeaders::getFirst"; - } - }; - public static ExchangeFilterFunction create(BeanFactory beanFactory) { return new TraceExchangeFilterFunction(beanFactory); } @@ -134,6 +132,9 @@ class TraceExchangeFilterFunction implements ExchangeFilterFunction { .onErrorResume(Mono::just) .zipWith(Mono.subscriberContext()) .flatMap(anyAndContext -> { + if (log.isDebugEnabled()) { + log.debug("Wrapping the context [" + anyAndContext + "]"); + } Object any = anyAndContext.getT1(); Span clientSpan = anyAndContext.getT2().get(CLIENT_SPAN_KEY); Mono continuation; diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH1102Tests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH1102Tests.java new file mode 100644 index 000000000..b45eabf50 --- /dev/null +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH1102Tests.java @@ -0,0 +1,127 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.sleuth.instrument.web.client; + +import brave.ScopedSpan; +import brave.Tracer; +import brave.sampler.Sampler; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.assertj.core.api.BDDAssertions; +import org.junit.Test; +import org.junit.runner.RunWith; +import reactor.core.publisher.Mono; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.reactive.function.client.WebClientResponseException; + +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@RunWith(SpringRunner.class) +public class GH1102Tests { + + @Autowired + Tracer tracer; + @Autowired + WebClient webClient; + @Autowired + TestRetry testRetry; + @Autowired + ArrayListSpanReporter reporter; + + @LocalServerPort + int port; + + @Test + public void should_store_retries_as_separate_spans() throws Exception { + ScopedSpan foo = this.tracer.startScopedSpan("foo"); + try { + this.webClient + .get() + .uri("http://localhost:" + this.port + "/test") + .retrieve() + .bodyToMono(String.class) + .retry(1).block(); + BDDAssertions.fail("should throw exception"); + } + catch (WebClientResponseException ex) { + + } finally { + foo.finish(); + } + + BDDAssertions.then(this.testRetry.getHttpHeaders().get("x-b3-traceid")) + .hasSize(1); + } + + @EnableAutoConfiguration + @Configuration + static class WebConfig { + + @Bean + Sampler sampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + ArrayListSpanReporter reporter() { + return new ArrayListSpanReporter(); + } + + @Bean + WebClient webClient() { + return WebClient.builder().build(); + } + + @Bean + TestRetry testRetry() { + return new TestRetry(); + } + } + + + @RestController + static class TestRetry { + + private static final Log log = LogFactory.getLog(TestRetry.class); + + private MultiValueMap httpHeaders; + + @GetMapping("test") + Mono test(@RequestHeader MultiValueMap map) { + this.httpHeaders = map; + log.info("Processing test. Headers [" + this.httpHeaders + "]"); + return Mono.error(new RuntimeException("BOOM!")); + } + + MultiValueMap getHttpHeaders() { + return this.httpHeaders; + } + } +} diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH846Test.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH846Tests.java similarity index 95% rename from spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH846Test.java rename to spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH846Tests.java index 794b2031a..012d0195a 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH846Test.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH846Tests.java @@ -31,9 +31,9 @@ import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.client.RestTemplate; -@SpringBootTest(classes = GH846Test.App.class, webEnvironment=WebEnvironment.NONE) +@SpringBootTest(classes = GH846Tests.App.class, webEnvironment=WebEnvironment.NONE) @RunWith(SpringRunner.class) -public class GH846Test { +public class GH846Tests { @Autowired private MyBean myBean; diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessorTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessorTest.java index 2fd77c54b..93a5f98da 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessorTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessorTest.java @@ -16,12 +16,18 @@ package org.springframework.cloud.sleuth.instrument.web.client; +import java.net.URI; + +import brave.propagation.Propagation; import org.assertj.core.api.BDDAssertions; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; + import org.springframework.beans.factory.BeanFactory; +import org.springframework.http.HttpMethod; +import org.springframework.web.reactive.function.client.ClientRequest; import org.springframework.web.reactive.function.client.WebClient; /** @@ -30,9 +36,11 @@ import org.springframework.web.reactive.function.client.WebClient; @RunWith(MockitoJUnitRunner.class) public class TraceWebClientBeanPostProcessorTest { - @Mock BeanFactory beanFactory; + @Mock + BeanFactory beanFactory; - @Test public void should_add_filter_only_once_to_web_client() { + @Test + public void should_add_filter_only_once_to_web_client() { TraceWebClientBeanPostProcessor processor = new TraceWebClientBeanPostProcessor(this.beanFactory); WebClient client = WebClient.create(); @@ -41,20 +49,26 @@ public class TraceWebClientBeanPostProcessorTest { client.mutate().filters(filters -> { BDDAssertions.then(filters).hasSize(1); - BDDAssertions.then(filters.get(0)).isInstanceOf(TraceExchangeFilterFunction.class); + BDDAssertions.then(filters.get(0)) + .isInstanceOf(TraceExchangeFilterFunction.class); }); } - @Test public void should_add_filter_only_once_to_web_client_via_builder() { + @Test + public void should_add_filter_only_once_to_web_client_via_builder() { TraceWebClientBeanPostProcessor processor = new TraceWebClientBeanPostProcessor(this.beanFactory); WebClient.Builder builder = WebClient.builder(); - builder = (WebClient.Builder) processor.postProcessAfterInitialization(builder, "foo"); - builder = (WebClient.Builder) processor.postProcessAfterInitialization(builder, "foo"); + builder = (WebClient.Builder) processor + .postProcessAfterInitialization(builder, "foo"); + builder = (WebClient.Builder) processor + .postProcessAfterInitialization(builder, "foo"); builder.build().mutate().filters(filters -> { BDDAssertions.then(filters).hasSize(1); - BDDAssertions.then(filters.get(0)).isInstanceOf(TraceExchangeFilterFunction.class); + BDDAssertions.then(filters.get(0)) + .isInstanceOf(TraceExchangeFilterFunction.class); }); } + } \ No newline at end of file