diff --git a/.editorconfig b/.editorconfig index ddda9782f..ffe385c6d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,5 +1,9 @@ root = true +[*] +end_of_line = crlf +insert_final_newline = true + [*.java] indent_style = tab indent_size = 4 diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index aeafef9d3..813d3b5cf 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -12,6 +12,6 @@ Please provide details of the problem, including the version of Spring Cloud tha are using. **Sample** -If possible, please provide a test case or sample application that reproduces +If possible, please provide a test case or a minimal **Maven** sample written in **Java** that reproduces the problem. This makes it much easier for us to diagnose the problem and to verify that we have fixed it. diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 32d179893..2e7786e55 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -1,31 +1,32 @@ -# This workflow will build a Java project with Maven -# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven - -name: Build - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - name: Cache local Maven repository - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - - name: Build with Maven - run: ./mvnw clean install -B -U \ No newline at end of file +name: Build + +on: + push: + branches: [ 3.1.x ] + pull_request: + branches: [ 3.1.x ] + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + matrix: + java: ["8", "11", "16"] + + steps: + - uses: actions/checkout@v2 + - name: Setup java + uses: actions/setup-java@v2 + with: + distribution: 'zulu' + java-version: ${{ matrix.java }} + - name: Cache local Maven repository + uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Build with Maven + run: ./mvnw clean install -B -U -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 2e529b161..d7b910b9a 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -22,13 +22,13 @@ Benchmarks Benchmarks (JMH) org.springframework.cloud - 3.0.2-SNAPSHOT + 3.1.0-SNAPSHOT benchmarks org.springframework.boot spring-boot-starter-parent - 2.4.3 + 2.4.5-SNAPSHOT @@ -41,7 +41,7 @@ 4.9.0 0.2.0.RELEASE 1.26 - 3.1.1-SNAPSHOT + 3.1.3-SNAPSHOT diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/mvc/SleuthBenchmarkingSpringApp.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/mvc/SleuthBenchmarkingSpringApp.java index 67b51420c..943d5055d 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/mvc/SleuthBenchmarkingSpringApp.java +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/mvc/SleuthBenchmarkingSpringApp.java @@ -1,181 +1,181 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.benchmarks.app.mvc; - -import java.util.concurrent.Future; -import java.util.regex.Pattern; - -import javax.annotation.PreDestroy; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; -import org.springframework.cloud.sleuth.Span; -import org.springframework.cloud.sleuth.Tracer; -import org.springframework.cloud.sleuth.annotation.ContinueSpan; -import org.springframework.cloud.sleuth.annotation.NewSpan; -import org.springframework.cloud.sleuth.annotation.SpanTag; -import org.springframework.cloud.sleuth.benchmarks.app.mvc.controller.AsyncSimulationController; -import org.springframework.cloud.sleuth.instrument.web.SkipPatternProvider; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.annotation.EnableAsync; -import org.springframework.util.SocketUtils; - -/** - * @author Marcin Grzejszczak - */ -@SpringBootApplication -@EnableAsync -public class SleuthBenchmarkingSpringApp implements ApplicationListener { - - private static final Log log = LogFactory.getLog(SleuthBenchmarkingSpringApp.class); - - /** - * Port of the app. - */ - public int port; - - @Autowired(required = false) - Tracer tracer; - - @Autowired - AClass aClass; - - @Autowired - AsyncSimulationController controller; - - public static void main(String... args) { - SpringApplication.run(SleuthBenchmarkingSpringApp.class, args); - } - - @PreDestroy - public void clean() { - this.controller.clean(); - } - - public String manualSpan() { - return this.aClass.manualSpan(); - } - - public String newSpan() { - return this.aClass.newSpan(); - } - - @Override - public void onApplicationEvent(ServletWebServerInitializedEvent event) { - this.port = event.getSource().getPort(); - } - - public Future async() { - return this.controller.async(); - } - - @Configuration - static class Config { - @Autowired(required = false) - Tracer tracer; - - @Bean - AnotherClass anotherClass() { - return new AnotherClass(this.tracer); - } - - @Bean - AClass aClass() { - return new AClass(this.tracer, anotherClass()); - } - - @Bean - SkipPatternProvider patternProvider() { - return new SkipPatternProvider() { - @Override - public Pattern skipPattern() { - return Pattern.compile(""); - } - }; - } - - - @Bean - public ServletWebServerFactory servletContainer(@Value("${server.port:0}") int serverPort) { - log.info("Starting container at port [" + serverPort + "]"); - return new TomcatServletWebServerFactory(serverPort == 0 ? SocketUtils.findAvailableTcpPort() : serverPort); - } - - } -} - -class AClass { - - private final Tracer tracer; - - private final AnotherClass anotherClass; - - AClass(Tracer tracer, AnotherClass anotherClass) { - this.tracer = tracer; - this.anotherClass = anotherClass; - } - - public String manualSpan() { - Span manual = this.tracer.nextSpan().name("span-name"); - try (Tracer.SpanInScope ws = this.tracer.withSpan(manual.start())) { - return this.anotherClass.continuedSpan(); - } - finally { - manual.end(); - } - } - - @NewSpan - public String newSpan() { - return this.anotherClass.continuedAnnotation("bar"); - } - -} - -class AnotherClass { - - private final Tracer tracer; - - AnotherClass(Tracer tracer) { - this.tracer = tracer; - } - - @ContinueSpan(log = "continuedspan") - public String continuedAnnotation(@SpanTag("foo") String tagValue) { - return "continued"; - } - - public String continuedSpan() { - Span span = this.tracer.currentSpan(); - span.tag("foo", "bar"); - span.event("continuedspan.before"); - String response = "continued"; - span.event("continuedspan.after"); - return response; - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.benchmarks.app.mvc; + +import java.util.concurrent.Future; +import java.util.regex.Pattern; + +import javax.annotation.PreDestroy; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent; +import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.annotation.ContinueSpan; +import org.springframework.cloud.sleuth.annotation.NewSpan; +import org.springframework.cloud.sleuth.annotation.SpanTag; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.controller.AsyncSimulationController; +import org.springframework.cloud.sleuth.instrument.web.SkipPatternProvider; +import org.springframework.context.ApplicationListener; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.util.SocketUtils; + +/** + * @author Marcin Grzejszczak + */ +@SpringBootApplication +@EnableAsync +public class SleuthBenchmarkingSpringApp implements ApplicationListener { + + private static final Log log = LogFactory.getLog(SleuthBenchmarkingSpringApp.class); + + /** + * Port of the app. + */ + public int port; + + @Autowired(required = false) + Tracer tracer; + + @Autowired + AClass aClass; + + @Autowired + AsyncSimulationController controller; + + public static void main(String... args) { + SpringApplication.run(SleuthBenchmarkingSpringApp.class, args); + } + + @PreDestroy + public void clean() { + this.controller.clean(); + } + + public String manualSpan() { + return this.aClass.manualSpan(); + } + + public String newSpan() { + return this.aClass.newSpan(); + } + + @Override + public void onApplicationEvent(ServletWebServerInitializedEvent event) { + this.port = event.getSource().getPort(); + } + + public Future async() { + return this.controller.async(); + } + + @Configuration + static class Config { + @Autowired(required = false) + Tracer tracer; + + @Bean + AnotherClass anotherClass() { + return new AnotherClass(this.tracer); + } + + @Bean + AClass aClass() { + return new AClass(this.tracer, anotherClass()); + } + + @Bean + SkipPatternProvider patternProvider() { + return new SkipPatternProvider() { + @Override + public Pattern skipPattern() { + return Pattern.compile(""); + } + }; + } + + + @Bean + public ServletWebServerFactory servletContainer(@Value("${server.port:0}") int serverPort) { + log.info("Starting container at port [" + serverPort + "]"); + return new TomcatServletWebServerFactory(serverPort == 0 ? SocketUtils.findAvailableTcpPort() : serverPort); + } + + } +} + +class AClass { + + private final Tracer tracer; + + private final AnotherClass anotherClass; + + AClass(Tracer tracer, AnotherClass anotherClass) { + this.tracer = tracer; + this.anotherClass = anotherClass; + } + + public String manualSpan() { + Span manual = this.tracer.nextSpan().name("span-name"); + try (Tracer.SpanInScope ws = this.tracer.withSpan(manual.start())) { + return this.anotherClass.continuedSpan(); + } + finally { + manual.end(); + } + } + + @NewSpan + public String newSpan() { + return this.anotherClass.continuedAnnotation("bar"); + } + +} + +class AnotherClass { + + private final Tracer tracer; + + AnotherClass(Tracer tracer) { + this.tracer = tracer; + } + + @ContinueSpan(log = "continuedspan") + public String continuedAnnotation(@SpanTag("foo") String tagValue) { + return "continued"; + } + + public String continuedSpan() { + Span span = this.tracer.currentSpan(); + span.tag("foo", "bar"); + span.event("continuedspan.before"); + String response = "continued"; + span.event("continuedspan.after"); + return response; + } + +} diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/stream/SleuthBenchmarkingStreamApplication.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/stream/SleuthBenchmarkingStreamApplication.java index c8aa01ed6..ca33e5bd8 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/stream/SleuthBenchmarkingStreamApplication.java +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/stream/SleuthBenchmarkingStreamApplication.java @@ -1,275 +1,283 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.benchmarks.app.stream; - -import java.io.IOException; -import java.time.Duration; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.function.Function; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.core.scheduler.Scheduler; -import reactor.core.scheduler.Schedulers; - -import org.springframework.beans.factory.BeanFactory; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.sleuth.instrument.messaging.MessagingSleuthOperators; -import org.springframework.cloud.stream.binder.test.InputDestination; -import org.springframework.cloud.stream.binder.test.OutputDestination; -import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.messaging.Message; -import org.springframework.messaging.support.MessageBuilder; - -import static org.assertj.core.api.Assertions.assertThat; - -@SpringBootApplication -@Import(TestChannelBinderConfiguration.class) -public class SleuthBenchmarkingStreamApplication { - - private static final Logger log = LoggerFactory.getLogger(SleuthBenchmarkingStreamApplication.class); - - public static void main(String[] args) throws InterruptedException, IOException { - // System.setProperty("spring.sleuth.enabled", "false"); - // System.setProperty("spring.sleuth.reactor.instrumentation-type", - // "DECORATE_ON_EACH"); - // System.setProperty("spring.sleuth.reactor.instrumentation-type", - // "DECORATE_ON_LAST"); - // System.setProperty("spring.sleuth.reactor.instrumentation-type", "MANUAL"); - System.setProperty("spring.sleuth.reactor.instrumentation-type", "MANUAL"); - System.setProperty("spring.sleuth.function.type", "simple"); - ConfigurableApplicationContext context = SpringApplication.run(SleuthBenchmarkingStreamApplication.class, args); - for (int i = 0; i < 1; i++) { - InputDestination input = context.getBean(InputDestination.class); - input.send(MessageBuilder.withPayload("hello".getBytes()) - .setHeader("b3", "4883117762eb9420-4883117762eb9420-1").build()); - log.info("Retrieving the message for tests"); - OutputDestination output = context.getBean(OutputDestination.class); - Message message = output.receive(200L); - log.info("Got the message from output"); - assertThat(message).isNotNull(); - log.info("Message is not null"); - assertThat(message.getPayload()).isEqualTo("HELLO".getBytes()); - log.info("Payload is HELLO"); - String b3 = message.getHeaders().get("b3", String.class); - log.info("Checking the b3 header [" + b3 + "]"); - assertThat(b3).startsWith("4883117762eb9420"); - } - } - - @Bean - ExecutorService sleuthExecutorService() { - return Executors.newCachedThreadPool(); - } - - @Bean(name = "myFlux") - @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "simple") - public Function simple() { - log.info("simple_function"); - return new SimpleFunction(); - } - - @Bean(name = "myFlux") - @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "reactive_simple") - public Function, Flux> reactiveSimple() { - log.info("simple_reactive_function"); - return new SimpleReactiveFunction(); - } - - @Bean(name = "myFlux") - @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "simple_function_with_around") - public Function, Message> simpleFunctionWithAround() { - log.info("simple_function_with_around"); - return new SimpleMessageFunction(); - } - - @Bean(name = "myFlux") - @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "simple_manual") - public Function, Message> simpleManual(BeanFactory beanFactory) { - log.info("simple_manual_function"); - return new SimpleManualFunction(beanFactory); - } - - @Bean(name = "myFlux") - @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "reactive_simple_manual") - public Function>, Flux>> reactiveSimpleManual(BeanFactory beanFactory) { - log.info("simple_reactive_manual_function"); - return new SimpleReactiveManualFunction(beanFactory); - } - - @Bean(name = "myFlux") - @ConditionalOnProperty(value = "spring.sleuth.nonreactive.function.enabled", havingValue = "true") - public Function nonReactiveFunction(ExecutorService executorService) { - log.info("no sleuth non reactive function"); - return new SleuthNonReactiveFunction(executorService); - } - - @Bean(name = "myFlux") - @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "DECORATE_ON_EACH", - matchIfMissing = true) - public Function, Flux> onEachFunction() { - log.info("on each function"); - return new SleuthFunction(); - } - - @Bean(name = "myFlux") - @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "DECORATE_ON_LAST") - public Function, Flux> onLastFunction() { - log.info("on last function"); - return new SleuthFunction(); - } - -} - -class SimpleFunction implements Function { - - private static final Logger log = LoggerFactory.getLogger(SimpleFunction.class); - - @Override - public String apply(String input) { - // tracing works cause headers from the input message get propagated to the output - // message - log.info("Hello from simple [{}]", input); - return input.toUpperCase(); - } - -} - -class SimpleReactiveFunction implements Function, Flux> { - - private static final Logger log = LoggerFactory.getLogger(SimpleReactiveFunction.class); - - @Override - public Flux apply(Flux input) { - return input.doOnNext(s -> log.info("Hello from simple [{}]", s)).map(String::toUpperCase); - } - -} - -class SimpleManualFunction implements Function, Message> { - - private static final Logger log = LoggerFactory.getLogger(SimpleFunction.class); - - private final BeanFactory beanFactory; - - SimpleManualFunction(BeanFactory beanFactory) { - this.beanFactory = beanFactory; - } - - @Override - public Message apply(Message input) { - return (MessagingSleuthOperators.asFunction(this.beanFactory, input) - .andThen(msg -> MessagingSleuthOperators.withSpanInScope(this.beanFactory, msg, stringMessage -> { - log.info("Hello from simple manual [{}]", stringMessage.getPayload()); - return stringMessage; - })).andThen(msg -> MessagingSleuthOperators.afterMessageHandled(this.beanFactory, msg, null)) - .andThen(msg -> MessagingSleuthOperators.handleOutputMessage(this.beanFactory, msg)) - .andThen(msg -> MessageBuilder.createMessage(msg.getPayload().toUpperCase(), msg.getHeaders())) - .andThen(msg -> MessagingSleuthOperators.afterMessageHandled(this.beanFactory, msg, null)) - .apply(input)); - } - -} - -class SimpleMessageFunction implements Function, Message> { - - private static final Logger log = LoggerFactory.getLogger(SimpleFunction.class); - - @Override - public Message apply(Message input) { - log.info("Hello from message simple [{}]", input.getPayload()); - return MessageBuilder.withPayload(input.getPayload().toUpperCase()).build(); - } - -} - -// tag::simple_reactive[] -class SimpleReactiveManualFunction implements Function>, Flux>> { - - private static final Logger log = LoggerFactory.getLogger(SimpleReactiveFunction.class); - - private final BeanFactory beanFactory; - - SimpleReactiveManualFunction(BeanFactory beanFactory) { - this.beanFactory = beanFactory; - } - - @Override - public Flux> apply(Flux> input) { - return input.map(message -> (MessagingSleuthOperators.asFunction(this.beanFactory, message)) - .andThen(msg -> MessagingSleuthOperators.withSpanInScope(this.beanFactory, msg, stringMessage -> { - log.info("Hello from simple manual [{}]", stringMessage.getPayload()); - return stringMessage; - })).andThen(msg -> MessagingSleuthOperators.afterMessageHandled(this.beanFactory, msg, null)) - .andThen(msg -> MessageBuilder.createMessage(msg.getPayload().toUpperCase(), msg.getHeaders())) - .andThen(msg -> MessagingSleuthOperators.handleOutputMessage(this.beanFactory, msg)).apply(message)); - } - -} -// end::simple_reactive[] - -class SleuthNonReactiveFunction implements Function { - - private static final Logger log = LoggerFactory.getLogger(SleuthNonReactiveFunction.class); - - private final ExecutorService executorService; - - SleuthNonReactiveFunction(ExecutorService executorService) { - this.executorService = executorService; - } - - @Override - public String apply(String input) { - log.info("Got a message"); - try { - return this.executorService.submit(() -> { - log.info("Logging [{}] from a new thread", input); - return input.toUpperCase(); - }).get(20, TimeUnit.MILLISECONDS); - } - catch (Exception e) { - throw new IllegalStateException(e); - } - } - -} - -class SleuthFunction implements Function, Flux> { - - private static final Logger log = LoggerFactory.getLogger(SleuthFunction.class); - - static final Scheduler SCHEDULER = Schedulers.newParallel("sleuthFunction"); - - @Override - public Flux apply(Flux input) { - return input.doOnEach(signal -> log.info("Got a message")) - .flatMap(s -> Mono.delay(Duration.ofMillis(1), SCHEDULER).map(aLong -> { - log.info("Logging [{}] from flat map", s); - return s.toUpperCase(); - })); - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.benchmarks.app.stream; + +import java.io.IOException; +import java.time.Duration; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Scheduler; +import reactor.core.scheduler.Schedulers; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.sleuth.instrument.messaging.MessagingSleuthOperators; +import org.springframework.cloud.stream.binder.test.InputDestination; +import org.springframework.cloud.stream.binder.test.OutputDestination; +import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootApplication +@Import(TestChannelBinderConfiguration.class) +public class SleuthBenchmarkingStreamApplication { + + private static final Logger log = LoggerFactory.getLogger(SleuthBenchmarkingStreamApplication.class); + + public static void main(String[] args) throws InterruptedException, IOException { + // System.setProperty("spring.sleuth.enabled", "false"); + // System.setProperty("spring.sleuth.reactor.instrumentation-type", + // "DECORATE_ON_EACH"); + // System.setProperty("spring.sleuth.reactor.instrumentation-type", + // "DECORATE_ON_LAST"); + // System.setProperty("spring.sleuth.reactor.instrumentation-type", "MANUAL"); + System.setProperty("spring.sleuth.reactor.instrumentation-type", "DECORATE_QUEUES"); + System.setProperty("spring.sleuth.function.type", "DECORATE_QUEUES"); + ConfigurableApplicationContext context = SpringApplication.run(SleuthBenchmarkingStreamApplication.class, args); + for (int i = 0; i < 1; i++) { + InputDestination input = context.getBean(InputDestination.class); + input.send(MessageBuilder.withPayload("hello".getBytes()) + .setHeader("b3", "4883117762eb9420-4883117762eb9420-1").build()); + log.info("Retrieving the message for tests"); + OutputDestination output = context.getBean(OutputDestination.class); + Message message = output.receive(200L); + log.info("Got the message from output"); + assertThat(message).isNotNull(); + log.info("Message is not null"); + assertThat(message.getPayload()).isEqualTo("HELLO".getBytes()); + log.info("Payload is HELLO"); + String b3 = message.getHeaders().get("b3", String.class); + log.info("Checking the b3 header [" + b3 + "]"); + assertThat(b3).startsWith("4883117762eb9420"); + } + } + + @Bean + ExecutorService sleuthExecutorService() { + return Executors.newCachedThreadPool(); + } + + @Bean(name = "myFlux") + @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "simple") + public Function simple() { + log.info("simple_function"); + return new SimpleFunction(); + } + + @Bean(name = "myFlux") + @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "reactive_simple") + public Function, Flux> reactiveSimple() { + log.info("simple_reactive_function"); + return new SimpleReactiveFunction(); + } + + @Bean(name = "myFlux") + @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "simple_function_with_around") + public Function, Message> simpleFunctionWithAround() { + log.info("simple_function_with_around"); + return new SimpleMessageFunction(); + } + + @Bean(name = "myFlux") + @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "simple_manual") + public Function, Message> simpleManual(BeanFactory beanFactory) { + log.info("simple_manual_function"); + return new SimpleManualFunction(beanFactory); + } + + @Bean(name = "myFlux") + @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "reactive_simple_manual") + public Function>, Flux>> reactiveSimpleManual(BeanFactory beanFactory) { + log.info("simple_reactive_manual_function"); + return new SimpleReactiveManualFunction(beanFactory); + } + + @Bean(name = "myFlux") + @ConditionalOnProperty(value = "spring.sleuth.nonreactive.function.enabled", havingValue = "true") + public Function nonReactiveFunction(ExecutorService executorService) { + log.info("no sleuth non reactive function"); + return new SleuthNonReactiveFunction(executorService); + } + + @Bean(name = "myFlux") + @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "DECORATE_ON_EACH", + matchIfMissing = true) + public Function, Flux> onEachFunction() { + log.info("on each function"); + return new SleuthFunction(); + } + + @Bean(name = "myFlux") + @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "DECORATE_QUEUES", + matchIfMissing = true) + public Function, Flux> decorateQueuesFunction() { + log.info("decorate queues function"); + return new SleuthFunction(); + } + + @Bean(name = "myFlux") + @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "DECORATE_ON_LAST") + public Function, Flux> onLastFunction() { + log.info("on last function"); + return new SleuthFunction(); + } + +} + +class SimpleFunction implements Function { + + private static final Logger log = LoggerFactory.getLogger(SimpleFunction.class); + + @Override + public String apply(String input) { + // tracing works cause headers from the input message get propagated to the output + // message + log.info("Hello from simple [{}]", input); + return input.toUpperCase(); + } + +} + +class SimpleReactiveFunction implements Function, Flux> { + + private static final Logger log = LoggerFactory.getLogger(SimpleReactiveFunction.class); + + @Override + public Flux apply(Flux input) { + return input.doOnNext(s -> log.info("Hello from simple [{}]", s)).map(String::toUpperCase); + } + +} + +class SimpleManualFunction implements Function, Message> { + + private static final Logger log = LoggerFactory.getLogger(SimpleFunction.class); + + private final BeanFactory beanFactory; + + SimpleManualFunction(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @Override + public Message apply(Message input) { + return (MessagingSleuthOperators.asFunction(this.beanFactory, input) + .andThen(msg -> MessagingSleuthOperators.withSpanInScope(this.beanFactory, msg, stringMessage -> { + log.info("Hello from simple manual [{}]", stringMessage.getPayload()); + return stringMessage; + })).andThen(msg -> MessagingSleuthOperators.afterMessageHandled(this.beanFactory, msg, null)) + .andThen(msg -> MessagingSleuthOperators.handleOutputMessage(this.beanFactory, msg)) + .andThen(msg -> MessageBuilder.createMessage(msg.getPayload().toUpperCase(), msg.getHeaders())) + .andThen(msg -> MessagingSleuthOperators.afterMessageHandled(this.beanFactory, msg, null)) + .apply(input)); + } + +} + +class SimpleMessageFunction implements Function, Message> { + + private static final Logger log = LoggerFactory.getLogger(SimpleFunction.class); + + @Override + public Message apply(Message input) { + log.info("Hello from message simple [{}]", input.getPayload()); + return MessageBuilder.withPayload(input.getPayload().toUpperCase()).build(); + } + +} + +// tag::simple_reactive[] +class SimpleReactiveManualFunction implements Function>, Flux>> { + + private static final Logger log = LoggerFactory.getLogger(SimpleReactiveFunction.class); + + private final BeanFactory beanFactory; + + SimpleReactiveManualFunction(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @Override + public Flux> apply(Flux> input) { + return input.map(message -> (MessagingSleuthOperators.asFunction(this.beanFactory, message)) + .andThen(msg -> MessagingSleuthOperators.withSpanInScope(this.beanFactory, msg, stringMessage -> { + log.info("Hello from simple manual [{}]", stringMessage.getPayload()); + return stringMessage; + })).andThen(msg -> MessagingSleuthOperators.afterMessageHandled(this.beanFactory, msg, null)) + .andThen(msg -> MessageBuilder.createMessage(msg.getPayload().toUpperCase(), msg.getHeaders())) + .andThen(msg -> MessagingSleuthOperators.handleOutputMessage(this.beanFactory, msg)).apply(message)); + } + +} +// end::simple_reactive[] + +class SleuthNonReactiveFunction implements Function { + + private static final Logger log = LoggerFactory.getLogger(SleuthNonReactiveFunction.class); + + private final ExecutorService executorService; + + SleuthNonReactiveFunction(ExecutorService executorService) { + this.executorService = executorService; + } + + @Override + public String apply(String input) { + log.info("Got a message"); + try { + return this.executorService.submit(() -> { + log.info("Logging [{}] from a new thread", input); + return input.toUpperCase(); + }).get(20, TimeUnit.MILLISECONDS); + } + catch (Exception e) { + throw new IllegalStateException(e); + } + } + +} + +class SleuthFunction implements Function, Flux> { + + private static final Logger log = LoggerFactory.getLogger(SleuthFunction.class); + + static final Scheduler SCHEDULER = Schedulers.newParallel("sleuthFunction"); + + @Override + public Flux apply(Flux input) { + return input.doOnEach(signal -> log.info("Got a message")) + .flatMap(s -> Mono.delay(Duration.ofMillis(1), SCHEDULER).map(aLong -> { + log.info("Logging [{}] from flat map", s); + return s.toUpperCase(); + })); + } + +} diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java index ac61085db..bdda1256e 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java @@ -1,153 +1,153 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.benchmarks.app.webflux; - -import java.time.Duration; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.core.publisher.SignalType; -import reactor.core.scheduler.Scheduler; -import reactor.core.scheduler.Schedulers; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; -import org.springframework.boot.web.reactive.context.ReactiveWebServerInitializedEvent; -import org.springframework.cloud.sleuth.TraceContext; -import org.springframework.cloud.sleuth.instrument.web.SkipPatternProvider; -import org.springframework.cloud.sleuth.instrument.web.WebFluxSleuthOperators; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; -import org.springframework.util.Assert; -import org.springframework.util.SocketUtils; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * @author alvin - */ -@SpringBootApplication -@RestController -public class SleuthBenchmarkingSpringWebFluxApp implements ApplicationListener { - - static final Scheduler FOO_SCHEDULER = Schedulers.newParallel("foo"); - - private static final Logger log = LoggerFactory.getLogger(SleuthBenchmarkingSpringWebFluxApp.class); - - /** - * Port to set. - */ - public int port; - - public static void main(String... args) { - new SpringApplicationBuilder(SleuthBenchmarkingSpringWebFluxApp.class).web(WebApplicationType.REACTIVE) - .application().run(args); - } - - @RequestMapping("/foo") - public Mono foo() { - return Mono.just("foo"); - } - - @Bean - SkipPatternProvider patternProvider() { - return () -> Pattern.compile(""); - } - - @Bean - NettyReactiveWebServerFactory nettyReactiveWebServerFactory(@Value("${server.port:0}") int serverPort) { - log.info("Starting container at port [" + serverPort + "]"); - return new NettyReactiveWebServerFactory(serverPort == 0 ? SocketUtils.findAvailableTcpPort() : serverPort); - } - - @Override - public void onApplicationEvent(ReactiveWebServerInitializedEvent event) { - this.port = event.getWebServer().getPort(); - } - - @GetMapping("/simple") - public Mono simple() { - return Mono.just("hello").map(String::toUpperCase).doOnNext(s -> log.info("Hello from simple [{}]", s)); - } - - // tag::simple_manual[] - @GetMapping("/simpleManual") - public Mono simpleManual() { - return Mono.just("hello").map(String::toUpperCase).doOnEach(WebFluxSleuthOperators - .withSpanInScope(SignalType.ON_NEXT, signal -> log.info("Hello from simple [{}]", signal.get()))); - } - // end::simple_manual[] - - @GetMapping("/complexNoSleuth") - public Mono complexNoSleuth() { - return Flux.range(1, 10).map(String::valueOf).collect(Collectors.toList()) - .doOnEach(signal -> log.info("Got a request")) - .flatMap(s -> Mono.delay(Duration.ofMillis(1), FOO_SCHEDULER).map(aLong -> { - log.info("Logging [{}] from flat map", s); - return ""; - })); - } - - @GetMapping("/complex") - public Mono complex() { - return Flux.range(1, 10).map(String::valueOf).collect(Collectors.toList()) - .doOnEach(signal -> log.info("Got a request")) - .flatMap(s -> Mono.delay(Duration.ofMillis(1), FOO_SCHEDULER).map(aLong -> { - log.info("Logging [{}] from flat map", s); - return ""; - })).doOnEach(signal -> { - log.info("Doing assertions"); - TraceContext traceContext = signal.getContext().get(TraceContext.class); - Assert.notNull(traceContext, "Context must be set by Sleuth instrumentation"); - if (traceContext.traceId().startsWith("0000000000000000")) { - Assert.state(traceContext.traceId().equals("00000000000000004883117762eb9420"), "TraceId must be propagated"); - } else { - Assert.state(traceContext.traceId().equals("4883117762eb9420"), "TraceId must be propagated"); - } - log.info("Assertions passed"); - }); - } - - @GetMapping("/complexManual") - public Mono complexManual() { - return Flux.range(1, 10).map(String::valueOf).collect(Collectors.toList()) - .doOnEach(WebFluxSleuthOperators.withSpanInScope(SignalType.ON_NEXT, () -> log.info("Got a request"))) - .flatMap(s -> Mono.subscriberContext().delayElement(Duration.ofMillis(1), FOO_SCHEDULER).map(ctx -> { - WebFluxSleuthOperators.withSpanInScope(ctx, () -> log.info("Logging [{}] from flat map", s)); - return ""; - })).doOnEach(signal -> { - WebFluxSleuthOperators.withSpanInScope(signal.getContext(), () -> log.info("Doing assertions")); - TraceContext traceContext = signal.getContext().get(TraceContext.class); - Assert.notNull(traceContext, "Context must be set by Sleuth instrumentation"); - if (traceContext.traceId().startsWith("0000000000000000")) { - Assert.state(traceContext.traceId().equals("00000000000000004883117762eb9420"), "TraceId must be propagated"); - } else { - Assert.state(traceContext.traceId().equals("4883117762eb9420"), "TraceId must be propagated"); - } - log.info("Assertions passed"); - }); - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.benchmarks.app.webflux; + +import java.time.Duration; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.publisher.SignalType; +import reactor.core.scheduler.Scheduler; +import reactor.core.scheduler.Schedulers; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; +import org.springframework.boot.web.reactive.context.ReactiveWebServerInitializedEvent; +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.cloud.sleuth.instrument.web.SkipPatternProvider; +import org.springframework.cloud.sleuth.instrument.web.WebFluxSleuthOperators; +import org.springframework.context.ApplicationListener; +import org.springframework.context.annotation.Bean; +import org.springframework.util.Assert; +import org.springframework.util.SocketUtils; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author alvin + */ +@SpringBootApplication +@RestController +public class SleuthBenchmarkingSpringWebFluxApp implements ApplicationListener { + + static final Scheduler FOO_SCHEDULER = Schedulers.newParallel("foo"); + + private static final Logger log = LoggerFactory.getLogger(SleuthBenchmarkingSpringWebFluxApp.class); + + /** + * Port to set. + */ + public int port; + + public static void main(String... args) { + new SpringApplicationBuilder(SleuthBenchmarkingSpringWebFluxApp.class).web(WebApplicationType.REACTIVE) + .application().run(args); + } + + @RequestMapping("/foo") + public Mono foo() { + return Mono.just("foo"); + } + + @Bean + SkipPatternProvider patternProvider() { + return () -> Pattern.compile(""); + } + + @Bean + NettyReactiveWebServerFactory nettyReactiveWebServerFactory(@Value("${server.port:0}") int serverPort) { + log.info("Starting container at port [" + serverPort + "]"); + return new NettyReactiveWebServerFactory(serverPort == 0 ? SocketUtils.findAvailableTcpPort() : serverPort); + } + + @Override + public void onApplicationEvent(ReactiveWebServerInitializedEvent event) { + this.port = event.getWebServer().getPort(); + } + + @GetMapping("/simple") + public Mono simple() { + return Mono.just("hello").map(String::toUpperCase).doOnNext(s -> log.info("Hello from simple [{}]", s)); + } + + // tag::simple_manual[] + @GetMapping("/simpleManual") + public Mono simpleManual() { + return Mono.just("hello").map(String::toUpperCase).doOnEach(WebFluxSleuthOperators + .withSpanInScope(SignalType.ON_NEXT, signal -> log.info("Hello from simple [{}]", signal.get()))); + } + // end::simple_manual[] + + @GetMapping("/complexNoSleuth") + public Mono complexNoSleuth() { + return Flux.range(1, 10).map(String::valueOf).collect(Collectors.toList()) + .doOnEach(signal -> log.info("Got a request")) + .flatMap(s -> Mono.delay(Duration.ofMillis(1), FOO_SCHEDULER).map(aLong -> { + log.info("Logging [{}] from flat map", s); + return ""; + })); + } + + @GetMapping("/complex") + public Mono complex() { + return Flux.range(1, 10).map(String::valueOf).collect(Collectors.toList()) + .doOnEach(signal -> log.info("Got a request")) + .flatMap(s -> Mono.delay(Duration.ofMillis(1), FOO_SCHEDULER).map(aLong -> { + log.info("Logging [{}] from flat map", s); + return ""; + })).doOnEach(signal -> { + log.info("Doing assertions"); + TraceContext traceContext = signal.getContext().get(TraceContext.class); + Assert.notNull(traceContext, "Context must be set by Sleuth instrumentation"); + if (traceContext.traceId().startsWith("0000000000000000")) { + Assert.state(traceContext.traceId().equals("00000000000000004883117762eb9420"), "TraceId must be propagated"); + } else { + Assert.state(traceContext.traceId().equals("4883117762eb9420"), "TraceId must be propagated"); + } + log.info("Assertions passed"); + }); + } + + @GetMapping("/complexManual") + public Mono complexManual() { + return Flux.range(1, 10).map(String::valueOf).collect(Collectors.toList()) + .doOnEach(WebFluxSleuthOperators.withSpanInScope(SignalType.ON_NEXT, () -> log.info("Got a request"))) + .flatMap(s -> Mono.subscriberContext().delayElement(Duration.ofMillis(1), FOO_SCHEDULER).map(ctx -> { + WebFluxSleuthOperators.withSpanInScope(ctx, () -> log.info("Logging [{}] from flat map", s)); + return ""; + })).doOnEach(signal -> { + WebFluxSleuthOperators.withSpanInScope(signal.getContext(), () -> log.info("Doing assertions")); + TraceContext traceContext = signal.getContext().get(TraceContext.class); + Assert.notNull(traceContext, "Context must be set by Sleuth instrumentation"); + if (traceContext.traceId().startsWith("0000000000000000")) { + Assert.state(traceContext.traceId().equals("00000000000000004883117762eb9420"), "TraceId must be propagated"); + } else { + Assert.state(traceContext.traceId().equals("4883117762eb9420"), "TraceId must be propagated"); + } + log.info("Assertions passed"); + }); + } + +} diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java new file mode 100644 index 000000000..67c0ca5fe --- /dev/null +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java @@ -0,0 +1,61 @@ +/* + * Copyright 2016-2021 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 + * + * https://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.benchmarks.jmh; + +import org.springframework.cloud.sleuth.autoconfig.instrument.reactor.SleuthReactorProperties; + +public class Pair { + final String key; + final String value; + + public Pair(String key, String value) { + this.key = key; + this.value = value; + } + + public String asProp() { + return this.key + "=" + this.value; + } + + public static Pair of(String key, String value) { + return new Pair(key, value); + } + + public static Pair onHook() { + return new Pair("spring.sleuth.reactor.instrumentation-type", SleuthReactorProperties.InstrumentationType.DECORATE_QUEUES.name()); + } + + public static Pair noSleuth() { + return new Pair("spring.sleuth.enabled", "false"); + } + + public static Pair onEach() { + return new Pair("spring.sleuth.reactor.instrumentation-type", SleuthReactorProperties.InstrumentationType.DECORATE_ON_EACH.name()); + } + + public static Pair decorateQueues() { + return new Pair("spring.sleuth.reactor.instrumentation-type", SleuthReactorProperties.InstrumentationType.DECORATE_QUEUES.name()); + } + + public static Pair manual() { + return new Pair("spring.sleuth.reactor.instrumentation-type", SleuthReactorProperties.InstrumentationType.MANUAL.name()); + } + + public static Pair onLast() { + return new Pair("spring.sleuth.reactor.instrumentation-type", SleuthReactorProperties.InstrumentationType.DECORATE_ON_LAST.name()); + } +} diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/ProcessLauncherState.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/ProcessLauncherState.java index 7a57bfc13..26899d5d4 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/ProcessLauncherState.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/ProcessLauncherState.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2021 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. diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/SampleTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/SampleTests.java index 3cadc3077..9da2c9478 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/SampleTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/SampleTests.java @@ -1,163 +1,163 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.benchmarks.jmh; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import brave.Tracing; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.openjdk.jmh.annotations.Param; -import org.openjdk.jmh.annotations.Setup; -import org.openjdk.jmh.annotations.TearDown; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.sleuth.benchmarks.app.stream.SleuthBenchmarkingStreamApplication; -import org.springframework.cloud.stream.binder.test.InputDestination; -import org.springframework.cloud.stream.binder.test.OutputDestination; -import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.messaging.Message; -import org.springframework.messaging.support.MessageBuilder; -import org.springframework.util.StringUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -@Disabled -public class SampleTests { - - @Test - public void testStream() throws Exception { - for (BenchmarkContext.Instrumentation value : BenchmarkContext.Instrumentation.values()) { - run(value); - } - // run(BenchmarkContext.Instrumentation.sleuthReactiveSimpleManual); - } - - private void run(BenchmarkContext.Instrumentation value) throws Exception { - BenchmarkContext context = new BenchmarkContext(); - System.out.println("\n\n\n\n WILL WORK WITH [" + value + "]\n\n\n\n"); - context.instrumentation = value; - context.setup(); - - try { - context.run(value); - } - finally { - context.clean(); - } - System.out.println("\n\n FINISHED WITH [" + value + "]\n\n\n\n"); - } - - public static class BenchmarkContext { - - volatile ConfigurableApplicationContext applicationContext; - - volatile InputDestination input; - - volatile OutputDestination output; - - @Param - private Instrumentation instrumentation; - - @Setup - public void setup() { - this.applicationContext = initContext(); - this.input = this.applicationContext.getBean(InputDestination.class); - this.output = this.applicationContext.getBean(OutputDestination.class); - } - - protected ConfigurableApplicationContext initContext() { - SpringApplication application = new SpringApplicationBuilder(SleuthBenchmarkingStreamApplication.class) - .web(WebApplicationType.REACTIVE).application(); - return application.run(runArgs()); - } - - protected String[] runArgs() { - List strings = new ArrayList<>(); - strings.addAll(Arrays.asList("--spring.jmx.enabled=false", - "--spring.application.name=defaultTraceContextForStream" + instrumentation.name())); - strings.addAll(instrumentation.entires.stream().map(s -> "--" + s).collect(Collectors.toList())); - return strings.toArray(new String[0]); - } - - void run(Instrumentation value) { - System.out.println("Sending the message to input"); - input.send(MessageBuilder.withPayload("hello".getBytes()) - .setHeader("b3", "4883117762eb9420-4883117762eb9420-1").build()); - System.out.println("Retrieving the message for tests"); - Message message = output.receive(200L); - System.out.println("Got the message from output"); - assertThat(message).isNotNull(); - System.out.println("Message is not null"); - assertThat(message.getPayload()).isEqualTo("HELLO".getBytes()); - System.out.println("Payload is HELLO"); - if (!value.toString().toLowerCase().contains("nosleuth")) { - String b3 = message.getHeaders().get("b3", String.class); - System.out.println("Checking the b3 header [" + b3 + "]"); - assertThat(b3).startsWith("4883117762eb9420"); - } - } - - @TearDown - public void clean() throws Exception { - Tracing current = Tracing.current(); - if (current != null) { - current.close(); - } - try { - this.applicationContext.close(); - } - catch (Exception ig) { - - } - } - - public enum Instrumentation { - - noSleuthSimple("spring.sleuth.enabled=false,spring.sleuth.function.type=simple"); - - private Set entires = new HashSet<>(); - - Instrumentation(String key, String value) { - this.entires.add(key + "=" + value); - } - - Instrumentation(String commaSeparated) { - this.entires.addAll(StringUtils.commaDelimitedListToSet(commaSeparated)); - } - - } - - } - - @Configuration(proxyBeanMethods = false) - @Import(TestChannelBinderConfiguration.class) - static class TestConfiguration { - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.benchmarks.jmh; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import brave.Tracing; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.TearDown; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.sleuth.benchmarks.app.stream.SleuthBenchmarkingStreamApplication; +import org.springframework.cloud.stream.binder.test.InputDestination; +import org.springframework.cloud.stream.binder.test.OutputDestination; +import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.util.StringUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +@Disabled +public class SampleTests { + + @Test + public void testStream() throws Exception { + for (BenchmarkContext.Instrumentation value : BenchmarkContext.Instrumentation.values()) { + run(value); + } + // run(BenchmarkContext.Instrumentation.sleuthReactiveSimpleManual); + } + + private void run(BenchmarkContext.Instrumentation value) throws Exception { + BenchmarkContext context = new BenchmarkContext(); + System.out.println("\n\n\n\n WILL WORK WITH [" + value + "]\n\n\n\n"); + context.instrumentation = value; + context.setup(); + + try { + context.run(value); + } + finally { + context.clean(); + } + System.out.println("\n\n FINISHED WITH [" + value + "]\n\n\n\n"); + } + + public static class BenchmarkContext { + + volatile ConfigurableApplicationContext applicationContext; + + volatile InputDestination input; + + volatile OutputDestination output; + + @Param + private Instrumentation instrumentation; + + @Setup + public void setup() { + this.applicationContext = initContext(); + this.input = this.applicationContext.getBean(InputDestination.class); + this.output = this.applicationContext.getBean(OutputDestination.class); + } + + protected ConfigurableApplicationContext initContext() { + SpringApplication application = new SpringApplicationBuilder(SleuthBenchmarkingStreamApplication.class) + .web(WebApplicationType.REACTIVE).application(); + return application.run(runArgs()); + } + + protected String[] runArgs() { + List strings = new ArrayList<>(); + strings.addAll(Arrays.asList("--spring.jmx.enabled=false", + "--spring.application.name=defaultTraceContextForStream" + instrumentation.name())); + strings.addAll(instrumentation.entires.stream().map(s -> "--" + s).collect(Collectors.toList())); + return strings.toArray(new String[0]); + } + + void run(Instrumentation value) { + System.out.println("Sending the message to input"); + input.send(MessageBuilder.withPayload("hello".getBytes()) + .setHeader("b3", "4883117762eb9420-4883117762eb9420-1").build()); + System.out.println("Retrieving the message for tests"); + Message message = output.receive(200L); + System.out.println("Got the message from output"); + assertThat(message).isNotNull(); + System.out.println("Message is not null"); + assertThat(message.getPayload()).isEqualTo("HELLO".getBytes()); + System.out.println("Payload is HELLO"); + if (!value.toString().toLowerCase().contains("nosleuth")) { + String b3 = message.getHeaders().get("b3", String.class); + System.out.println("Checking the b3 header [" + b3 + "]"); + assertThat(b3).startsWith("4883117762eb9420"); + } + } + + @TearDown + public void clean() throws Exception { + Tracing current = Tracing.current(); + if (current != null) { + current.close(); + } + try { + this.applicationContext.close(); + } + catch (Exception ig) { + + } + } + + public enum Instrumentation { + + noSleuthSimple("spring.sleuth.enabled=false,spring.sleuth.function.type=simple"); + + private Set entires = new HashSet<>(); + + Instrumentation(String key, String value) { + this.entires.add(key + "=" + value); + } + + Instrumentation(String commaSeparated) { + this.entires.addAll(StringUtils.commaDelimitedListToSet(commaSeparated)); + } + + } + + } + + @Configuration(proxyBeanMethods = false) + @Import(TestChannelBinderConfiguration.class) + static class TestConfiguration { + + } + +} diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/TracerImplementation.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/TracerImplementation.java index 75fa5373b..348c8ff61 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/TracerImplementation.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/TracerImplementation.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2021 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. diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/bridge/BridgeTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/bridge/BridgeTests.java index f14424c77..ab4a7f5af 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/bridge/BridgeTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/bridge/BridgeTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2021 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. diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AnnotationBenchmarksTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AnnotationBenchmarksTests.java index 16b014d0a..a4b4ad197 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AnnotationBenchmarksTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AnnotationBenchmarksTests.java @@ -1,88 +1,88 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.benchmarks.jmh.mvc; - -import java.util.concurrent.TimeUnit; - -import jmh.mbr.junit5.Microbenchmark; -import org.openjdk.jmh.annotations.Benchmark; -import org.openjdk.jmh.annotations.BenchmarkMode; -import org.openjdk.jmh.annotations.Fork; -import org.openjdk.jmh.annotations.Measurement; -import org.openjdk.jmh.annotations.Mode; -import org.openjdk.jmh.annotations.OutputTimeUnit; -import org.openjdk.jmh.annotations.Param; -import org.openjdk.jmh.annotations.Scope; -import org.openjdk.jmh.annotations.Setup; -import org.openjdk.jmh.annotations.State; -import org.openjdk.jmh.annotations.TearDown; -import org.openjdk.jmh.annotations.Threads; -import org.openjdk.jmh.annotations.Warmup; - -import org.springframework.boot.SpringApplication; -import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; -import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; -import org.springframework.context.ConfigurableApplicationContext; - -import static org.assertj.core.api.BDDAssertions.then; - -@Measurement(iterations = 5, time = 1) -@Warmup(iterations = 5, time = 1) -@Fork(2) -@BenchmarkMode(Mode.SampleTime) -@OutputTimeUnit(TimeUnit.MICROSECONDS) -@Threads(Threads.MAX) -@Microbenchmark -public class AnnotationBenchmarksTests { - - @Benchmark - public void manuallyCreatedSpans(BenchmarkContext context) throws Exception { - then(context.sleuth.manualSpan()).isEqualTo("continued"); - } - - @Benchmark - public void spanCreatedWithAnnotations(BenchmarkContext context) throws Exception { - then(context.sleuth.newSpan()).isEqualTo("continued"); - } - - @State(Scope.Benchmark) - public static class BenchmarkContext { - - volatile ConfigurableApplicationContext withSleuth; - - volatile SleuthBenchmarkingSpringApp sleuth; - - @Param - private TracerImplementation tracerImplementation; - - @Setup - public void setup() { - this.withSleuth = new SpringApplication(SleuthBenchmarkingSpringApp.class).run("--spring.jmx.enabled=false", - - "--spring.application.name=withSleuth_" + this.tracerImplementation.name()); - this.sleuth = this.withSleuth.getBean(SleuthBenchmarkingSpringApp.class); - } - - @TearDown - public void clean() { - this.sleuth.clean(); - this.withSleuth.close(); - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.benchmarks.jmh.mvc; + +import java.util.concurrent.TimeUnit; + +import jmh.mbr.junit5.Microbenchmark; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; + +import org.springframework.boot.SpringApplication; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; +import org.springframework.context.ConfigurableApplicationContext; + +import static org.assertj.core.api.BDDAssertions.then; + +@Measurement(iterations = 10, time = 1) +@Warmup(iterations = 10, time = 1) +@Fork(4) +@BenchmarkMode(Mode.SampleTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Threads(Threads.MAX) +@Microbenchmark +public class AnnotationBenchmarksTests { + + @Benchmark + public void manuallyCreatedSpans(BenchmarkContext context) throws Exception { + then(context.sleuth.manualSpan()).isEqualTo("continued"); + } + + @Benchmark + public void spanCreatedWithAnnotations(BenchmarkContext context) throws Exception { + then(context.sleuth.newSpan()).isEqualTo("continued"); + } + + @State(Scope.Benchmark) + public static class BenchmarkContext { + + volatile ConfigurableApplicationContext withSleuth; + + volatile SleuthBenchmarkingSpringApp sleuth; + + @Param + private TracerImplementation tracerImplementation; + + @Setup + public void setup() { + this.withSleuth = new SpringApplication(SleuthBenchmarkingSpringApp.class).run("--spring.jmx.enabled=false", + + "--spring.application.name=withSleuth_" + this.tracerImplementation.name()); + this.sleuth = this.withSleuth.getBean(SleuthBenchmarkingSpringApp.class); + } + + @TearDown + public void clean() { + this.sleuth.clean(); + this.withSleuth.close(); + } + + } + +} diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithSleuthBenchmarksTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithSleuthBenchmarksTests.java index 3869b98fa..cd1b74f30 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithSleuthBenchmarksTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithSleuthBenchmarksTests.java @@ -1,81 +1,81 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.benchmarks.jmh.mvc; - -import java.util.concurrent.TimeUnit; - -import jmh.mbr.junit5.Microbenchmark; -import org.openjdk.jmh.annotations.Benchmark; -import org.openjdk.jmh.annotations.BenchmarkMode; -import org.openjdk.jmh.annotations.Fork; -import org.openjdk.jmh.annotations.Measurement; -import org.openjdk.jmh.annotations.Mode; -import org.openjdk.jmh.annotations.OutputTimeUnit; -import org.openjdk.jmh.annotations.Param; -import org.openjdk.jmh.annotations.Scope; -import org.openjdk.jmh.annotations.Setup; -import org.openjdk.jmh.annotations.State; -import org.openjdk.jmh.annotations.TearDown; -import org.openjdk.jmh.annotations.Threads; -import org.openjdk.jmh.annotations.Warmup; - -import org.springframework.boot.SpringApplication; -import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; -import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; -import org.springframework.context.ConfigurableApplicationContext; - -import static org.assertj.core.api.BDDAssertions.then; - -@Measurement(iterations = 5, time = 1) -@Warmup(iterations = 5, time = 1) -@Fork(2) -@BenchmarkMode(Mode.SampleTime) -@OutputTimeUnit(TimeUnit.MICROSECONDS) -@Threads(Threads.MAX) -@Microbenchmark -public class AsyncWithSleuthBenchmarksTests { - @Benchmark - public void asyncMethodWithSleuth(BenchmarkContext context) throws Exception { - then(context.app.async().get()).isEqualTo("async"); - } - - @State(Scope.Benchmark) - public static class BenchmarkContext { - volatile ConfigurableApplicationContext context; - volatile SleuthBenchmarkingSpringApp app; - - @Param - private TracerImplementation tracerImplementation; - - @Setup - public void setup() { - this.context = new SpringApplication(SleuthBenchmarkingSpringApp.class).run( - "--spring.jmx.enabled=false", - "--spring.application.name=withSleuth_" + this.tracerImplementation.name() - ); - this.app = this.context.getBean(SleuthBenchmarkingSpringApp.class); - } - - @TearDown - public void clean() { - this.app.clean(); - this.context.close(); - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.benchmarks.jmh.mvc; + +import java.util.concurrent.TimeUnit; + +import jmh.mbr.junit5.Microbenchmark; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; + +import org.springframework.boot.SpringApplication; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; +import org.springframework.context.ConfigurableApplicationContext; + +import static org.assertj.core.api.BDDAssertions.then; + +@Measurement(iterations = 5, time = 1) +@Warmup(iterations = 5, time = 1) +@Fork(2) +@BenchmarkMode(Mode.SampleTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Threads(Threads.MAX) +@Microbenchmark +public class AsyncWithSleuthBenchmarksTests { + @Benchmark + public void asyncMethodWithSleuth(BenchmarkContext context) throws Exception { + then(context.app.async().get()).isEqualTo("async"); + } + + @State(Scope.Benchmark) + public static class BenchmarkContext { + volatile ConfigurableApplicationContext context; + volatile SleuthBenchmarkingSpringApp app; + + @Param + private TracerImplementation tracerImplementation; + + @Setup + public void setup() { + this.context = new SpringApplication(SleuthBenchmarkingSpringApp.class).run( + "--spring.jmx.enabled=false", + "--spring.application.name=withSleuth_" + this.tracerImplementation.name() + ); + this.app = this.context.getBean(SleuthBenchmarkingSpringApp.class); + } + + @TearDown + public void clean() { + this.app.clean(); + this.context.close(); + } + + } + +} diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithoutSleuthBenchmarksTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithoutSleuthBenchmarksTests.java index 868e41efc..f97f64c55 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithoutSleuthBenchmarksTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithoutSleuthBenchmarksTests.java @@ -1,78 +1,78 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.benchmarks.jmh.mvc; - -import java.util.concurrent.TimeUnit; - -import jmh.mbr.junit5.Microbenchmark; -import org.openjdk.jmh.annotations.Benchmark; -import org.openjdk.jmh.annotations.BenchmarkMode; -import org.openjdk.jmh.annotations.Fork; -import org.openjdk.jmh.annotations.Measurement; -import org.openjdk.jmh.annotations.Mode; -import org.openjdk.jmh.annotations.OutputTimeUnit; -import org.openjdk.jmh.annotations.Scope; -import org.openjdk.jmh.annotations.Setup; -import org.openjdk.jmh.annotations.State; -import org.openjdk.jmh.annotations.TearDown; -import org.openjdk.jmh.annotations.Threads; -import org.openjdk.jmh.annotations.Warmup; - -import org.springframework.boot.SpringApplication; -import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; -import org.springframework.context.ConfigurableApplicationContext; - -import static org.assertj.core.api.BDDAssertions.then; - -@Measurement(iterations = 5, time = 1) -@Warmup(iterations = 5, time = 1) -@Fork(2) -@BenchmarkMode(Mode.SampleTime) -@OutputTimeUnit(TimeUnit.MICROSECONDS) -@Threads(Threads.MAX) -@Microbenchmark -public class AsyncWithoutSleuthBenchmarksTests { - @Benchmark - public void asyncMethodWithoutSleuth(BenchmarkContext context) throws Exception { - then(context.app.async().get()).isEqualTo("async"); - } - - @State(Scope.Benchmark) - public static class BenchmarkContext { - volatile ConfigurableApplicationContext context; - volatile SleuthBenchmarkingSpringApp app; - - @Setup - public void setup() { - this.context = new SpringApplication(SleuthBenchmarkingSpringApp.class).run( - "--spring.jmx.enabled=false", - "--spring.application.name=withoutSleuth", - "--spring.sleuth.enabled=false", - "--spring.sleuth.async.enabled=false" - ); - this.app = this.context.getBean(SleuthBenchmarkingSpringApp.class); - } - - @TearDown - public void clean() { - this.app.clean(); - this.context.close(); - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.benchmarks.jmh.mvc; + +import java.util.concurrent.TimeUnit; + +import jmh.mbr.junit5.Microbenchmark; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; + +import org.springframework.boot.SpringApplication; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; +import org.springframework.context.ConfigurableApplicationContext; + +import static org.assertj.core.api.BDDAssertions.then; + +@Measurement(iterations = 5, time = 1) +@Warmup(iterations = 5, time = 1) +@Fork(2) +@BenchmarkMode(Mode.SampleTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Threads(Threads.MAX) +@Microbenchmark +public class AsyncWithoutSleuthBenchmarksTests { + @Benchmark + public void asyncMethodWithoutSleuth(BenchmarkContext context) throws Exception { + then(context.app.async().get()).isEqualTo("async"); + } + + @State(Scope.Benchmark) + public static class BenchmarkContext { + volatile ConfigurableApplicationContext context; + volatile SleuthBenchmarkingSpringApp app; + + @Setup + public void setup() { + this.context = new SpringApplication(SleuthBenchmarkingSpringApp.class).run( + "--spring.jmx.enabled=false", + "--spring.application.name=withoutSleuth", + "--spring.sleuth.enabled=false", + "--spring.sleuth.async.enabled=false" + ); + this.app = this.context.getBean(SleuthBenchmarkingSpringApp.class); + } + + @TearDown + public void clean() { + this.app.clean(); + this.context.close(); + } + + } + +} diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterBenchmarksTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterBenchmarksTests.java index 91570bf0c..05b3a871f 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterBenchmarksTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterBenchmarksTests.java @@ -1,187 +1,167 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.benchmarks.jmh.mvc; - -import java.io.IOException; -import java.util.concurrent.Callable; -import java.util.concurrent.TimeUnit; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import jmh.mbr.junit5.Microbenchmark; -import org.openjdk.jmh.annotations.Benchmark; -import org.openjdk.jmh.annotations.BenchmarkMode; -import org.openjdk.jmh.annotations.Fork; -import org.openjdk.jmh.annotations.Measurement; -import org.openjdk.jmh.annotations.Mode; -import org.openjdk.jmh.annotations.OutputTimeUnit; -import org.openjdk.jmh.annotations.Param; -import org.openjdk.jmh.annotations.Scope; -import org.openjdk.jmh.annotations.Setup; -import org.openjdk.jmh.annotations.State; -import org.openjdk.jmh.annotations.TearDown; -import org.openjdk.jmh.annotations.Threads; -import org.openjdk.jmh.annotations.Warmup; - -import org.springframework.boot.SpringApplication; -import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; -import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; -import org.springframework.cloud.sleuth.benchmarks.app.mvc.controller.AsyncSimulationController; -import org.springframework.cloud.sleuth.instrument.web.servlet.TracingFilter; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.http.MediaType; -import org.springframework.mock.web.MockFilterChain; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.mock.web.MockServletContext; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.MvcResult; -import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -@Warmup(iterations = 5) -@BenchmarkMode(Mode.SampleTime) -@OutputTimeUnit(TimeUnit.MICROSECONDS) -@Threads(Threads.MAX) -@Microbenchmark -public class HttpFilterBenchmarksTests { - - @Benchmark - @Measurement(iterations = 5, time = 1) - @Fork(2) - public void filterWithoutSleuth(BenchmarkContext context) throws IOException, ServletException { - MockHttpServletRequest request = builder().buildRequest(new MockServletContext()); - MockHttpServletResponse response = new MockHttpServletResponse(); - response.setContentType(MediaType.APPLICATION_JSON_VALUE); - - context.dummyFilter.doFilter(request, response, new MockFilterChain()); - } - - @Benchmark - @Measurement(iterations = 5, time = 1) - @Fork(2) - public void filterWithSleuth(BenchmarkContext context) throws ServletException, IOException { - MockHttpServletRequest request = builder().buildRequest(new MockServletContext()); - MockHttpServletResponse response = new MockHttpServletResponse(); - response.setContentType(MediaType.APPLICATION_JSON_VALUE); - - context.tracingFilter.doFilter(request, response, new MockFilterChain()); - } - - @Benchmark - @Measurement(iterations = 5, time = 10) - @Fork(10) - public void asyncWithoutSleuth(BenchmarkContext context) throws Exception { - performRequest(context.mockMvcForUntracedController, "vanilla", "vanilla"); - } - - @Benchmark - @Measurement(iterations = 5, time = 10) - @Fork(10) - public void asyncWithSleuth(BenchmarkContext context) throws Exception { - performRequest(context.mockMvcForTracedController, "bar", "bar"); - } - - private MockHttpServletRequestBuilder builder() { - return get("/").accept(MediaType.APPLICATION_JSON).header("User-Agent", "MockMvc"); - } - - private void performRequest(MockMvc mockMvc, String url, String expectedResult) throws Exception { - MvcResult mvcResult = mockMvc.perform(get("/" + url)).andExpect(status().isOk()) - .andExpect(request().asyncStarted()).andReturn(); - - mockMvc.perform(asyncDispatch(mvcResult)).andExpect(status().isOk()) - .andExpect(content().string(expectedResult)); - } - - @State(Scope.Benchmark) - public static class BenchmarkContext { - - volatile ConfigurableApplicationContext withSleuth; - - volatile DummyFilter dummyFilter = new DummyFilter(); - - volatile TracingFilter tracingFilter; - - volatile MockMvc mockMvcForTracedController; - - volatile MockMvc mockMvcForUntracedController; - - @Param - private TracerImplementation tracerImplementation; - - @Setup - public void setup() { - this.withSleuth = new SpringApplication(SleuthBenchmarkingSpringApp.class).run("--spring.jmx.enabled=false", - - "--spring.application.name=withSleuth_" + this.tracerImplementation.name()); - this.tracingFilter = this.withSleuth.getBean(TracingFilter.class); - this.mockMvcForTracedController = MockMvcBuilders - .standaloneSetup(this.withSleuth.getBean(AsyncSimulationController.class)).build(); - this.mockMvcForUntracedController = MockMvcBuilders.standaloneSetup(new VanillaController()).build(); - } - - @TearDown - public void clean() { - this.withSleuth.getBean(SleuthBenchmarkingSpringApp.class).clean(); - this.withSleuth.close(); - } - - } - - private static class DummyFilter implements Filter { - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws IOException, ServletException { - chain.doFilter(request, response); - } - - @Override - public void destroy() { - } - - } - - @RestController - private static class VanillaController { - - @RequestMapping("/vanilla") - public Callable vanilla() { - return () -> "vanilla"; - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.benchmarks.jmh.mvc; + +import java.io.IOException; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import jmh.mbr.junit5.Microbenchmark; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; + +import org.springframework.boot.SpringApplication; +import org.springframework.cloud.sleuth.CurrentTraceContext; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.controller.AsyncSimulationController; +import org.springframework.cloud.sleuth.http.HttpServerHandler; +import org.springframework.cloud.sleuth.instrument.web.servlet.TracingFilter; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.http.MediaType; +import org.springframework.mock.web.MockFilterChain; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.mock.web.MockServletContext; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@Warmup(iterations = 5) +@Measurement(iterations = 10, time = 1) +@Fork(2) +@BenchmarkMode(Mode.SampleTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Threads(Threads.MAX) +@Microbenchmark +public class HttpFilterBenchmarksTests { + + @Benchmark + public void filterWithSleuth(BenchmarkContext context) throws ServletException, IOException { + MockHttpServletRequest request = builder().buildRequest(new MockServletContext()); + MockHttpServletResponse response = new MockHttpServletResponse(); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + + context.tracingFilter.doFilter(request, response, new MockFilterChain()); + } + + @Benchmark + public void asyncWithSleuth(BenchmarkContext context) throws Exception { + performRequest(context.mockMvcForTracedController, "bar", "bar"); + } + + private MockHttpServletRequestBuilder builder() { + return get("/").accept(MediaType.APPLICATION_JSON).header("User-Agent", "MockMvc"); + } + + private void performRequest(MockMvc mockMvc, String url, String expectedResult) throws Exception { + MvcResult mvcResult = mockMvc.perform(get("/" + url)).andExpect(status().isOk()) + .andExpect(request().asyncStarted()).andReturn(); + + mockMvc.perform(asyncDispatch(mvcResult)).andExpect(status().isOk()) + .andExpect(content().string(expectedResult)); + } + + @State(Scope.Benchmark) + public static class BenchmarkContext { + + volatile ConfigurableApplicationContext withSleuth; + + volatile TracingFilter tracingFilter; + + volatile MockMvc mockMvcForTracedController; + + @Param + private TracerImplementation tracerImplementation; + + @Setup + public void setup() { + this.withSleuth = new SpringApplication(SleuthBenchmarkingSpringApp.class).run("--spring.jmx.enabled=false", + + "--spring.application.name=withSleuth_" + this.tracerImplementation.name()); + assertThat(this.withSleuth.getBeanProvider(Tracer.class).getIfAvailable(() -> null)).isNotNull(); + this.tracingFilter = TracingFilter.create(this.withSleuth.getBean(CurrentTraceContext.class), this.withSleuth.getBean(HttpServerHandler.class)); + this.mockMvcForTracedController = MockMvcBuilders + .standaloneSetup(this.withSleuth.getBean(AsyncSimulationController.class)).build(); + } + + @TearDown + public void clean() { + this.withSleuth.getBean(SleuthBenchmarkingSpringApp.class).clean(); + this.withSleuth.close(); + } + + } + + private static class DummyFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + chain.doFilter(request, response); + } + + @Override + public void destroy() { + } + + } + + @RestController + private static class VanillaController { + + @RequestMapping("/vanilla") + public Callable vanilla() { + return () -> "vanilla"; + } + + } + +} diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterNoSleuthBenchmarksTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterNoSleuthBenchmarksTests.java new file mode 100644 index 000000000..bbab91076 --- /dev/null +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterNoSleuthBenchmarksTests.java @@ -0,0 +1,161 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.benchmarks.jmh.mvc; + +import java.io.IOException; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import jmh.mbr.junit5.Microbenchmark; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; + +import org.springframework.boot.SpringApplication; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.http.MediaType; +import org.springframework.mock.web.MockFilterChain; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.mock.web.MockServletContext; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@Warmup(iterations = 5) +@Measurement(iterations = 10, time = 1) +@Fork(2) +@BenchmarkMode(Mode.SampleTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Threads(Threads.MAX) +@Microbenchmark +public class HttpFilterNoSleuthBenchmarksTests { + + @Benchmark + public void filterWithoutSleuth(BenchmarkContext context) throws IOException, ServletException { + MockHttpServletRequest request = builder().buildRequest(new MockServletContext()); + MockHttpServletResponse response = new MockHttpServletResponse(); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + + context.dummyFilter.doFilter(request, response, new MockFilterChain()); + } + + @Benchmark + public void asyncWithoutSleuth(BenchmarkContext context) throws Exception { + performRequest(context.mockMvcForUntracedController, "vanilla", "vanilla"); + } + + private MockHttpServletRequestBuilder builder() { + return get("/").accept(MediaType.APPLICATION_JSON).header("User-Agent", "MockMvc"); + } + + private void performRequest(MockMvc mockMvc, String url, String expectedResult) throws Exception { + MvcResult mvcResult = mockMvc.perform(get("/" + url)).andExpect(status().isOk()) + .andExpect(request().asyncStarted()).andReturn(); + + mockMvc.perform(asyncDispatch(mvcResult)).andExpect(status().isOk()) + .andExpect(content().string(expectedResult)); + } + + @State(Scope.Benchmark) + public static class BenchmarkContext { + + volatile ConfigurableApplicationContext app; + + volatile DummyFilter dummyFilter = new DummyFilter(); + + volatile MockMvc mockMvcForUntracedController; + + @Param + private TracerImplementation tracerImplementation; + + @Setup + public void setup() { + this.app = new SpringApplication(SleuthBenchmarkingSpringApp.class).run("--spring.jmx.enabled=false", "--spring.sleuth.enabled=false", + + "--spring.application.name=noSleuth_" + this.tracerImplementation.name()); + assertThat(this.app.getBeanProvider(Tracer.class).getIfAvailable(() -> null)).isNull(); + this.mockMvcForUntracedController = MockMvcBuilders.standaloneSetup(new VanillaController()).build(); + } + + @TearDown + public void clean() { + this.app.getBean(SleuthBenchmarkingSpringApp.class).clean(); + this.app.close(); + } + + } + + private static class DummyFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + chain.doFilter(request, response); + } + + @Override + public void destroy() { + } + + } + + @RestController + private static class VanillaController { + + @RequestMapping("/vanilla") + public Callable vanilla() { + return () -> "vanilla"; + } + + } + +} diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/RestTemplateBenchmarkTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/RestTemplateBenchmarkTests.java index 6066b8274..a5ad1d1d5 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/RestTemplateBenchmarkTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/RestTemplateBenchmarkTests.java @@ -1,111 +1,111 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.benchmarks.jmh.mvc; - -import java.io.IOException; -import java.util.Collections; -import java.util.concurrent.TimeUnit; - -import javax.servlet.ServletException; - -import jmh.mbr.junit5.Microbenchmark; -import org.openjdk.jmh.annotations.Benchmark; -import org.openjdk.jmh.annotations.BenchmarkMode; -import org.openjdk.jmh.annotations.Fork; -import org.openjdk.jmh.annotations.Measurement; -import org.openjdk.jmh.annotations.Mode; -import org.openjdk.jmh.annotations.OutputTimeUnit; -import org.openjdk.jmh.annotations.Param; -import org.openjdk.jmh.annotations.Scope; -import org.openjdk.jmh.annotations.Setup; -import org.openjdk.jmh.annotations.State; -import org.openjdk.jmh.annotations.TearDown; -import org.openjdk.jmh.annotations.Threads; -import org.openjdk.jmh.annotations.Warmup; - -import org.springframework.boot.SpringApplication; -import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; -import org.springframework.cloud.sleuth.benchmarks.app.mvc.controller.AsyncSimulationController; -import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; -import org.springframework.cloud.sleuth.instrument.web.mvc.TracingClientHttpRequestInterceptor; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.test.web.client.MockMvcClientHttpRequestFactory; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * We're checking how much overhead does the instrumentation of the RestTemplate take - */ -@Measurement(iterations = 5, time = 1) -@Warmup(iterations = 5, time = 1) -@Fork(2) -@BenchmarkMode(Mode.SampleTime) -@OutputTimeUnit(TimeUnit.MICROSECONDS) -@Threads(Threads.MAX) -@Microbenchmark -public class RestTemplateBenchmarkTests { - - @Benchmark - public void syncEndpointWithoutSleuth(BenchmarkContext context) throws IOException, ServletException { - then(context.untracedTemplate.getForObject("/foo", String.class)).isEqualTo("foo"); - } - - @Benchmark - public void syncEndpointWithSleuth(BenchmarkContext context) throws ServletException, IOException { - then(context.tracedTemplate.getForObject("/foo", String.class)).isEqualTo("foo"); - } - - @State(Scope.Benchmark) - public static class BenchmarkContext { - - volatile ConfigurableApplicationContext withSleuth; - - volatile MockMvc mockMvc; - - volatile RestTemplate tracedTemplate; - - volatile RestTemplate untracedTemplate; - - @Param - private TracerImplementation tracerImplementation; - - @Setup - public void setup() { - this.withSleuth = new SpringApplication(SleuthBenchmarkingSpringApp.class).run( - "--spring.jmx.enabled=false", - "--spring.application.name=withSleuth_" + this.tracerImplementation.name() - ); - this.mockMvc = MockMvcBuilders.standaloneSetup(this.withSleuth.getBean(AsyncSimulationController.class)) - .build(); - this.tracedTemplate = new RestTemplate(new MockMvcClientHttpRequestFactory(this.mockMvc)); - this.tracedTemplate.setInterceptors( - Collections.singletonList(this.withSleuth.getBean(TracingClientHttpRequestInterceptor.class))); - this.untracedTemplate = new RestTemplate(new MockMvcClientHttpRequestFactory(this.mockMvc)); - } - - @TearDown - public void clean() { - this.withSleuth.getBean(SleuthBenchmarkingSpringApp.class).clean(); - this.withSleuth.close(); - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.benchmarks.jmh.mvc; + +import java.io.IOException; +import java.util.Collections; +import java.util.concurrent.TimeUnit; + +import javax.servlet.ServletException; + +import jmh.mbr.junit5.Microbenchmark; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; + +import org.springframework.boot.SpringApplication; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.controller.AsyncSimulationController; +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; +import org.springframework.cloud.sleuth.instrument.web.mvc.TracingClientHttpRequestInterceptor; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.test.web.client.MockMvcClientHttpRequestFactory; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.client.RestTemplate; + +import static org.assertj.core.api.BDDAssertions.then; + +/** + * We're checking how much overhead does the instrumentation of the RestTemplate take + */ +@Measurement(iterations = 5, time = 1) +@Warmup(iterations = 5, time = 1) +@Fork(2) +@BenchmarkMode(Mode.SampleTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Threads(Threads.MAX) +@Microbenchmark +public class RestTemplateBenchmarkTests { + + @Benchmark + public void syncEndpointWithoutSleuth(BenchmarkContext context) throws IOException, ServletException { + then(context.untracedTemplate.getForObject("/foo", String.class)).isEqualTo("foo"); + } + + @Benchmark + public void syncEndpointWithSleuth(BenchmarkContext context) throws ServletException, IOException { + then(context.tracedTemplate.getForObject("/foo", String.class)).isEqualTo("foo"); + } + + @State(Scope.Benchmark) + public static class BenchmarkContext { + + volatile ConfigurableApplicationContext withSleuth; + + volatile MockMvc mockMvc; + + volatile RestTemplate tracedTemplate; + + volatile RestTemplate untracedTemplate; + + @Param + private TracerImplementation tracerImplementation; + + @Setup + public void setup() { + this.withSleuth = new SpringApplication(SleuthBenchmarkingSpringApp.class).run( + "--spring.jmx.enabled=false", + "--spring.application.name=withSleuth_" + this.tracerImplementation.name() + ); + this.mockMvc = MockMvcBuilders.standaloneSetup(this.withSleuth.getBean(AsyncSimulationController.class)) + .build(); + this.tracedTemplate = new RestTemplate(new MockMvcClientHttpRequestFactory(this.mockMvc)); + this.tracedTemplate.setInterceptors( + Collections.singletonList(this.withSleuth.getBean(TracingClientHttpRequestInterceptor.class))); + this.untracedTemplate = new RestTemplate(new MockMvcClientHttpRequestFactory(this.mockMvc)); + } + + @TearDown + public void clean() { + this.withSleuth.getBean(SleuthBenchmarkingSpringApp.class).clean(); + this.withSleuth.close(); + } + + } + +} diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/StartupBenchmarkTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/StartupBenchmarkTests.java index 63a6adc65..b57c195cd 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/StartupBenchmarkTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/StartupBenchmarkTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2021 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. diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/stream/MicroBenchmarkStreamTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/stream/MicroBenchmarkStreamTests.java index 6c332d407..bdc933410 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/stream/MicroBenchmarkStreamTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/stream/MicroBenchmarkStreamTests.java @@ -1,192 +1,207 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.benchmarks.jmh.stream; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import brave.Tracing; -import jmh.mbr.junit5.Microbenchmark; -import org.junit.platform.commons.annotation.Testable; -import org.openjdk.jmh.annotations.Benchmark; -import org.openjdk.jmh.annotations.BenchmarkMode; -import org.openjdk.jmh.annotations.Fork; -import org.openjdk.jmh.annotations.Measurement; -import org.openjdk.jmh.annotations.Mode; -import org.openjdk.jmh.annotations.OutputTimeUnit; -import org.openjdk.jmh.annotations.Param; -import org.openjdk.jmh.annotations.Scope; -import org.openjdk.jmh.annotations.Setup; -import org.openjdk.jmh.annotations.State; -import org.openjdk.jmh.annotations.TearDown; -import org.openjdk.jmh.annotations.Warmup; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.sleuth.benchmarks.app.stream.SleuthBenchmarkingStreamApplication; -import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; -import org.springframework.cloud.stream.binder.test.InputDestination; -import org.springframework.cloud.stream.binder.test.OutputDestination; -import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.messaging.Message; -import org.springframework.messaging.support.MessageBuilder; -import org.springframework.util.StringUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -@Measurement(iterations = 5, time = 1) -@Warmup(iterations = 5, time = 1) -@Fork(2) -@BenchmarkMode(Mode.SampleTime) -@OutputTimeUnit(TimeUnit.MILLISECONDS) -@Microbenchmark -public class MicroBenchmarkStreamTests { - - @Benchmark - @Testable - public void testStream(BenchmarkContext context) throws Exception { - context.run(); - } - - @State(Scope.Benchmark) - public static class BenchmarkContext { - - volatile ConfigurableApplicationContext applicationContext; - - volatile InputDestination input; - - volatile OutputDestination output; - - @Param - private Instrumentation instrumentation; - - @Param - private TracerImplementation tracerImplementation; - - @Setup - public void setup() { - this.applicationContext = initContext(); - this.input = this.applicationContext.getBean(InputDestination.class); - this.output = this.applicationContext.getBean(OutputDestination.class); - } - - private void sendInputMessage() { - // System.out.println("Sending the message to input"); - input.send(MessageBuilder.withPayload("hello".getBytes()) - .setHeader("b3", "4883117762eb9420-4883117762eb9420-1").build()); - } - - protected ConfigurableApplicationContext initContext() { - SpringApplication application = new SpringApplicationBuilder(SleuthBenchmarkingStreamApplication.class) - .web(WebApplicationType.NONE).application(); - return application.run(runArgs()); - } - - protected String[] runArgs() { - List strings = new ArrayList<>(); - strings.addAll(Arrays.asList("--spring.jmx.enabled=false", - "--spring.application.name=defaultTraceContextForStream" + instrumentation.name() + "_" - + tracerImplementation.name())); - strings.addAll(instrumentation.entires.stream().map(s -> "--" + s).collect(Collectors.toList())); - return strings.toArray(new String[0]); - } - - void run() { - sendInputMessage(); - assertThatOutputMessageGotReceived(); - } - - private void assertThatOutputMessageGotReceived() { - // System.out.println("Retrieving the message for tests"); - Message message = output.receive(200L); - // System.out.println("Got the message from output"); - assertThat(message).isNotNull(); - // System.out.println("Message is not null"); - assertThat(message.getPayload()).isEqualTo("HELLO".getBytes()); - // System.out.println("Payload is HELLO"); - if (!instrumentation.toString().toLowerCase().contains("nosleuth")) { - String b3 = message.getHeaders().get("b3", String.class); - // System.out.println("Checking the b3 header [" + b3 + "]"); - assertThat(b3).isNotEmpty(); - if (b3.startsWith("0000000000000000")) { - assertThat(b3).startsWith("00000000000000004883117762eb9420"); - } else { - assertThat(b3).startsWith("4883117762eb9420"); - } - } - } - - @TearDown - public void clean() throws Exception { - Tracing current = Tracing.current(); - if (current != null) { - current.close(); - } - try { - this.applicationContext.close(); - } - catch (Exception ig) { - - } - } - - public enum Instrumentation { - - noSleuthSimple("spring.sleuth.enabled=false,spring.sleuth.function.type=simple"), sleuthSimple( - "spring.sleuth.function.type=simple"), sleuthSimpleWithAround( - "spring.sleuth.function.type=simple_function_with_around"), noSleuthReactiveSimple( - "spring.sleuth.enabled=false,spring.sleuth.function.type=reactive_simple"), sleuthReactiveSimpleManual( - "spring.sleuth.function.type=reactive_simple_manual"), sleuthReactiveSimpleOnEach( - "spring.sleuth.reactor.instrumentation-type=DECORATE_ON_EACH,spring.sleuth.integration.enabled=true,spring.sleuth.function.type=DECORATE_ON_EACH"), - // This won't work with messaging - // sleuthReactiveSimpleOnLast("spring.sleuth.reactor.instrumentation-type=DECORATE_ON_LAST,spring.sleuth.function.type=DECORATE_ON_LAST"), - // NO FUNCTION, NO INTEGRATION, MANUAL OPERATORS - sleuthSimpleManual( - "spring.sleuth.function.enabled=false,spring.sleuth.integration.enabled=false,spring.sleuth.function.type=simple_manual"), sleuthSimpleNoFunctionInstrumentationManual( - "spring.sleuth.function.type=simple_manual,spring.sleuth.function.enabled=false,spring.sleuth.integration.enabled=true,spring.sleuth.reactor.instrumentation-type=MANUAL"), sleuthReactiveSimpleNoFunctionInstrumentationManual( - "spring.sleuth.function.type=reactive_simple_manual,spring.sleuth.function.enabled=false,spring.sleuth.integration.enabled=true,spring.sleuth.reactor.instrumentation-type=MANUAL"); - - private Set entires = new HashSet<>(); - - Instrumentation(String key, String value) { - this.entires.add(key + "=" + value); - } - - Instrumentation(String commaSeparated) { - this.entires.addAll(StringUtils.commaDelimitedListToSet(commaSeparated)); - } - - } - - } - - @Configuration(proxyBeanMethods = false) - @Import(TestChannelBinderConfiguration.class) - static class TestConfiguration { - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.benchmarks.jmh.stream; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import brave.Tracing; +import jmh.mbr.junit5.Microbenchmark; +import org.junit.platform.commons.annotation.Testable; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.benchmarks.app.stream.SleuthBenchmarkingStreamApplication; +import org.springframework.cloud.sleuth.benchmarks.jmh.Pair; +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; +import org.springframework.cloud.stream.binder.test.InputDestination; +import org.springframework.cloud.stream.binder.test.OutputDestination; +import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; + +import static org.assertj.core.api.Assertions.assertThat; + +@Measurement(iterations = 10, time = 1) +@Warmup(iterations = 10, time = 1) +@Fork(4) +@BenchmarkMode(Mode.SampleTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Microbenchmark +public class MicroBenchmarkStreamTests { + + @Benchmark + @Testable + public void testStream(BenchmarkContext context) throws Exception { + context.run(); + } + + @State(Scope.Benchmark) + public static class BenchmarkContext { + + volatile ConfigurableApplicationContext applicationContext; + + volatile InputDestination input; + + volatile OutputDestination output; + + @Param + private Instrumentation instrumentation; + + @Param + private TracerImplementation tracerImplementation; + + @Setup + public void setup() { + this.applicationContext = initContext(); + this.input = this.applicationContext.getBean(InputDestination.class); + this.output = this.applicationContext.getBean(OutputDestination.class); + } + + private void sendInputMessage() { + // System.out.println("Sending the message to input"); + input.send(MessageBuilder.withPayload("hello".getBytes()) + .setHeader("b3", "4883117762eb9420-4883117762eb9420-1").build()); + } + + protected ConfigurableApplicationContext initContext() { + SpringApplication application = new SpringApplicationBuilder(SleuthBenchmarkingStreamApplication.class) + .web(WebApplicationType.NONE).application(); + return application.run(runArgs()); + } + + protected String[] runArgs() { + List strings = new ArrayList<>(); + strings.addAll(Arrays.asList("--spring.jmx.enabled=false", + "--spring.application.name=defaultTraceContextForStream" + instrumentation.name() + "_" + + tracerImplementation.name())); + strings.addAll(Arrays.asList(instrumentation.asParams())); + return strings.toArray(new String[0]); + } + + void run() { + sendInputMessage(); + assertThatOutputMessageGotReceived(); + } + + private void assertThatOutputMessageGotReceived() { + // System.out.println("Retrieving the message for tests"); + Message message = output.receive(200L); + // System.out.println("Got the message from output"); + assertThat(message).isNotNull(); + // System.out.println("Message is not null"); + assertThat(message.getPayload()).isEqualTo("HELLO".getBytes()); + // System.out.println("Payload is HELLO"); + if (!instrumentation.toString().toLowerCase().contains("nosleuth")) { + String b3 = message.getHeaders().get("b3", String.class); + // System.out.println("Checking the b3 header [" + b3 + "]"); + assertThat(b3).isNotEmpty(); + if (b3.startsWith("0000000000000000")) { + assertThat(b3).startsWith("00000000000000004883117762eb9420"); + } else { + assertThat(b3).startsWith("4883117762eb9420"); + } + assertThat(this.applicationContext.getBean(Tracer.class).currentSpan()).isNull(); + } + } + + @TearDown + public void clean() throws Exception { + Tracing current = Tracing.current(); + if (current != null) { + current.close(); + } + try { + this.applicationContext.close(); + } + catch (Exception ig) { + + } + } + + public enum Instrumentation { + + // @formatter:off + noSleuthSimple(Pair.noSleuth(), function("simple")), + sleuthSimpleOnQueues(function("simple"), Pair.onHook()), + sleuthSimpleManual(function("simple_manual"), Pair.manual(), functionDisabled(), integrationDisabled()), + sleuthSimpleNoFunctionInstrumentationManual(function("simple_manual"), Pair.manual(), functionDisabled(), integrationEnabled()), + sleuthSimpleOnEach(function("simple"), Pair.onEach()), + sleuthSimpleOnLast(function("simple"), Pair.onLast()), + sleuthSimpleWithAroundOnQueues(function("simple_function_with_around")), + noSleuthReactiveSimple(function("reactive_simple"), Pair.noSleuth()), + sleuthReactiveSimpleOnQueues(function("DECORATE_QUEUES"), Pair.decorateQueues(), integrationEnabled()), + sleuthReactiveSimpleOnEach(function("DECORATE_ON_EACH"), Pair.onEach(), integrationEnabled()), + sleuthReactiveSimpleManual(function("reactive_simple_manual"), Pair.manual()), + sleuthReactiveSimpleNoFunctionInstrumentationManual(function("reactive_simple_manual"), Pair.manual(), integrationEnabled(), functionDisabled()); + // @formatter:on + + private final List pairs; + + Instrumentation(Pair... pairs) { + this.pairs = Arrays.asList(pairs); + } + + String[] asParams() { + return this.pairs.stream().map(p -> "--" + p.asProp()).toArray(String[]::new); + } + + static Pair function(String type) { + return Pair.of("spring.sleuth.function.type", type); + } + + static Pair integrationEnabled() { + return Pair.of("spring.sleuth.integration.enabled", "true"); + } + + static Pair integrationDisabled() { + return Pair.of("spring.sleuth.integration.enabled", "false"); + } + + static Pair functionDisabled() { + return Pair.of("spring.sleuth.function.enabled", "false"); + } + } + + } + + @Configuration(proxyBeanMethods = false) + @Import(TestChannelBinderConfiguration.class) + static class TestConfiguration { + + } + +} diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/MicroBenchmarkHttpTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/MicroBenchmarkHttpTests.java index 89ed7c443..b7913e07e 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/MicroBenchmarkHttpTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/MicroBenchmarkHttpTests.java @@ -1,143 +1,156 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.benchmarks.jmh.webflux; - -import java.util.concurrent.TimeUnit; - -import brave.Tracing; -import jmh.mbr.junit5.Microbenchmark; -import org.junit.platform.commons.annotation.Testable; -import org.openjdk.jmh.annotations.Benchmark; -import org.openjdk.jmh.annotations.BenchmarkMode; -import org.openjdk.jmh.annotations.Fork; -import org.openjdk.jmh.annotations.Measurement; -import org.openjdk.jmh.annotations.Mode; -import org.openjdk.jmh.annotations.OutputTimeUnit; -import org.openjdk.jmh.annotations.Param; -import org.openjdk.jmh.annotations.Scope; -import org.openjdk.jmh.annotations.Setup; -import org.openjdk.jmh.annotations.State; -import org.openjdk.jmh.annotations.TearDown; -import org.openjdk.jmh.annotations.Warmup; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.sleuth.benchmarks.app.webflux.SleuthBenchmarkingSpringWebFluxApp; -import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.test.web.reactive.server.WebTestClient; - -@Measurement(iterations = 5, time = 1) -@Warmup(iterations = 5, time = 1) -@Fork(2) -@BenchmarkMode(Mode.SampleTime) -@OutputTimeUnit(TimeUnit.MILLISECONDS) -@Microbenchmark -public class MicroBenchmarkHttpTests { - - @Benchmark - @Testable - public void test(BenchmarkContext context) throws Exception { - context.run(); - } - - @State(Scope.Benchmark) - public static class BenchmarkContext { - - volatile ConfigurableApplicationContext applicationContext; - - volatile WebTestClient webTestClient; - - @Param - private Instrumentation instrumentation; - - @Param - private TracerImplementation tracerImplementation; - - @Setup - public void setup() { - this.applicationContext = initContext(); - this.webTestClient = WebTestClient.bindToApplicationContext(applicationContext).build(); - } - - protected ConfigurableApplicationContext initContext() { - SpringApplication application = new SpringApplicationBuilder(SleuthBenchmarkingSpringWebFluxApp.class) - .web(WebApplicationType.REACTIVE).application(); - return application.run(runArgs()); - } - - protected String[] runArgs() { - return new String[] { "--spring.jmx.enabled=false", - "--spring.application.name=defaultTraceContext" + instrumentation.name() + "_" - + tracerImplementation.name(), - "--" + instrumentation.key + "=" + instrumentation.value }; - } - - void run() { - this.webTestClient.get().uri(instrumentation.url).header("X-B3-TraceId", "4883117762eb9420") - .header("X-B3-SpanId", "4883117762eb9420").exchange().expectStatus().isOk(); - } - - @TearDown - public void clean() throws Exception { - Tracing current = Tracing.current(); - if (current != null) { - current.close(); - } - try { - this.applicationContext.close(); - } - catch (Exception ig) { - - } - } - - public enum Instrumentation { - - noSleuthSimple("spring.sleuth.enabled", "false", "/simple"), sleuthSimpleManual( - "spring.sleuth.reactor.instrumentation-type", "MANUAL", - "/simple"), sleuthManual("spring.sleuth.reactor.instrumentation-type", "MANUAL", - "/simpleManual"), sleuthSimpleOnEach("spring.sleuth.reactor.instrumentation-type", - "DECORATE_ON_EACH", - "/simple"), sleuthSimpleOnLast("spring.sleuth.reactor.instrumentation-type", - "DECORATE_ON_LAST", "/simple"), noSleuthComplex("spring.sleuth.enabled", - "false", "/complexNoSleuth"), onEachComplex( - "spring.sleuth.reactor.instrumentation-type", - "DECORATE_ON_EACH", "/complex"), onLastComplex( - "spring.sleuth.reactor.instrumentation-type", - "DECORATE_ON_LAST", "/complex"), onManualComplex( - "spring.sleuth.reactor.instrumentation-type", - "MANUAL", "/complexManual"); - - private String key; - - private String value; - - private String url; - - Instrumentation(String key, String value, String url) { - this.key = key; - this.value = value; - this.url = url; - } - - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.benchmarks.jmh.webflux; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import brave.Tracing; +import jmh.mbr.junit5.Microbenchmark; +import org.junit.platform.commons.annotation.Testable; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.benchmarks.app.webflux.SleuthBenchmarkingSpringWebFluxApp; +import org.springframework.cloud.sleuth.benchmarks.jmh.Pair; +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.test.web.reactive.server.WebTestClient; + +import static org.assertj.core.api.Assertions.assertThat; + +@Measurement(iterations = 10, time = 1) +@Warmup(iterations = 10, time = 1) +@Fork(4) +@BenchmarkMode(Mode.SampleTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Microbenchmark +public class MicroBenchmarkHttpTests { + + @Benchmark + @Testable + public void test(BenchmarkContext context) throws Exception { + context.run(); + } + + @State(Scope.Benchmark) + public static class BenchmarkContext { + + volatile ConfigurableApplicationContext applicationContext; + + volatile WebTestClient webTestClient; + + @Param + private Instrumentation instrumentation; + + @Param + private TracerImplementation tracerImplementation; + + @Setup + public void setup() { + this.applicationContext = initContext(); + this.webTestClient = WebTestClient.bindToApplicationContext(applicationContext).build(); + } + + protected ConfigurableApplicationContext initContext() { + SpringApplication application = new SpringApplicationBuilder(SleuthBenchmarkingSpringWebFluxApp.class) + .web(WebApplicationType.REACTIVE).application(); + return application.run(runArgs()); + } + + protected String[] runArgs() { + String[] defaultArgs = new String[] { "--spring.jmx.enabled=false", + "--spring.application.name=defaultTraceContext" + instrumentation.name() + "_" + + tracerImplementation.name() }; + List list = new ArrayList<>(Arrays.asList(defaultArgs)); + list.addAll(Arrays.asList(instrumentation.asParams())); + return list.toArray(new String[0]); + } + + void run() { + this.webTestClient.get().uri(instrumentation.url).header("X-B3-TraceId", "4883117762eb9420") + .header("X-B3-SpanId", "4883117762eb9420").exchange().expectStatus().isOk(); + if (this.instrumentation.name().toLowerCase().contains("nosleuth")) { + assertThat(this.applicationContext.getBeanProvider(Tracer.class).getIfAvailable(() -> null)).isNull(); + } else { + assertThat(this.applicationContext.getBean(Tracer.class).currentSpan()).isNull(); + } + } + + @TearDown + public void clean() throws Exception { + Tracing current = Tracing.current(); + if (current != null) { + current.close(); + } + try { + this.applicationContext.close(); + } + catch (Exception ig) { + + } + } + + public enum Instrumentation { + + // @formatter:off + noSleuthSimple("/simple", Pair.noSleuth()), + onQueuesSimple("/simple", Pair.onHook()), + onManualSimple("/simpleManual", Pair.manual()), + onEachSimple("/simple", Pair.onEach()), + onLastSimple("/simple", Pair.onLast()), + noSleuthComplex("/complexNoSleuth", Pair.noSleuth()), + onQueueComplex("/complex", Pair.onHook()), + onManualComplex("/complexManual", Pair.manual()), + onEachComplex("/complex", Pair.onEach()), + onLastComplex("/complex", Pair.onLast()); + // @formatter:on + + private String url; + + private List pairs; + + Instrumentation(String url, Pair... pairs) { + this.url = url; + this.pairs = Arrays.asList(pairs); + } + + String[] asParams() { + return this.pairs.stream().map(p -> "--" + p.asProp()).collect(Collectors.toList()).toArray(new String[0]); + } + } + + } + +} diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/SpringWebFluxBenchmarksTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/SpringWebFluxBenchmarksTests.java index b7c7719af..1776ab3f6 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/SpringWebFluxBenchmarksTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/SpringWebFluxBenchmarksTests.java @@ -1,183 +1,183 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.benchmarks.jmh.webflux; - -import java.io.IOException; -import java.util.concurrent.TimeUnit; - -import brave.Tracing; -import brave.handler.SpanHandler; -import brave.http.HttpTracing; -import brave.httpclient.TracingHttpClientBuilder; -import brave.propagation.CurrentTraceContext; -import brave.propagation.TraceContext; -import brave.sampler.Sampler; -import jmh.mbr.junit5.Microbenchmark; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.util.EntityUtils; -import org.openjdk.jmh.annotations.Benchmark; -import org.openjdk.jmh.annotations.BenchmarkMode; -import org.openjdk.jmh.annotations.Fork; -import org.openjdk.jmh.annotations.Measurement; -import org.openjdk.jmh.annotations.Mode; -import org.openjdk.jmh.annotations.OutputTimeUnit; -import org.openjdk.jmh.annotations.Scope; -import org.openjdk.jmh.annotations.Setup; -import org.openjdk.jmh.annotations.State; -import org.openjdk.jmh.annotations.TearDown; -import org.openjdk.jmh.annotations.Threads; -import org.openjdk.jmh.annotations.Warmup; -import org.openjdk.jmh.runner.Runner; -import org.openjdk.jmh.runner.RunnerException; -import org.openjdk.jmh.runner.options.Options; -import org.openjdk.jmh.runner.options.OptionsBuilder; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.sleuth.benchmarks.app.webflux.SleuthBenchmarkingSpringWebFluxApp; -import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; -import org.springframework.context.ConfigurableApplicationContext; - -@Measurement(iterations = 5, time = 1) -@Warmup(iterations = 5, time = 1) -@Fork(2) -@BenchmarkMode(Mode.SampleTime) -@OutputTimeUnit(TimeUnit.MICROSECONDS) -@Threads(2) -@State(Scope.Benchmark) -@Microbenchmark -public abstract class SpringWebFluxBenchmarksTests { - - static final SpanHandler FAKE_SPAN_HANDLER = new SpanHandler() { - // intentionally anonymous to prevent logging fallback on NOOP - }; - - protected static TraceContext defaultTraceContext = TraceContext.newBuilder().traceIdHigh(333L).traceId(444L) - .spanId(3).sampled(true).build(); - - protected ConfigurableApplicationContext applicationContext; - - protected SleuthBenchmarkingSpringWebFluxApp springWebFluxApp; - - CloseableHttpClient client; - - CloseableHttpClient tracedClient; - - CloseableHttpClient unsampledClient; - - private String baseUrl; - - public static void main(String[] args) throws RunnerException { - Options opt = new OptionsBuilder().include(".*" + SpringWebFluxBenchmarksTests.class.getSimpleName() + ".*") - .build(); - - new Runner(opt).run(); - } - - public String getBaseUrl() { - return baseUrl; - } - - protected CloseableHttpClient newClient(HttpTracing httpTracing) { - return TracingHttpClientBuilder.create(httpTracing).disableAutomaticRetries().build(); - } - - protected CloseableHttpClient newClient() { - return HttpClients.custom().disableAutomaticRetries().build(); - } - - protected void get(CloseableHttpClient client) throws Exception { - EntityUtils.consume(client.execute(new HttpGet(getBaseUrl())).getEntity()); - } - - protected void close(CloseableHttpClient client) throws IOException { - client.close(); - } - - @Setup - public void setup() { - ConfigurableApplicationContext context = initContext(); - this.applicationContext = context; - this.springWebFluxApp = this.applicationContext.getBean(SleuthBenchmarkingSpringWebFluxApp.class); - baseUrl = "http://127.0.0.1:" + springWebFluxApp.port + "/foo"; - client = newClient(); - tracedClient = newClient(HttpTracing.create(Tracing.newBuilder().addSpanHandler(FAKE_SPAN_HANDLER).build())); - unsampledClient = newClient(HttpTracing - .create(Tracing.newBuilder().sampler(Sampler.NEVER_SAMPLE).addSpanHandler(FAKE_SPAN_HANDLER).build())); - postSetUp(); - } - - protected ConfigurableApplicationContext initContext() { - SpringApplication application = new SpringApplicationBuilder(SleuthBenchmarkingSpringWebFluxApp.class) - .web(WebApplicationType.REACTIVE).application(); - customSpringApplication(application); - return application.run(runArgs()); - } - - protected void customSpringApplication(SpringApplication springApplication) { - - } - - protected void postSetUp() { - } - - protected String[] runArgs() { - return new String[] { "--spring.jmx.enabled=false", "--spring.application.name=defaultTraceContext", - TracerImplementation.brave.toString(), "--spring.sleuth.enabled=true" }; - } - - @TearDown - public void clean() throws Exception { - close(client); - close(unsampledClient); - close(tracedClient); - Tracing.current().close(); - try { - - this.applicationContext.close(); - } - catch (Exception ig) { - - } - } - - @Benchmark - public void client_get() throws Exception { - get(client); - } - - @Benchmark - public void unsampledClient_get() throws Exception { - get(unsampledClient); - } - - @Benchmark - public void tracedClient_get() throws Exception { - get(tracedClient); - } - - @Benchmark - public void tracedClient_get_resumeTrace() throws Exception { - try (CurrentTraceContext.Scope scope = Tracing.current().currentTraceContext().newScope(defaultTraceContext)) { - get(tracedClient); - } - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.benchmarks.jmh.webflux; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import brave.Tracing; +import brave.handler.SpanHandler; +import brave.http.HttpTracing; +import brave.httpclient.TracingHttpClientBuilder; +import brave.propagation.CurrentTraceContext; +import brave.propagation.TraceContext; +import brave.sampler.Sampler; +import jmh.mbr.junit5.Microbenchmark; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.sleuth.benchmarks.app.webflux.SleuthBenchmarkingSpringWebFluxApp; +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; +import org.springframework.context.ConfigurableApplicationContext; + +@Measurement(iterations = 5, time = 1) +@Warmup(iterations = 5, time = 1) +@Fork(2) +@BenchmarkMode(Mode.SampleTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Threads(2) +@State(Scope.Benchmark) +@Microbenchmark +public abstract class SpringWebFluxBenchmarksTests { + + static final SpanHandler FAKE_SPAN_HANDLER = new SpanHandler() { + // intentionally anonymous to prevent logging fallback on NOOP + }; + + protected static TraceContext defaultTraceContext = TraceContext.newBuilder().traceIdHigh(333L).traceId(444L) + .spanId(3).sampled(true).build(); + + protected ConfigurableApplicationContext applicationContext; + + protected SleuthBenchmarkingSpringWebFluxApp springWebFluxApp; + + CloseableHttpClient client; + + CloseableHttpClient tracedClient; + + CloseableHttpClient unsampledClient; + + private String baseUrl; + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder().include(".*" + SpringWebFluxBenchmarksTests.class.getSimpleName() + ".*") + .build(); + + new Runner(opt).run(); + } + + public String getBaseUrl() { + return baseUrl; + } + + protected CloseableHttpClient newClient(HttpTracing httpTracing) { + return TracingHttpClientBuilder.create(httpTracing).disableAutomaticRetries().build(); + } + + protected CloseableHttpClient newClient() { + return HttpClients.custom().disableAutomaticRetries().build(); + } + + protected void get(CloseableHttpClient client) throws Exception { + EntityUtils.consume(client.execute(new HttpGet(getBaseUrl())).getEntity()); + } + + protected void close(CloseableHttpClient client) throws IOException { + client.close(); + } + + @Setup + public void setup() { + ConfigurableApplicationContext context = initContext(); + this.applicationContext = context; + this.springWebFluxApp = this.applicationContext.getBean(SleuthBenchmarkingSpringWebFluxApp.class); + baseUrl = "http://127.0.0.1:" + springWebFluxApp.port + "/foo"; + client = newClient(); + tracedClient = newClient(HttpTracing.create(Tracing.newBuilder().addSpanHandler(FAKE_SPAN_HANDLER).build())); + unsampledClient = newClient(HttpTracing + .create(Tracing.newBuilder().sampler(Sampler.NEVER_SAMPLE).addSpanHandler(FAKE_SPAN_HANDLER).build())); + postSetUp(); + } + + protected ConfigurableApplicationContext initContext() { + SpringApplication application = new SpringApplicationBuilder(SleuthBenchmarkingSpringWebFluxApp.class) + .web(WebApplicationType.REACTIVE).application(); + customSpringApplication(application); + return application.run(runArgs()); + } + + protected void customSpringApplication(SpringApplication springApplication) { + + } + + protected void postSetUp() { + } + + protected String[] runArgs() { + return new String[] { "--spring.jmx.enabled=false", "--spring.application.name=defaultTraceContext", + TracerImplementation.brave.toString(), "--spring.sleuth.enabled=true" }; + } + + @TearDown + public void clean() throws Exception { + close(client); + close(unsampledClient); + close(tracedClient); + Tracing.current().close(); + try { + + this.applicationContext.close(); + } + catch (Exception ig) { + + } + } + + @Benchmark + public void client_get() throws Exception { + get(client); + } + + @Benchmark + public void unsampledClient_get() throws Exception { + get(unsampledClient); + } + + @Benchmark + public void tracedClient_get() throws Exception { + get(tracedClient); + } + + @Benchmark + public void tracedClient_get_resumeTrace() throws Exception { + try (CurrentTraceContext.Scope scope = Tracing.current().currentTraceContext().newScope(defaultTraceContext)) { + get(tracedClient); + } + } + +} diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutReactorSleuthSpringWebFluxBenchmarksTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutReactorSleuthSpringWebFluxBenchmarksTests.java index 3629040a1..93f35d8a2 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutReactorSleuthSpringWebFluxBenchmarksTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutReactorSleuthSpringWebFluxBenchmarksTests.java @@ -1,54 +1,54 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.benchmarks.jmh.webflux; - -import jmh.mbr.junit5.Microbenchmark; -import org.openjdk.jmh.runner.Runner; -import org.openjdk.jmh.runner.RunnerException; -import org.openjdk.jmh.runner.options.Options; -import org.openjdk.jmh.runner.options.OptionsBuilder; - -import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; - -/** - * @author alvin - */ -@Microbenchmark -public class WithOutReactorSleuthSpringWebFluxBenchmarksTests extends SpringWebFluxBenchmarksTests { - - public static void main(String[] args) throws RunnerException { - Options opt = new OptionsBuilder() - .include(".*" + WithOutReactorSleuthSpringWebFluxBenchmarksTests.class.getSimpleName() + ".*").build(); - - new Runner(opt).run(); - } - - @Override - protected String[] runArgs() { - return new String[] { "--spring.jmx.enabled=false", "--spring.application.name=defaultTraceContext", - TracerImplementation.brave.toString(), "--spring.sleuth.enabled=true", - "--spring.sleuth.reactor.enabled=false" - - }; - } - - @Override - protected void postSetUp() { - super.postSetUp(); - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.benchmarks.jmh.webflux; + +import jmh.mbr.junit5.Microbenchmark; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; + +/** + * @author alvin + */ +@Microbenchmark +public class WithOutReactorSleuthSpringWebFluxBenchmarksTests extends SpringWebFluxBenchmarksTests { + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(".*" + WithOutReactorSleuthSpringWebFluxBenchmarksTests.class.getSimpleName() + ".*").build(); + + new Runner(opt).run(); + } + + @Override + protected String[] runArgs() { + return new String[] { "--spring.jmx.enabled=false", "--spring.application.name=defaultTraceContext", + TracerImplementation.brave.toString(), "--spring.sleuth.enabled=true", + "--spring.sleuth.reactor.enabled=false" + + }; + } + + @Override + protected void postSetUp() { + super.postSetUp(); + } + +} diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutSleuthSpringWebFluxBenchmarksTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutSleuthSpringWebFluxBenchmarksTests.java index 8185d0c20..f609fd615 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutSleuthSpringWebFluxBenchmarksTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutSleuthSpringWebFluxBenchmarksTests.java @@ -1,51 +1,51 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.benchmarks.jmh.webflux; - -import jmh.mbr.junit5.Microbenchmark; -import org.openjdk.jmh.runner.Runner; -import org.openjdk.jmh.runner.RunnerException; -import org.openjdk.jmh.runner.options.Options; -import org.openjdk.jmh.runner.options.OptionsBuilder; - -import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; - -/** - * @author alvin - */ -@Microbenchmark -public class WithOutSleuthSpringWebFluxBenchmarksTests extends SpringWebFluxBenchmarksTests { - - public static void main(String[] args) throws RunnerException { - Options opt = new OptionsBuilder() - .include(".*" + WithOutSleuthSpringWebFluxBenchmarksTests.class.getSimpleName() + ".*").build(); - - new Runner(opt).run(); - } - - @Override - protected String[] runArgs() { - return new String[] { "--spring.jmx.enabled=false", "--spring.application.name=defaultTraceContext", - TracerImplementation.brave.toString(), "--spring.sleuth.enabled=false" }; - } - - @Override - protected void postSetUp() { - super.postSetUp(); - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.benchmarks.jmh.webflux; + +import jmh.mbr.junit5.Microbenchmark; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; + +/** + * @author alvin + */ +@Microbenchmark +public class WithOutSleuthSpringWebFluxBenchmarksTests extends SpringWebFluxBenchmarksTests { + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(".*" + WithOutSleuthSpringWebFluxBenchmarksTests.class.getSimpleName() + ".*").build(); + + new Runner(opt).run(); + } + + @Override + protected String[] runArgs() { + return new String[] { "--spring.jmx.enabled=false", "--spring.application.name=defaultTraceContext", + TracerImplementation.brave.toString(), "--spring.sleuth.enabled=false" }; + } + + @Override + protected void postSetUp() { + super.postSetUp(); + } + +} diff --git a/docs/pom.xml b/docs/pom.xml index 03a3c3b77..cf86faac6 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -21,7 +21,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.1.0-SNAPSHOT spring-cloud-sleuth-docs jar diff --git a/docs/src/main/asciidoc/_configprops.adoc b/docs/src/main/asciidoc/_configprops.adoc index 44d2be68d..e2c13e903 100644 --- a/docs/src/main/asciidoc/_configprops.adoc +++ b/docs/src/main/asciidoc/_configprops.adoc @@ -10,13 +10,16 @@ |spring.sleuth.baggage.remote-fields | | List of fields that are referenced the same in-process as it is on the wire. For example, the field "x-vcap-request-id" would be set as-is including the prefix. |spring.sleuth.baggage.tag-fields | | |spring.sleuth.circuitbreaker.enabled | `true` | Enable Spring Cloud CircuitBreaker instrumentation. +|spring.sleuth.config.server.enabled | `true` | Enable Spring Cloud Config Server instrumentation. +|spring.sleuth.deployer.enabled | `true` | Enable Spring Cloud Deployer instrumentation. +|spring.sleuth.deployer.status-poll-delay | `1000` | Default poll delay to retrieve the deployed application status. |spring.sleuth.enabled | `true` | |spring.sleuth.feign.enabled | `true` | Enable span information propagation when using Feign. |spring.sleuth.feign.processor.enabled | `true` | Enable post processor that wraps Feign Context in its tracing representations. |spring.sleuth.function.enabled | `true` | Enable instrumenting of Spring Cloud Function and Spring Cloud Function based projects (e.g. Spring Cloud Stream). |spring.sleuth.grpc.enabled | `true` | Enable span information propagation when using GRPC. |spring.sleuth.http.enabled | `true` | Enables HTTP support. -|spring.sleuth.integration.enabled | `true` | Enable Spring Integration sleuth instrumentation. +|spring.sleuth.integration.enabled | `true` | Enable Spring Integration instrumentation. |spring.sleuth.integration.patterns | `[!hystrixStreamOutput*, *, !channel*]` | An array of patterns against which channel names will be matched. @see org.springframework.integration.config.GlobalChannelInterceptor#patterns() Defaults to any channel name not matching the Hystrix Stream and functional Stream channel names. |spring.sleuth.integration.websockets.enabled | `true` | Enable tracing for WebSockets. |spring.sleuth.messaging.enabled | `false` | Should messaging be turned on. @@ -49,6 +52,7 @@ |spring.sleuth.span-filter.enabled | `false` | Will turn on the default Sleuth handler mechanism. Might ignore exporting of certain spans; |spring.sleuth.span-filter.span-name-patterns-to-skip | `^catalogWatchTaskScheduler$` | List of span names to ignore. They will not be sent to external systems. |spring.sleuth.supports-join | `true` | True means the tracing system supports sharing a span ID between a client and server. +|spring.sleuth.task.enabled | `true` | Enable Spring Cloud Task instrumentation. |spring.sleuth.trace-id128 | `false` | When true, generate 128-bit trace IDs instead of 64-bit ones. |spring.sleuth.tracer.mode | | Set which tracer implementation should be picked. |spring.sleuth.web.additional-skip-pattern | | Additional pattern for URLs that should be skipped in tracing. This will be appended to the {@link SleuthWebProperties#skipPattern}. @@ -62,6 +66,7 @@ |spring.sleuth.web.webclient.enabled | `true` | Enable tracing instrumentation for WebClient. |spring.zipkin.activemq.message-max-bytes | `100000` | Maximum number of bytes for a given message with spans sent to Zipkin over ActiveMQ. |spring.zipkin.activemq.queue | `zipkin` | Name of the ActiveMQ queue where spans should be sent to Zipkin. +|spring.zipkin.api-path | | The API path to append to baseUrl (above) as suffix. This applies if you use other monitoring tools, such as New Relic. The trace API doesn't need the API path, so you can set it to blank ("") in the configuration. |spring.zipkin.base-url | `http://localhost:9411/` | URL of the zipkin query server instance. You can also provide the service id of the Zipkin server if Zipkin's registered in service discovery (e.g. https://zipkinserver/). |spring.zipkin.compression.enabled | `false` | |spring.zipkin.discovery-client-enabled | | If set to {@code false}, will treat the {@link ZipkinProperties#baseUrl} as a URL always. diff --git a/docs/src/main/asciidoc/_index.adoc b/docs/src/main/asciidoc/_index.adoc deleted file mode 100644 index d0a241950..000000000 --- a/docs/src/main/asciidoc/_index.adoc +++ /dev/null @@ -1,18 +0,0 @@ -[[spring-cloud-sleuth-reference-documentation]] -= Spring Cloud Sleuth Reference Documentation -Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer, Jay Bryant - -:docinfo: shared -include::_attributes.adoc[] - -The reference documentation consists of the following sections: - -[horizontal] -<> :: Legal information. -<> :: About the Documentation, Getting Help, First Steps, and more. -<> :: Introducing {project-full-name}, Developing Your First {project-full-name}-based Application -<> :: {project-full-name} usage examples and workflows. -<> :: Span creation, context propagation, and more. -<> :: Add sampling, propagate remote tags, and more. -<> :: Instrumentation configuration, context propagation, and more. -<> :: Configuration properties. diff --git a/docs/src/main/asciidoc/_index_pdf.adoc b/docs/src/main/asciidoc/_index_pdf.adoc deleted file mode 100644 index e1edcb891..000000000 --- a/docs/src/main/asciidoc/_index_pdf.adoc +++ /dev/null @@ -1,13 +0,0 @@ -[[spring-cloud-sleuth-reference-documentation]] -= Spring Cloud Sleuth Reference Documentation -Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer, Jay Bryant - -include::_attributes.adoc[] - -include::legal.adoc[leveloffset=+1] -include::getting-started.adoc[leveloffset=+1] -include::using.adoc[leveloffset=+1] -include::project-features.adoc[leveloffset=+1] -include::howto.adoc[leveloffset=+1] -include::integrations.adoc[leveloffset=+1] -include::appendix.adoc[leveloffset=+1] diff --git a/docs/src/main/asciidoc/_index_single.adoc b/docs/src/main/asciidoc/_index_single.adoc deleted file mode 100644 index 741b91da1..000000000 --- a/docs/src/main/asciidoc/_index_single.adoc +++ /dev/null @@ -1,14 +0,0 @@ -[[spring-cloud-sleuth-reference-documentation]] -= Spring Cloud Sleuth Reference Documentation -Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer, Jay Bryant - -:docinfo: shared -include::_attributes.adoc[] - -include::legal.adoc[leveloffset=+1] -include::getting-started.adoc[leveloffset=+1] -include::using.adoc[leveloffset=+1] -include::project-features.adoc[leveloffset=+1] -include::howto.adoc[leveloffset=+1] -include::integrations.adoc[leveloffset=+1] -include::appendix.adoc[leveloffset=+1] \ No newline at end of file diff --git a/docs/src/main/asciidoc/howto.adoc b/docs/src/main/asciidoc/howto.adoc index 97ecdff11..ae3b9c206 100644 --- a/docs/src/main/asciidoc/howto.adoc +++ b/docs/src/main/asciidoc/howto.adoc @@ -213,7 +213,7 @@ dependencies { ---- ==== -If you want Sleuth over RabbitMQ, add the `spring-cloud-starter-sleuth`, `spring-cloud-sleuth-zipkin` and `activemq-client` dependencies. +If you want Sleuth over ActiveMQ, add the `spring-cloud-starter-sleuth`, `spring-cloud-sleuth-zipkin` and `activemq-client` dependencies. ==== [source,xml,indent=0,subs="verbatim,attributes",role="primary"] @@ -458,4 +458,4 @@ include::{autoconfig_path}/src/test/java/org/springframework/cloud/sleuth/autoco Spring Cloud Sleuth API contains all necessary interfaces to be implemented by a tracer. The project comes with OpenZipkin Brave implementation. -You can check how both tracers are bridged to the Sleuth's API by looking at the `org.springframework.cloud.sleuth.brave.bridge` module. \ No newline at end of file +You can check how both tracers are bridged to the Sleuth's API by looking at the `org.springframework.cloud.sleuth.brave.bridge` module. diff --git a/docs/src/main/asciidoc/index.adoc b/docs/src/main/asciidoc/index.adoc new file mode 120000 index 000000000..2ab5e96e8 --- /dev/null +++ b/docs/src/main/asciidoc/index.adoc @@ -0,0 +1 @@ +spring-cloud-sleuth.adoc \ No newline at end of file diff --git a/docs/src/main/asciidoc/index.htmladoc b/docs/src/main/asciidoc/index.htmladoc deleted file mode 100644 index c674268b6..000000000 --- a/docs/src/main/asciidoc/index.htmladoc +++ /dev/null @@ -1 +0,0 @@ -include::_index.adoc[] \ No newline at end of file diff --git a/docs/src/main/asciidoc/index.htmladoc b/docs/src/main/asciidoc/index.htmladoc new file mode 120000 index 000000000..2ab5e96e8 --- /dev/null +++ b/docs/src/main/asciidoc/index.htmladoc @@ -0,0 +1 @@ +spring-cloud-sleuth.adoc \ No newline at end of file diff --git a/docs/src/main/asciidoc/index.htmlsingleadoc b/docs/src/main/asciidoc/index.htmlsingleadoc deleted file mode 100644 index 67d39bee3..000000000 --- a/docs/src/main/asciidoc/index.htmlsingleadoc +++ /dev/null @@ -1 +0,0 @@ -include::_index_single.adoc[] \ No newline at end of file diff --git a/docs/src/main/asciidoc/index.htmlsingleadoc b/docs/src/main/asciidoc/index.htmlsingleadoc new file mode 120000 index 000000000..f8d93d10b --- /dev/null +++ b/docs/src/main/asciidoc/index.htmlsingleadoc @@ -0,0 +1 @@ +spring-cloud-sleuth.htmlsingleadoc \ No newline at end of file diff --git a/docs/src/main/asciidoc/index.pdfadoc b/docs/src/main/asciidoc/index.pdfadoc new file mode 120000 index 000000000..d4beca5b9 --- /dev/null +++ b/docs/src/main/asciidoc/index.pdfadoc @@ -0,0 +1 @@ +spring-cloud-sleuth.pdfadoc \ No newline at end of file diff --git a/docs/src/main/asciidoc/integrations.adoc b/docs/src/main/asciidoc/integrations.adoc index 2313adf7f..322c2ff23 100644 --- a/docs/src/main/asciidoc/integrations.adoc +++ b/docs/src/main/asciidoc/integrations.adoc @@ -1,568 +1,594 @@ -[[sleuth-integration]] -= Spring Cloud Sleuth customization - -include::_attributes.adoc[] - -In this section, we describe how to customize various parts of Spring Cloud Sleuth. - -[[sleuth-async-integration]] -== Asynchronous Communication - -In this section, we describe how to customize asynchronous communication with Spring Cloud Sleuth. - -[[sleuth-async-annotation-integration]] -=== `@Async` Annotated methods - -This feature is available for all tracer implementations. - -In Spring Cloud Sleuth, we instrument async-related components so that the tracing information is passed between threads. -You can disable this behavior by setting the value of `spring.sleuth.async.enabled` to `false`. - -If you annotate your method with `@Async`, we automatically modify the existing Span as follows: - -* If the method is annotated with `@SpanName`, the value of the annotation is the Span's name. -* If the method is not annotated with `@SpanName`, the Span name is the annotated method name. -* The span is tagged with the method's class name and method name. - -Since we're modifying the existing span, if you want to maintain its original name (e.g. a span created by receiving an HTTP request) -you should wrap your `@Async` annotated method with a `@NewSpan` annotation or create a new span manually. - -[[sleuth-async-scheduled-integration]] -=== `@Scheduled` Annotated Methods - -This feature is available for all tracer implementations. - -In Spring Cloud Sleuth, we instrument scheduled method execution so that the tracing information is passed between threads. -You can disable this behavior by setting the value of `spring.sleuth.scheduled.enabled` to `false`. - -If you annotate your method with `@Scheduled`, we automatically create a new span with the following characteristics: - -* The span name is the annotated method name. -* The span is tagged with the method's class name and method name. - -If you want to skip span creation for some `@Scheduled` annotated classes, you can set the `spring.sleuth.scheduled.skipPattern` with a regular expression that matches the fully qualified name of the `@Scheduled` annotated class. - -[[sleuth-async-executor-service-integration]] -=== Executor, ExecutorService, and ScheduledExecutorService - -This feature is available for all tracer implementations. - -We provide `LazyTraceExecutor`, `TraceableExecutorService`, and `TraceableScheduledExecutorService`. -Those implementations create spans each time a new task is submitted, invoked, or scheduled. - -The following example shows how to pass tracing information with `TraceableExecutorService` when working with `CompletableFuture`: - -[source,java,indent=0] ----- - -include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java[tags=completablefuture,indent=0] ----- - -IMPORTANT: Sleuth does not work with `parallelStream()` out of the box. -If you want to have the tracing information propagated through the stream, you have to use the approach with `supplyAsync(...)`, as shown earlier. - -If there are beans that implement the `Executor` interface that you would like to exclude from span creation, you can use the `spring.sleuth.async.ignored-beans` -property where you can provide a list of bean names. - -You can disable this behavior by setting the value of `spring.sleuth.async.enabled` to `false`. - -[[sleuth-async-executor-integration]] -==== Customization of Executors - -Sometimes, you need to set up a custom instance of the `AsyncExecutor`. -The following example shows how to set up such a custom `Executor`: - -[source,java,indent=0] ----- -include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/MultipleAsyncRestTemplateTests.java[tags=custom_executor,indent=0] ----- - -TIP: To ensure that your configuration gets post processed, remember to add the `@Role(BeanDefinition.ROLE_INFRASTRUCTURE)` on your -`@Configuration` class - -[[sleuth-http-client-integration]] -== HTTP Client Integration - -Features from this section can be disabled by setting the `spring.sleuth.web.client.enabled` property with value equal to `false`. - -[[sleuth-http-client-rest-template-integration]] -=== Synchronous Rest Template - -This feature is available for all tracer implementations. - -We inject a `RestTemplate` interceptor to ensure that all the tracing information is passed to the requests. -Each time a call is made, a new Span is created. -It gets closed upon receiving the response. -To block the synchronous `RestTemplate` features, set `spring.sleuth.web.client.enabled` to `false`. - -IMPORTANT: You have to register `RestTemplate` as a bean so that the interceptors get injected. -If you create a `RestTemplate` instance with a `new` keyword, the instrumentation does NOT work. - -[[sleuth-http-client-async-rest-template-integration]] -=== Asynchronous Rest Template - -This feature is available for all tracer implementations. - -IMPORTANT: Starting with Sleuth `2.0.0`, we no longer register a bean of `AsyncRestTemplate` type. -It is up to you to create such a bean. -Then we instrument it. - -To block the `AsyncRestTemplate` features, set `spring.sleuth.web.async.client.enabled` to `false`. -To disable creation of the default `TraceAsyncClientHttpRequestFactoryWrapper`, set `spring.sleuth.web.async.client.factory.enabled` -to `false`. -If you do not want to create `AsyncRestClient` at all, set `spring.sleuth.web.async.client.template.enabled` to `false`. - -[[sleuth-http-client-multiple-async-rest-template-integration]] -==== Multiple Asynchronous Rest Templates - -Sometimes you need to use multiple implementations of the Asynchronous Rest Template. -In the following snippet, you can see an example of how to set up such a custom `AsyncRestTemplate`: - -[source,java,indent=0] ----- -include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/MultipleAsyncRestTemplateTests.java[tags=custom_async_rest_template,indent=0] ----- - -[[sleuth-http-client-webclient-integration]] -==== `WebClient` - -This feature is available for all tracer implementations. - -We inject a `ExchangeFilterFunction` implementation that creates a span and, through on-success and on-error callbacks, takes care of closing client-side spans. - -To block this feature, set `spring.sleuth.web.client.enabled` to `false`. - -IMPORTANT: You have to register `WebClient` as a bean so that the tracing instrumentation gets applied. -If you create a `WebClient` instance with a `new` keyword, the instrumentation does NOT work. - -[[sleuth-http-client-traverson-integration]] -==== Traverson - -This feature is available for all tracer implementations. - -If you use the https://docs.spring.io/spring-hateoas/docs/current/reference/html/#client.traverson[Traverson] library, you can inject a `RestTemplate` as a bean into your Traverson object. -Since `RestTemplate` is already intercepted, you get full support for tracing in your client. -The following pseudo code shows how to do that: - -[source,java,indent=0] ----- -@Autowired RestTemplate restTemplate; - -Traverson traverson = new Traverson(URI.create("https://some/address"), - MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8).setRestOperations(restTemplate); -// use Traverson ----- - -[[sleuth-http-client-apache-integration]] -==== Apache `HttpClientBuilder` and `HttpAsyncClientBuilder` - -This feature is available for Brave tracer implementation. - -We instrument the `HttpClientBuilder` and `HttpAsyncClientBuilder` so that tracing context gets injected to the sent requests. - -To block these features, set `spring.sleuth.web.client.enabled` to `false`. - -[[sleuth-http-client-netty-integration]] -==== Netty `HttpClient` - -This feature is available for all tracer implementations. - -We instrument the Netty's `HttpClient`. - -To block this feature, set `spring.sleuth.web.client.enabled` to `false`. - -IMPORTANT: You have to register `HttpClient` as a bean so that the instrumentation happens. -If you create a `HttpClient` instance with a `new` keyword, the instrumentation does NOT work. - -[[sleuth-http-client-userinfo-integration]] -==== `UserInfoRestTemplateCustomizer` - -This feature is available for all tracer implementations. - -We instrument the Spring Security's `UserInfoRestTemplateCustomizer`. - -To block this feature, set `spring.sleuth.web.client.enabled` to `false`. - -[[sleuth-http-server-integration]] -== HTTP Server Integration - -Features from this section can be disabled by setting the `spring.sleuth.web.enabled` property with value equal to `false`. - -[[sleuth-http-server-http-filter-integration]] -=== HTTP Filter - -This feature is available for all tracer implementations. - -Through the `TracingFilter`, all sampled incoming requests result in creation of a Span. -You can configure which URIs you would like to skip by setting the `spring.sleuth.web.skipPattern` property. -If you have `ManagementServerProperties` on classpath, its value of `contextPath` gets appended to the provided skip pattern. -If you want to reuse the Sleuth's default skip patterns and just append your own, pass those patterns by using the `spring.sleuth.web.additionalSkipPattern`. - -By default, all the spring boot actuator endpoints are automatically added to the skip pattern. -If you want to disable this behaviour set `spring.sleuth.web.ignore-auto-configured-skip-patterns` -to `true`. - -To change the order of tracing filter registration, please set the -`spring.sleuth.web.filter-order` property. - -To disable the filter that logs uncaught exceptions you can disable the -`spring.sleuth.web.exception-throwing-filter-enabled` property. - -[[sleuth-http-server-handler-interceptor-integration]] -=== HandlerInterceptor - -This feature is available for all tracer implementations. - -Since we want the span names to be precise, we use a `TraceHandlerInterceptor` that either wraps an existing `HandlerInterceptor` or is added directly to the list of existing `HandlerInterceptors`. -The `TraceHandlerInterceptor` adds a special request attribute to the given `HttpServletRequest`. -If the the `TracingFilter` does not see this attribute, it creates a "`fallback`" span, which is an additional span created on the server side so that the trace is presented properly in the UI. -If that happens, there is probably missing instrumentation. -In that case, please file an issue in Spring Cloud Sleuth. - -[[sleuth-http-server-async-integration]] -=== Async Servlet support - -This feature is available for all tracer implementations. - -If your controller returns a `Callable` or a `WebAsyncTask`, Spring Cloud Sleuth continues the existing span instead of creating a new one. - -[[sleuth-http-server-webflux-integration]] -=== WebFlux support - -This feature is available for all tracer implementations. - -Through `TraceWebFilter`, all sampled incoming requests result in creation of a Span. -That Span's name is `http:` + the path to which the request was sent. -For example, if the request was sent to `/this/that`, the name is `http:/this/that`. -You can configure which URIs you would like to skip by using the `spring.sleuth.web.skipPattern` property. -If you have `ManagementServerProperties` on the classpath, its value of `contextPath` gets appended to the provided skip pattern. -If you want to reuse Sleuth's default skip patterns and append your own, pass those patterns by using the `spring.sleuth.web.additionalSkipPattern`. - -In order to achieve best results in terms of performance and context propagation we suggest that you switch the `spring.sleuth.reactor.instrumentation-type` to `MANUAL`. -In order to execute code with the span in scope you can call `WebFluxSleuthOperators.withSpanInScope`. -Example: - -[source,java,indent=0] ------ -include::{project-root}/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java[tags=simple_manual,indent=0] ------ - -To change the order of tracing filter registration, please set the -`spring.sleuth.web.filter-order` property. - -[[sleuth-messaging-integration]] -== Messaging - -Features from this section can be disabled by setting the `spring.sleuth.messaging.enabled` property with value equal to `false`. - -[[sleuth-messaging-spring-integration-integration]] -=== Spring Integration - -This feature is available for all tracer implementations. - -Spring Cloud Sleuth integrates with https://projects.spring.io/spring-integration/[Spring Integration]. -It creates spans for publish and subscribe events. -To disable Spring Integration instrumentation, set `spring.sleuth.integration.enabled` to `false`. - -You can provide the `spring.sleuth.integration.patterns` pattern to explicitly provide the names of channels that you want to include for tracing. -By default, all channels but `hystrixStreamOutput` channel are included. - -IMPORTANT: When using the `Executor` to build a Spring Integration `IntegrationFlow`, you must use the untraced version of the `Executor`. -Decorating the Spring Integration Executor Channel with `TraceableExecutorService` causes the spans to be improperly closed. - -If you want to customize the way tracing context is read from and written to message headers, it's enough for you to register beans of types: - -* `Propagator.Setter` - for writing headers to the message -* `Propagator.Getter` - for reading headers from the message - -[[sleuth-messaging-spring-integration-customization]] -==== Spring Integration Customization - -==== Customizing messaging spans - -In order to change the default span names and tags, just register a bean of type `MessageSpanCustomizer`. You can also -override the existing `DefaultMessageSpanCustomizer` to extend the existing behaviour. - -[source,java] ----- -@Component -include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java[tags=message_span_customizer,indent=2] ----- - -[[sleuth-messaging-spring-cloud-function-integration]] -=== Spring Cloud Function and Spring Cloud Stream - -This feature is available for all tracer implementations. - -Spring Cloud Sleuth can instrument Spring Cloud Function. -The way to achieve it is to provide a `Function` or `Consumer` or `Supplier` that takes in a `Message` as a parameter e.g. `Function, Message>`. -If the type is not `Message` then instrumentation will not take place. -Out of the box instrumentation will not take place when dealing with Reactor based streams - e.g. `Function>, Flux>>`. - -Since Spring Cloud Stream reuses Spring Cloud Function, you'll get the instrumentation out of the box. - -You can disable this behavior by setting the value of `spring.sleuth.function.enabled` to `false`. - -In order to work with reactive Stream functions you can leverage the `MessagingSleuthOperators` utility class that allows you to manipulate the input and output messages in order to continue the tracing context and to execute custom code within the tracing context. - -[source,java,indent=0] ------ -include::{project-root}/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/stream/SleuthBenchmarkingStreamApplication.java[tags=simple_reactive,indent=0] ------ - -[[sleuth-messaging-spring-rabbitmq-integration]] -=== Spring RabbitMq - -This feature is available for Brave tracer implementation. - -We instrument the `RabbitTemplate` so that tracing headers get injected into the message. - -To block this feature, set `spring.sleuth.messaging.rabbit.enabled` to `false`. - -[[sleuth-messaging-spring-kafka-integration]] -=== Spring Kafka - -This feature is available for Brave tracer implementation. - -We instrument the Spring Kafka's `ProducerFactory` and `ConsumerFactory` -so that tracing headers get injected into the created Spring Kafka's -`Producer` and `Consumer`. - -To block this feature, set `spring.sleuth.messaging.kafka.enabled` to `false`. - -[[sleuth-messaging-spring-kafka-streams-integration]] -=== Spring Kafka Streams - -This feature is available for Brave tracer implementation. - -We instrument the `KafkaStreams` `KafkaClientSupplier` so that tracing headers get injected into the `Producer` and `Consumer`s. A `KafkaStreamsTracing` bean allows for further instrumentation through additional `TransformerSupplier` and -`ProcessorSupplier` methods. - -To block this feature, set `spring.sleuth.messaging.kafka.streams.enabled` to `false`. - -[[sleuth-messaging-spring-jms-integration]] -=== Spring JMS - -This feature is available for Brave tracer implementation. - -We instrument the `JmsTemplate` so that tracing headers get injected into the message. -We also support `@JmsListener` annotated methods on the consumer side. - -To block this feature, set `spring.sleuth.messaging.jms.enabled` to `false`. - -IMPORTANT: We don't support baggage propagation for JMS - -[[sleuth-openfeign-integration]] -== OpenFeign - -This feature is available for all tracer implementations. - -By default, Spring Cloud Sleuth provides integration with Feign through `TraceFeignClientAutoConfiguration`. -You can disable it entirely by setting `spring.sleuth.feign.enabled` to `false`. -If you do so, no Feign-related instrumentation take place. - -Part of Feign instrumentation is done through a `FeignBeanPostProcessor`. -You can disable it by setting `spring.sleuth.feign.processor.enabled` to `false`. -If you set it to `false`, Spring Cloud Sleuth does not instrument any of your custom Feign components. -However, all the default instrumentation is still there. - -[[sleuth-opentracing-integration]] -== OpenTracing - -This feature is available for all tracer implementations. - -Spring Cloud Sleuth is compatible with https://opentracing.io/[OpenTracing]. -If you have OpenTracing on the classpath, we automatically register the OpenTracing `Tracer` bean. -If you wish to disable this, set `spring.sleuth.opentracing.enabled` to `false` - -[[sleuth-quartz-integration]] -== Quartz - -This feature is available for all tracer implementations. - -We instrument quartz jobs by adding Job/Trigger listeners to the Quartz Scheduler. - -To turn off this feature, set the `spring.sleuth.quartz.enabled` property to `false`. - -[[sleuth-reactor-integration]] -== Reactor - -This feature is available for all tracer implementations. - -We have three modes of instrumenting reactor based applications that can be set via `spring.sleuth.reactor.instrumentation-type` property: - -* `ON_EACH` - wraps every Reactor operator in a trace representation. -Passes the tracing context in most cases. -This mode might lead to drastic performance degradation. -* `ON_LAST` - wraps last Reactor operator in a trace representation. -Passes the tracing context in some cases thus accessing MDC context might not work. -This mode might lead to medium performance degradation. -* `MANUAL` - wraps every Reactor in the least invasive way without passing of tracing context. -It's up to the user to do it. - -Current default is `ON_EACH` for backward compatibility reasons, however we encourage the users to migrate to the `MANUAL` instrumentation and profit from `WebFluxSleuthOperators` and `MessagingSleuthOperators`. -The performance improvement can be substantial. -Example: - -[source,java,indent=0] ------ -include::{project-root}/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java[tags=simple_manual,indent=0] ------ - -[[sleuth-redis-integration]] -== Redis - -This feature is available for Brave tracer implementation. - -We set `tracing` property to Lettuce `ClientResources` instance to enable Brave tracing built in Lettuce . -To disable Redis support, set the `spring.sleuth.redis.enabled` property to `false`. - -[[sleuth-runnablecallable-integration]] -== Runnable and Callable - -This feature is available for all tracer implementations. - -If you wrap your logic in `Runnable` or `Callable`, you can wrap those classes in their Sleuth representative, as shown in the following example for `Runnable`: - -[source,java,indent=0] ----- -include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java[tags=trace_runnable,indent=0] ----- - -The following example shows how to do so for `Callable`: - -[source,java,indent=0] ----- -include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java[tags=trace_callable,indent=0] ----- - -That way, you ensure that a new span is created and closed for each execution. - -[[sleuth-rpc-integration]] -== RPC - -This feature is available for Brave tracer implementation. - -Sleuth automatically configures the `RpcTracing` bean which serves as a foundation for RPC instrumentation such as gRPC or Dubbo. - -If a customization of client / server sampling of the RPC traces is required, just register a bean of type `brave.sampler.SamplerFunction` and name the bean `sleuthRpcClientSampler` for client sampler and -`sleuthRpcServerSampler` for server sampler. - -For your convenience the `@RpcClientSampler` and `@RpcServerSampler` -annotations can be used to inject the proper beans or to reference the bean names via their static String `NAME` fields. - -Ex. -Here's a sampler that traces 100 "GetUserToken" server requests per second. -This doesn't start new traces for requests to the health check service. -Other requests will use the global sampling configuration. - -[source,java,indent=0] ----- -@Configuration(proxyBeanMethods = false) - class Config { -include::{autoconfig_path}/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/rpc/BraveRpcAutoConfigurationIntegrationTests.java[tags=custom_rpc_server_sampler,indent=2] -} ----- - -For more, see https://github.com/openzipkin/brave/tree/master/instrumentation/rpc#sampling-policy - -[[sleuth-rpc-dubbo-integration]] -=== Dubbo RPC support - -Via the integration with Brave, Spring Cloud Sleuth supports https://dubbo.apache.org/[Dubbo]. -It's enough to add the `brave-instrumentation-dubbo` dependency: - -[source,xml,indent=0] ----- - - io.zipkin.brave - brave-instrumentation-dubbo - ----- - -You need to also set a `dubbo.properties` file with the following contents: - -```properties -dubbo.provider.filter=tracing -dubbo.consumer.filter=tracing -``` - -You can read more about Brave - Dubbo integration https://github.com/openzipkin/brave/tree/master/instrumentation/dubbo-rpc[here]. -An example of Spring Cloud Sleuth and Dubbo can be found https://github.com/openzipkin/sleuth-webmvc-example/compare/add-dubbo-tracing[here]. - -[[sleuth-rpc-grpc-integration]] -=== gRPC - -Spring Cloud Sleuth provides instrumentation for https://grpc.io/[gRPC] via the Brave tracer. -You can disable it entirely by setting `spring.sleuth.grpc.enabled` to `false`. - -[[sleuth-rpc-grpc-variant1-integration]] -==== Variant 1 - -[[sleuth-rpc-grpc-variant1-dependencies-integration]] -===== Dependencies - -IMPORTANT: The gRPC integration relies on two external libraries to instrument clients and servers and both of those libraries must be on the class path to enable the instrumentation. - -Maven: - -``` - - io.github.lognet - grpc-spring-boot-starter - - - io.zipkin.brave - brave-instrumentation-grpc - -``` - -Gradle: - -``` - compile("io.github.lognet:grpc-spring-boot-starter") - compile("io.zipkin.brave:brave-instrumentation-grpc") -``` - -[[sleuth-rpc-grpc-variant1-server-integration]] -===== Server Instrumentation - -Spring Cloud Sleuth leverages grpc-spring-boot-starter to register Brave's gRPC server interceptor with all services annotated with `@GRpcService`. - -[[sleuth-rpc-grpc-variant1-client-integration]] -===== Client Instrumentation - -gRPC clients leverage a `ManagedChannelBuilder` to construct a `ManagedChannel` used to communicate to the gRPC server. -The native `ManagedChannelBuilder` provides static methods as entry points for construction of `ManagedChannel` instances, however, this mechanism is outside the influence of the Spring application context. - -IMPORTANT: Spring Cloud Sleuth provides a `SpringAwareManagedChannelBuilder` that can be customized through the Spring application context and injected by gRPC clients. -*This builder must be used when creating `ManagedChannel` instances.* - -Sleuth creates a `TracingManagedChannelBuilderCustomizer` which inject Brave's client interceptor into the `SpringAwareManagedChannelBuilder`. - -[[sleuth-rpc-grpc-variant2-integration]] -==== Variant 2 - -https://github.com/yidongnan/grpc-spring-boot-starter[Grpc Spring Boot Starter] automatically detects the presence of Spring Cloud Sleuth and Brave's instrumentation for gRPC and registers the necessary client and/or server tooling. - -[[sleuth-rxjava-integration]] -== RxJava - -This feature is available for all tracer implementations. - -We registering a custom https://github.com/ReactiveX/RxJava/wiki/Plugins#rxjavaschedulershook[`RxJavaSchedulersHook`] that wraps all `Action0` instances in their Sleuth representative, which is called `TraceAction`. -The hook either starts or continues a span, depending on whether tracing was already going on before the Action was scheduled. -To disable the custom `RxJavaSchedulersHook`, set the `spring.sleuth.rxjava.schedulers.hook.enabled` to `false`. - -You can define a list of regular expressions for thread names for which you do not want spans to be created. -To do so, provide a comma-separated list of regular expressions in the `spring.sleuth.rxjava.schedulers.ignoredthreads` property. - -IMPORTANT: The suggested approach to reactive programming and Sleuth is to use the Reactor support. - -[[sleuth-circuitbreaker-integration]] -== Spring Cloud CircuitBreaker - -This feature is available for all tracer implementations. - -If you have Spring Cloud CircuitBreaker on the classpath, we will wrap the passed command `Supplier` and the fallback `Function` in its trace representations. -In order to disable this instrumentation set `spring.sleuth.circuitbreaker.enabled` to `false`. \ No newline at end of file +[[sleuth-integration]] += Spring Cloud Sleuth customization + +include::_attributes.adoc[] + +In this section, we describe how to customize various parts of Spring Cloud Sleuth. + +[[sleuth-async-integration]] +== Asynchronous Communication + +In this section, we describe how to customize asynchronous communication with Spring Cloud Sleuth. + +[[sleuth-async-annotation-integration]] +=== `@Async` Annotated methods + +This feature is available for all tracer implementations. + +In Spring Cloud Sleuth, we instrument async-related components so that the tracing information is passed between threads. +You can disable this behavior by setting the value of `spring.sleuth.async.enabled` to `false`. + +If you annotate your method with `@Async`, we automatically modify the existing Span as follows: + +* If the method is annotated with `@SpanName`, the value of the annotation is the Span's name. +* If the method is not annotated with `@SpanName`, the Span name is the annotated method name. +* The span is tagged with the method's class name and method name. + +Since we're modifying the existing span, if you want to maintain its original name (e.g. a span created by receiving an HTTP request) +you should wrap your `@Async` annotated method with a `@NewSpan` annotation or create a new span manually. + +[[sleuth-async-scheduled-integration]] +=== `@Scheduled` Annotated Methods + +This feature is available for all tracer implementations. + +In Spring Cloud Sleuth, we instrument scheduled method execution so that the tracing information is passed between threads. +You can disable this behavior by setting the value of `spring.sleuth.scheduled.enabled` to `false`. + +If you annotate your method with `@Scheduled`, we automatically create a new span with the following characteristics: + +* The span name is the annotated method name. +* The span is tagged with the method's class name and method name. + +If you want to skip span creation for some `@Scheduled` annotated classes, you can set the `spring.sleuth.scheduled.skipPattern` with a regular expression that matches the fully qualified name of the `@Scheduled` annotated class. + +[[sleuth-async-executor-service-integration]] +=== Executor, ExecutorService, and ScheduledExecutorService + +This feature is available for all tracer implementations. + +We provide `LazyTraceExecutor`, `TraceableExecutorService`, and `TraceableScheduledExecutorService`. +Those implementations create spans each time a new task is submitted, invoked, or scheduled. + +The following example shows how to pass tracing information with `TraceableExecutorService` when working with `CompletableFuture`: + +[source,java,indent=0] +---- + +include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java[tags=completablefuture,indent=0] +---- + +IMPORTANT: Sleuth does not work with `parallelStream()` out of the box. +If you want to have the tracing information propagated through the stream, you have to use the approach with `supplyAsync(...)`, as shown earlier. + +If there are beans that implement the `Executor` interface that you would like to exclude from span creation, you can use the `spring.sleuth.async.ignored-beans` +property where you can provide a list of bean names. + +You can disable this behavior by setting the value of `spring.sleuth.async.enabled` to `false`. + +[[sleuth-async-executor-integration]] +==== Customization of Executors + +Sometimes, you need to set up a custom instance of the `AsyncExecutor`. +The following example shows how to set up such a custom `Executor`: + +[source,java,indent=0] +---- +include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/MultipleAsyncRestTemplateTests.java[tags=custom_executor,indent=0] +---- + +TIP: To ensure that your configuration gets post processed, remember to add the `@Role(BeanDefinition.ROLE_INFRASTRUCTURE)` on your +`@Configuration` class + +[[sleuth-http-client-integration]] +== HTTP Client Integration + +Features from this section can be disabled by setting the `spring.sleuth.web.client.enabled` property with value equal to `false`. + +[[sleuth-http-client-rest-template-integration]] +=== Synchronous Rest Template + +This feature is available for all tracer implementations. + +We inject a `RestTemplate` interceptor to ensure that all the tracing information is passed to the requests. +Each time a call is made, a new Span is created. +It gets closed upon receiving the response. +To block the synchronous `RestTemplate` features, set `spring.sleuth.web.client.enabled` to `false`. + +IMPORTANT: You have to register `RestTemplate` as a bean so that the interceptors get injected. +If you create a `RestTemplate` instance with a `new` keyword, the instrumentation does NOT work. + +[[sleuth-http-client-async-rest-template-integration]] +=== Asynchronous Rest Template + +This feature is available for all tracer implementations. + +IMPORTANT: Starting with Sleuth `2.0.0`, we no longer register a bean of `AsyncRestTemplate` type. +It is up to you to create such a bean. +Then we instrument it. + +To block the `AsyncRestTemplate` features, set `spring.sleuth.web.async.client.enabled` to `false`. +To disable creation of the default `TraceAsyncClientHttpRequestFactoryWrapper`, set `spring.sleuth.web.async.client.factory.enabled` +to `false`. +If you do not want to create `AsyncRestClient` at all, set `spring.sleuth.web.async.client.template.enabled` to `false`. + +[[sleuth-http-client-multiple-async-rest-template-integration]] +==== Multiple Asynchronous Rest Templates + +Sometimes you need to use multiple implementations of the Asynchronous Rest Template. +In the following snippet, you can see an example of how to set up such a custom `AsyncRestTemplate`: + +[source,java,indent=0] +---- +include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/MultipleAsyncRestTemplateTests.java[tags=custom_async_rest_template,indent=0] +---- + +[[sleuth-http-client-webclient-integration]] +==== `WebClient` + +This feature is available for all tracer implementations. + +We inject a `ExchangeFilterFunction` implementation that creates a span and, through on-success and on-error callbacks, takes care of closing client-side spans. + +To block this feature, set `spring.sleuth.web.client.enabled` to `false`. + +IMPORTANT: You have to register `WebClient` as a bean so that the tracing instrumentation gets applied. +If you create a `WebClient` instance with a `new` keyword, the instrumentation does NOT work. + +[[sleuth-http-client-traverson-integration]] +==== Traverson + +This feature is available for all tracer implementations. + +If you use the https://docs.spring.io/spring-hateoas/docs/current/reference/html/#client.traverson[Traverson] library, you can inject a `RestTemplate` as a bean into your Traverson object. +Since `RestTemplate` is already intercepted, you get full support for tracing in your client. +The following pseudo code shows how to do that: + +[source,java,indent=0] +---- +@Autowired RestTemplate restTemplate; + +Traverson traverson = new Traverson(URI.create("https://some/address"), + MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8).setRestOperations(restTemplate); +// use Traverson +---- + +[[sleuth-http-client-apache-integration]] +==== Apache `HttpClientBuilder` and `HttpAsyncClientBuilder` + +This feature is available for Brave tracer implementation. + +We instrument the `HttpClientBuilder` and `HttpAsyncClientBuilder` so that tracing context gets injected to the sent requests. + +To block these features, set `spring.sleuth.web.client.enabled` to `false`. + +[[sleuth-http-client-netty-integration]] +==== Netty `HttpClient` + +This feature is available for all tracer implementations. + +We instrument the Netty's `HttpClient`. + +To block this feature, set `spring.sleuth.web.client.enabled` to `false`. + +IMPORTANT: You have to register `HttpClient` as a bean so that the instrumentation happens. +If you create a `HttpClient` instance with a `new` keyword, the instrumentation does NOT work. + +[[sleuth-http-client-userinfo-integration]] +==== `UserInfoRestTemplateCustomizer` + +This feature is available for all tracer implementations. + +We instrument the Spring Security's `UserInfoRestTemplateCustomizer`. + +To block this feature, set `spring.sleuth.web.client.enabled` to `false`. + +[[sleuth-http-server-integration]] +== HTTP Server Integration + +Features from this section can be disabled by setting the `spring.sleuth.web.enabled` property with value equal to `false`. + +[[sleuth-http-server-http-filter-integration]] +=== HTTP Filter + +This feature is available for all tracer implementations. + +Through the `TracingFilter`, all sampled incoming requests result in creation of a Span. +You can configure which URIs you would like to skip by setting the `spring.sleuth.web.skipPattern` property. +If you have `ManagementServerProperties` on classpath, its value of `contextPath` gets appended to the provided skip pattern. +If you want to reuse the Sleuth's default skip patterns and just append your own, pass those patterns by using the `spring.sleuth.web.additionalSkipPattern`. + +By default, all the spring boot actuator endpoints are automatically added to the skip pattern. +If you want to disable this behaviour set `spring.sleuth.web.ignore-auto-configured-skip-patterns` +to `true`. + +To change the order of tracing filter registration, please set the +`spring.sleuth.web.filter-order` property. + +To disable the filter that logs uncaught exceptions you can disable the +`spring.sleuth.web.exception-throwing-filter-enabled` property. + +[[sleuth-http-server-handler-interceptor-integration]] +=== HandlerInterceptor + +This feature is available for all tracer implementations. + +Since we want the span names to be precise, we use a `TraceHandlerInterceptor` that either wraps an existing `HandlerInterceptor` or is added directly to the list of existing `HandlerInterceptors`. +The `TraceHandlerInterceptor` adds a special request attribute to the given `HttpServletRequest`. +If the the `TracingFilter` does not see this attribute, it creates a "`fallback`" span, which is an additional span created on the server side so that the trace is presented properly in the UI. +If that happens, there is probably missing instrumentation. +In that case, please file an issue in Spring Cloud Sleuth. + +[[sleuth-http-server-async-integration]] +=== Async Servlet support + +This feature is available for all tracer implementations. + +If your controller returns a `Callable` or a `WebAsyncTask`, Spring Cloud Sleuth continues the existing span instead of creating a new one. + +[[sleuth-http-server-webflux-integration]] +=== WebFlux support + +This feature is available for all tracer implementations. + +Through `TraceWebFilter`, all sampled incoming requests result in creation of a Span. +That Span's name is `http:` + the path to which the request was sent. +For example, if the request was sent to `/this/that`, the name is `http:/this/that`. +You can configure which URIs you would like to skip by using the `spring.sleuth.web.skipPattern` property. +If you have `ManagementServerProperties` on the classpath, its value of `contextPath` gets appended to the provided skip pattern. +If you want to reuse Sleuth's default skip patterns and append your own, pass those patterns by using the `spring.sleuth.web.additionalSkipPattern`. + +In order to achieve best results in terms of performance and context propagation we suggest that you switch the `spring.sleuth.reactor.instrumentation-type` to `MANUAL`. +In order to execute code with the span in scope you can call `WebFluxSleuthOperators.withSpanInScope`. +Example: + +[source,java,indent=0] +----- +include::{project-root}/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java[tags=simple_manual,indent=0] +----- + +To change the order of tracing filter registration, please set the +`spring.sleuth.web.filter-order` property. + +[[sleuth-messaging-integration]] +== Messaging + +Features from this section can be disabled by setting the `spring.sleuth.messaging.enabled` property with value equal to `false`. + +[[sleuth-messaging-spring-integration-integration]] +=== Spring Integration + +This feature is available for all tracer implementations. + +Spring Cloud Sleuth integrates with https://projects.spring.io/spring-integration/[Spring Integration]. +It creates spans for publish and subscribe events. +To disable Spring Integration instrumentation, set `spring.sleuth.integration.enabled` to `false`. + +You can provide the `spring.sleuth.integration.patterns` pattern to explicitly provide the names of channels that you want to include for tracing. +By default, all channels but `hystrixStreamOutput` channel are included. + +IMPORTANT: When using the `Executor` to build a Spring Integration `IntegrationFlow`, you must use the untraced version of the `Executor`. +Decorating the Spring Integration Executor Channel with `TraceableExecutorService` causes the spans to be improperly closed. + +If you want to customize the way tracing context is read from and written to message headers, it's enough for you to register beans of types: + +* `Propagator.Setter` - for writing headers to the message +* `Propagator.Getter` - for reading headers from the message + +[[sleuth-messaging-spring-integration-customization]] +==== Spring Integration Customization + +==== Customizing messaging spans + +In order to change the default span names and tags, just register a bean of type `MessageSpanCustomizer`. You can also +override the existing `DefaultMessageSpanCustomizer` to extend the existing behaviour. + +[source,java] +---- +@Component +include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java[tags=message_span_customizer,indent=2] +---- + +[[sleuth-messaging-spring-cloud-function-integration]] +=== Spring Cloud Function and Spring Cloud Stream + +This feature is available for all tracer implementations. + +Spring Cloud Sleuth can instrument Spring Cloud Function. +The way to achieve it is to provide a `Function` or `Consumer` or `Supplier` that takes in a `Message` as a parameter e.g. `Function, Message>`. +If the type is not `Message` then instrumentation will not take place. +Out of the box instrumentation will not take place when dealing with Reactor based streams - e.g. `Function>, Flux>>`. + +Since Spring Cloud Stream reuses Spring Cloud Function, you'll get the instrumentation out of the box. + +You can disable this behavior by setting the value of `spring.sleuth.function.enabled` to `false`. + +In order to work with reactive Stream functions you can leverage the `MessagingSleuthOperators` utility class that allows you to manipulate the input and output messages in order to continue the tracing context and to execute custom code within the tracing context. + +[source,java,indent=0] +----- +include::{project-root}/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/stream/SleuthBenchmarkingStreamApplication.java[tags=simple_reactive,indent=0] +----- + +[[sleuth-messaging-spring-rabbitmq-integration]] +=== Spring RabbitMq + +This feature is available for Brave tracer implementation. + +We instrument the `RabbitTemplate` so that tracing headers get injected into the message. + +To block this feature, set `spring.sleuth.messaging.rabbit.enabled` to `false`. + +[[sleuth-messaging-spring-kafka-integration]] +=== Spring Kafka + +This feature is available for Brave tracer implementation. + +We instrument the Spring Kafka's `ProducerFactory` and `ConsumerFactory` +so that tracing headers get injected into the created Spring Kafka's +`Producer` and `Consumer`. + +To block this feature, set `spring.sleuth.messaging.kafka.enabled` to `false`. + +[[sleuth-messaging-spring-kafka-streams-integration]] +=== Spring Kafka Streams + +This feature is available for Brave tracer implementation. + +We instrument the `KafkaStreams` `KafkaClientSupplier` so that tracing headers get injected into the `Producer` and `Consumer`s. A `KafkaStreamsTracing` bean allows for further instrumentation through additional `TransformerSupplier` and +`ProcessorSupplier` methods. + +To block this feature, set `spring.sleuth.messaging.kafka.streams.enabled` to `false`. + +[[sleuth-messaging-spring-jms-integration]] +=== Spring JMS + +This feature is available for Brave tracer implementation. + +We instrument the `JmsTemplate` so that tracing headers get injected into the message. +We also support `@JmsListener` annotated methods on the consumer side. + +To block this feature, set `spring.sleuth.messaging.jms.enabled` to `false`. + +IMPORTANT: We don't support baggage propagation for JMS + +[[sleuth-openfeign-integration]] +== OpenFeign + +This feature is available for all tracer implementations. + +By default, Spring Cloud Sleuth provides integration with Feign through `TraceFeignClientAutoConfiguration`. +You can disable it entirely by setting `spring.sleuth.feign.enabled` to `false`. +If you do so, no Feign-related instrumentation take place. + +Part of Feign instrumentation is done through a `FeignBeanPostProcessor`. +You can disable it by setting `spring.sleuth.feign.processor.enabled` to `false`. +If you set it to `false`, Spring Cloud Sleuth does not instrument any of your custom Feign components. +However, all the default instrumentation is still there. + +[[sleuth-opentracing-integration]] +== OpenTracing + +This feature is available for all tracer implementations. + +Spring Cloud Sleuth is compatible with https://opentracing.io/[OpenTracing]. +If you have OpenTracing on the classpath, we automatically register the OpenTracing `Tracer` bean. +If you wish to disable this, set `spring.sleuth.opentracing.enabled` to `false` + +[[sleuth-quartz-integration]] +== Quartz + +This feature is available for all tracer implementations. + +We instrument quartz jobs by adding Job/Trigger listeners to the Quartz Scheduler. + +To turn off this feature, set the `spring.sleuth.quartz.enabled` property to `false`. + +[[sleuth-reactor-integration]] +== Reactor + +This feature is available for all tracer implementations. + +We have the following modes of instrumenting reactor based applications that can be set via `spring.sleuth.reactor.instrumentation-type` property: + +* `DECORATE_QUEUES` - With the new Reactor https://github.com/reactor/reactor-core/pull/2566[queue wrapping mechanism] (Reactor 3.4.3) we're instrumenting the way threads are switched by Reactor. This should lead to feature parity with `ON_EACH` with low performance impact. +* `DECORATE_ON_EACH` - wraps every Reactor operator in a trace representation. +Passes the tracing context in most cases. +This mode might lead to drastic performance degradation. +* `DECORATE_ON_LAST` - wraps last Reactor operator in a trace representation. +Passes the tracing context in some cases thus accessing MDC context might not work. +This mode might lead to medium performance degradation. +* `MANUAL` - wraps every Reactor in the least invasive way without passing of tracing context. +It's up to the user to do it. + +Current default is `ON_EACH` for backward compatibility reasons, however we encourage the users to migrate to the `MANUAL` instrumentation and profit from `WebFluxSleuthOperators` and `MessagingSleuthOperators`. +The performance improvement can be substantial. +Example: + +[source,java,indent=0] +----- +include::{project-root}/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java[tags=simple_manual,indent=0] +----- + +[[sleuth-redis-integration]] +== Redis + +This feature is available for Brave tracer implementation. + +We set `tracing` property to Lettuce `ClientResources` instance to enable Brave tracing built in Lettuce . +To disable Redis support, set the `spring.sleuth.redis.enabled` property to `false`. + +[[sleuth-runnablecallable-integration]] +== Runnable and Callable + +This feature is available for all tracer implementations. + +If you wrap your logic in `Runnable` or `Callable`, you can wrap those classes in their Sleuth representative, as shown in the following example for `Runnable`: + +[source,java,indent=0] +---- +include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java[tags=trace_runnable,indent=0] +---- + +The following example shows how to do so for `Callable`: + +[source,java,indent=0] +---- +include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java[tags=trace_callable,indent=0] +---- + +That way, you ensure that a new span is created and closed for each execution. + +[[sleuth-rpc-integration]] +== RPC + +This feature is available for Brave tracer implementation. + +Sleuth automatically configures the `RpcTracing` bean which serves as a foundation for RPC instrumentation such as gRPC or Dubbo. + +If a customization of client / server sampling of the RPC traces is required, just register a bean of type `brave.sampler.SamplerFunction` and name the bean `sleuthRpcClientSampler` for client sampler and +`sleuthRpcServerSampler` for server sampler. + +For your convenience the `@RpcClientSampler` and `@RpcServerSampler` +annotations can be used to inject the proper beans or to reference the bean names via their static String `NAME` fields. + +Ex. +Here's a sampler that traces 100 "GetUserToken" server requests per second. +This doesn't start new traces for requests to the health check service. +Other requests will use the global sampling configuration. + +[source,java,indent=0] +---- +@Configuration(proxyBeanMethods = false) + class Config { +include::{autoconfig_path}/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/rpc/BraveRpcAutoConfigurationIntegrationTests.java[tags=custom_rpc_server_sampler,indent=2] +} +---- + +For more, see https://github.com/openzipkin/brave/tree/master/instrumentation/rpc#sampling-policy + +[[sleuth-rpc-dubbo-integration]] +=== Dubbo RPC support + +Via the integration with Brave, Spring Cloud Sleuth supports https://dubbo.apache.org/[Dubbo]. +It's enough to add the `brave-instrumentation-dubbo` dependency: + +[source,xml,indent=0] +---- + + io.zipkin.brave + brave-instrumentation-dubbo + +---- + +You need to also set a `dubbo.properties` file with the following contents: + +```properties +dubbo.provider.filter=tracing +dubbo.consumer.filter=tracing +``` + +You can read more about Brave - Dubbo integration https://github.com/openzipkin/brave/tree/master/instrumentation/dubbo-rpc[here]. +An example of Spring Cloud Sleuth and Dubbo can be found https://github.com/openzipkin/sleuth-webmvc-example/compare/add-dubbo-tracing[here]. + +[[sleuth-rpc-grpc-integration]] +=== gRPC + +Spring Cloud Sleuth provides instrumentation for https://grpc.io/[gRPC] via the Brave tracer. +You can disable it entirely by setting `spring.sleuth.grpc.enabled` to `false`. + +[[sleuth-rpc-grpc-variant1-integration]] +==== Variant 1 + +[[sleuth-rpc-grpc-variant1-dependencies-integration]] +===== Dependencies + +IMPORTANT: The gRPC integration relies on two external libraries to instrument clients and servers and both of those libraries must be on the class path to enable the instrumentation. + +Maven: + +``` + + io.github.lognet + grpc-spring-boot-starter + + + io.zipkin.brave + brave-instrumentation-grpc + +``` + +Gradle: + +``` + compile("io.github.lognet:grpc-spring-boot-starter") + compile("io.zipkin.brave:brave-instrumentation-grpc") +``` + +[[sleuth-rpc-grpc-variant1-server-integration]] +===== Server Instrumentation + +Spring Cloud Sleuth leverages grpc-spring-boot-starter to register Brave's gRPC server interceptor with all services annotated with `@GRpcService`. + +[[sleuth-rpc-grpc-variant1-client-integration]] +===== Client Instrumentation + +gRPC clients leverage a `ManagedChannelBuilder` to construct a `ManagedChannel` used to communicate to the gRPC server. +The native `ManagedChannelBuilder` provides static methods as entry points for construction of `ManagedChannel` instances, however, this mechanism is outside the influence of the Spring application context. + +IMPORTANT: Spring Cloud Sleuth provides a `SpringAwareManagedChannelBuilder` that can be customized through the Spring application context and injected by gRPC clients. +*This builder must be used when creating `ManagedChannel` instances.* + +Sleuth creates a `TracingManagedChannelBuilderCustomizer` which inject Brave's client interceptor into the `SpringAwareManagedChannelBuilder`. + +[[sleuth-rpc-grpc-variant2-integration]] +==== Variant 2 + +https://github.com/yidongnan/grpc-spring-boot-starter[Grpc Spring Boot Starter] automatically detects the presence of Spring Cloud Sleuth and Brave's instrumentation for gRPC and registers the necessary client and/or server tooling. + +[[sleuth-rxjava-integration]] +== RxJava + +This feature is available for all tracer implementations. + +We registering a custom https://github.com/ReactiveX/RxJava/wiki/Plugins#rxjavaschedulershook[`RxJavaSchedulersHook`] that wraps all `Action0` instances in their Sleuth representative, which is called `TraceAction`. +The hook either starts or continues a span, depending on whether tracing was already going on before the Action was scheduled. +To disable the custom `RxJavaSchedulersHook`, set the `spring.sleuth.rxjava.schedulers.hook.enabled` to `false`. + +You can define a list of regular expressions for thread names for which you do not want spans to be created. +To do so, provide a comma-separated list of regular expressions in the `spring.sleuth.rxjava.schedulers.ignoredthreads` property. + +IMPORTANT: The suggested approach to reactive programming and Sleuth is to use the Reactor support. + +[[sleuth-circuitbreaker-integration]] +== Spring Cloud CircuitBreaker + +This feature is available for all tracer implementations. + +If you have Spring Cloud CircuitBreaker on the classpath, we will wrap the passed command `Supplier` and the fallback `Function` in its trace representations. We will also instrument the reactive implementation of the CircuitBreaker. +In order to disable this instrumentation set `spring.sleuth.circuitbreaker.enabled` to `false`. + +[[sleuth-config-server-integration]] +== Spring Cloud Config Server + +This feature is available for all tracer implementations. + +If you have Spring Cloud Config Server running on the classpath, we will wrap the `EnvironmentRepository` in a span. +In order to disable this instrumentation set `spring.sleuth.config.server.enabled` to `false`. + +[[sleuth-deployer-integration]] +== Spring Cloud Deployer + +This feature is available for all tracer implementations. + +If you have Spring Cloud Deployer running on the classpath, we wrap the `AppDeployer` in a trace representation. We are polling the application for its status at a default interval. You can change that default by setting the `spring.sleuth.deployer.status-poll-delay` property. +In order to disable this instrumentation set `spring.sleuth.deployer.enabled` to `false`. + + +[[sleuth-deployer-integration]] +== Spring RSocket + +This feature is available for all tracer implementations. + +If you have Spring RSocket running on the classpath, we wrap the inbound and outbound communication to propagate the tracing context via the metadata. +In order to disable this instrumentation set `spring.sleuth.rsocket.enabled` to `false`. diff --git a/docs/src/main/asciidoc/legal.adoc b/docs/src/main/asciidoc/legal.adoc index cc02760e7..8d6a7e9ad 100644 --- a/docs/src/main/asciidoc/legal.adoc +++ b/docs/src/main/asciidoc/legal.adoc @@ -3,6 +3,6 @@ {project-version} -Copyright © 2012-2020 +Copyright © 2012-2021 Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically. \ No newline at end of file diff --git a/docs/src/main/asciidoc/project-features.adoc b/docs/src/main/asciidoc/project-features.adoc index 63201f262..fb84d25c7 100644 --- a/docs/src/main/asciidoc/project-features.adoc +++ b/docs/src/main/asciidoc/project-features.adoc @@ -316,6 +316,13 @@ object, you will have to create a bean of `zipkin2.reporter.Sender` type. } ---- +By default, api path will be set to `api/v2/spans` or `api/v1/spans` depending on the encoder version. If you want to use a custom api path, you can configure it using the following property (empty case, set ""): + +[source,yaml] +---- +spring.zipkin.api-path: v2/path2 +---- + [[features-zipkin-custom-service-name]] === Custom service name diff --git a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc deleted file mode 120000 index 1abdb4fda..000000000 --- a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc +++ /dev/null @@ -1 +0,0 @@ -index.htmladoc \ No newline at end of file diff --git a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc new file mode 100644 index 000000000..d0a241950 --- /dev/null +++ b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc @@ -0,0 +1,18 @@ +[[spring-cloud-sleuth-reference-documentation]] += Spring Cloud Sleuth Reference Documentation +Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer, Jay Bryant + +:docinfo: shared +include::_attributes.adoc[] + +The reference documentation consists of the following sections: + +[horizontal] +<> :: Legal information. +<> :: About the Documentation, Getting Help, First Steps, and more. +<> :: Introducing {project-full-name}, Developing Your First {project-full-name}-based Application +<> :: {project-full-name} usage examples and workflows. +<> :: Span creation, context propagation, and more. +<> :: Add sampling, propagate remote tags, and more. +<> :: Instrumentation configuration, context propagation, and more. +<> :: Configuration properties. diff --git a/docs/src/main/asciidoc/spring-cloud-sleuth.htmlsingleadoc b/docs/src/main/asciidoc/spring-cloud-sleuth.htmlsingleadoc deleted file mode 120000 index edc86da18..000000000 --- a/docs/src/main/asciidoc/spring-cloud-sleuth.htmlsingleadoc +++ /dev/null @@ -1 +0,0 @@ -index.htmlsingleadoc \ No newline at end of file diff --git a/docs/src/main/asciidoc/spring-cloud-sleuth.htmlsingleadoc b/docs/src/main/asciidoc/spring-cloud-sleuth.htmlsingleadoc new file mode 100644 index 000000000..741b91da1 --- /dev/null +++ b/docs/src/main/asciidoc/spring-cloud-sleuth.htmlsingleadoc @@ -0,0 +1,14 @@ +[[spring-cloud-sleuth-reference-documentation]] += Spring Cloud Sleuth Reference Documentation +Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer, Jay Bryant + +:docinfo: shared +include::_attributes.adoc[] + +include::legal.adoc[leveloffset=+1] +include::getting-started.adoc[leveloffset=+1] +include::using.adoc[leveloffset=+1] +include::project-features.adoc[leveloffset=+1] +include::howto.adoc[leveloffset=+1] +include::integrations.adoc[leveloffset=+1] +include::appendix.adoc[leveloffset=+1] \ No newline at end of file diff --git a/docs/src/main/asciidoc/spring-cloud-sleuth.pdfadoc b/docs/src/main/asciidoc/spring-cloud-sleuth.pdfadoc index 572640be0..e1edcb891 100644 --- a/docs/src/main/asciidoc/spring-cloud-sleuth.pdfadoc +++ b/docs/src/main/asciidoc/spring-cloud-sleuth.pdfadoc @@ -1 +1,13 @@ -include::_index_pdf.adoc[] \ No newline at end of file +[[spring-cloud-sleuth-reference-documentation]] += Spring Cloud Sleuth Reference Documentation +Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer, Jay Bryant + +include::_attributes.adoc[] + +include::legal.adoc[leveloffset=+1] +include::getting-started.adoc[leveloffset=+1] +include::using.adoc[leveloffset=+1] +include::project-features.adoc[leveloffset=+1] +include::howto.adoc[leveloffset=+1] +include::integrations.adoc[leveloffset=+1] +include::appendix.adoc[leveloffset=+1] diff --git a/pom.xml b/pom.xml index baa7df39c..7a970cd8d 100644 --- a/pom.xml +++ b/pom.xml @@ -1,442 +1,474 @@ - - - - - 4.0.0 - - spring-cloud-sleuth - 3.0.2-SNAPSHOT - pom - Spring Cloud Sleuth - Spring Cloud Sleuth - - - org.springframework.cloud - spring-cloud-build - 3.0.2-SNAPSHOT - - - - - - https://github.com/spring-cloud/spring-cloud-sleuth - scm:git:git://github.com/spring-cloud/spring-cloud-sleuth.git - - - scm:git:ssh://git@github.com/spring-cloud/spring-cloud-sleuth.git - - HEAD - - - - spring-cloud-sleuth-dependencies - spring-cloud-sleuth-api - spring-cloud-sleuth-instrumentation - spring-cloud-sleuth-brave - spring-cloud-sleuth-autoconfigure - tests - spring-cloud-sleuth-zipkin - spring-cloud-starter-sleuth - spring-cloud-sleuth-samples - docs - - - - 1.8 - 1.8 - 1.8 - 1.8 - 3.0.2-SNAPSHOT - 3.0.2-SNAPSHOT - 3.0.2-SNAPSHOT - 2.0.1-SNAPSHOT - 3.1.1-SNAPSHOT - 3.1.2-SNAPSHOT - 3.0.2-SNAPSHOT - 3.0.2-SNAPSHOT - 5.13.2 - 1.3.3 - 2.6.2 - 0.32.0 - 2.3.4.RELEASE - false - 4.9.0 - 4.8.0 - 20.0 - 1.7.1 - 3.3.0 - 3.0.1 - 2.2.0.RELEASE - - - true - false - 3.8.1 - 2.2 - 4.0.3 - 0.21.3 - 0.14.1 - - - - - - - maven-compiler-plugin - 3.8.1 - - - default-compile - - true - true - - ${maven.compiler.source} - ${maven.compiler.target} - - - - - default-testCompile - - true - true - - ${maven.compiler.testSource} - ${maven.compiler.testTarget} - - - - - - - maven-enforcer-plugin - 1.3.1 - - - enforce-java - - enforce - - - - - ${maven.compiler.testTarget} - - - - - - - - maven-deploy-plugin - 2.8.2 - - - - - - io.spring.javaformat - spring-javaformat-maven-plugin - - - maven-checkstyle-plugin - - - - - - - - maven-checkstyle-plugin - - - maven-surefire-report-plugin - - - - - - - - org.springframework.cloud - spring-cloud-sleuth-dependencies - ${project.version} - pom - import - - - org.springframework.cloud - spring-cloud-netflix-dependencies - ${spring-cloud-netflix.version} - pom - import - - - org.springframework.cloud - spring-cloud-commons-dependencies - ${spring-cloud-commons.version} - pom - import - - - org.springframework.cloud - spring-cloud-gateway-dependencies - ${spring-cloud-gateway.version} - pom - import - - - org.springframework.cloud - spring-cloud-circuitbreaker-dependencies - ${spring-cloud-circuitbreaker.version} - pom - import - - - org.springframework.cloud - spring-cloud-stream-dependencies - ${spring-cloud-stream.version} - pom - import - - - org.springframework.cloud - spring-cloud-function-dependencies - ${spring-cloud-function.version} - pom - import - - - org.springframework.cloud - spring-cloud-openfeign-dependencies - ${spring-cloud-openfeign.version} - pom - import - - - org.springframework.security.oauth.boot - spring-security-oauth2-autoconfigure - ${spring-security-boot-autoconfigure.version} - true - - - com.wavefront - wavefront-runtime-sdk-jvm - ${wavefront-runtime-sdk-jvm.version} - true - - - com.wavefront - wavefront-sdk-java - ${wavefront-sdk-java.version} - true - - - cglib - cglib-nodep - ${cglib-nodep.version} - - - org.objenesis - objenesis - ${objenesis.version} - - - - com.squareup.okhttp3 - mockwebserver - ${mockwebserver.version} - - - org.springframework.security.oauth - spring-security-oauth2 - ${spring-security-oauth2.version} - - - io.zipkin.aws - brave-propagation-aws - ${brave-propagation-aws.version} - - - org.hamcrest - hamcrest-core - ${hamcrest-core.version} - test - - - org.awaitility - awaitility - ${awaitility.version} - test - - - com.tngtech.archunit - archunit-junit5 - ${archunit-junit5.version} - - - - - - - spring - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - false - - - - - jfrog-snapshots - JFrog Snapshots - https://oss.jfrog.org/oss-snapshot-local/ - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/release - - false - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/release - - false - - - - - - ide - - false - - - - - maven-compiler-plugin - - ${maven.compiler.testSource} - ${maven.compiler.testTarget} - - - - - - - benchmarks - - false - - - benchmarks - - - - sonar - - - - org.jacoco - jacoco-maven-plugin - - - pre-unit-test - - prepare-agent - - - surefireArgLine - ${project.build.directory}/jacoco.exec - - - - - post-unit-test - test - - report - - - - ${project.build.directory}/jacoco.exec - - - - - - - maven-surefire-plugin - - - ${surefireArgLine} - - - - - - - - + + + + + 4.0.0 + + spring-cloud-sleuth + 3.1.0-SNAPSHOT + pom + Spring Cloud Sleuth + Spring Cloud Sleuth + + + org.springframework.cloud + spring-cloud-build + 3.0.3-SNAPSHOT + + + + + + https://github.com/spring-cloud/spring-cloud-sleuth + scm:git:git://github.com/spring-cloud/spring-cloud-sleuth.git + + + scm:git:ssh://git@github.com/spring-cloud/spring-cloud-sleuth.git + + HEAD + + + + spring-cloud-sleuth-dependencies + spring-cloud-sleuth-api + spring-cloud-sleuth-instrumentation + spring-cloud-sleuth-brave + spring-cloud-sleuth-autoconfigure + tests + spring-cloud-sleuth-zipkin + spring-cloud-starter-sleuth + spring-cloud-sleuth-samples + docs + + + + 1.8 + 1.8 + 1.8 + 1.8 + 3.0.3-SNAPSHOT + 3.0.3-SNAPSHOT + 3.0.3-SNAPSHOT + 3.0.3-SNAPSHOT + 2.0.2-SNAPSHOT + 3.1.3-SNAPSHOT + 3.1.3-SNAPSHOT + 3.0.3-SNAPSHOT + 3.0.3-SNAPSHOT + 2.3.2-SNAPSHOT + 2.5.1 + 5.13.2 + 1.3.3 + 2.6.2 + 0.32.0 + 2.3.4.RELEASE + false + 4.9.0 + 4.8.0 + 20.0 + 1.7.1 + 3.3.0 + 3.0.1 + 2.2.0.RELEASE + + + true + false + 3.8.1 + 2.2 + 4.0.3 + 0.21.3 + 0.14.1 + 1.15.3 + + + + + + + maven-compiler-plugin + 3.8.1 + + + default-compile + + true + true + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + default-testCompile + + true + true + + ${maven.compiler.testSource} + ${maven.compiler.testTarget} + + + + + + + maven-enforcer-plugin + 1.3.1 + + + enforce-java + + enforce + + + + + ${maven.compiler.testTarget} + + + + + + + + maven-deploy-plugin + 2.8.2 + + + + + + io.spring.javaformat + spring-javaformat-maven-plugin + + + maven-checkstyle-plugin + + + + + + + + maven-checkstyle-plugin + + + maven-surefire-report-plugin + + + + + + + + org.springframework.cloud + spring-cloud-sleuth-dependencies + ${project.version} + pom + import + + + org.springframework.cloud + spring-cloud-netflix-dependencies + ${spring-cloud-netflix.version} + pom + import + + + org.springframework.cloud + spring-cloud-commons-dependencies + ${spring-cloud-commons.version} + pom + import + + + org.springframework.cloud + spring-cloud-gateway-dependencies + ${spring-cloud-gateway.version} + pom + import + + + org.springframework.cloud + spring-cloud-circuitbreaker-dependencies + ${spring-cloud-circuitbreaker.version} + pom + import + + + org.springframework.cloud + spring-cloud-stream-dependencies + ${spring-cloud-stream.version} + pom + import + + + org.springframework.cloud + spring-cloud-function-dependencies + ${spring-cloud-function.version} + pom + import + + + org.springframework.cloud + spring-cloud-openfeign-dependencies + ${spring-cloud-openfeign.version} + pom + import + + + org.springframework.cloud + spring-cloud-config-dependencies + ${spring-cloud-config.version} + pom + import + + + org.springframework.cloud + spring-cloud-task-dependencies + ${spring-cloud-task.version} + pom + import + + + org.springframework.cloud + spring-cloud-deployer-dependencies + ${spring-cloud-deployer.version} + import + pom + + + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure + ${spring-security-boot-autoconfigure.version} + true + + + com.wavefront + wavefront-runtime-sdk-jvm + ${wavefront-runtime-sdk-jvm.version} + true + + + com.wavefront + wavefront-sdk-java + ${wavefront-sdk-java.version} + true + + + cglib + cglib-nodep + ${cglib-nodep.version} + + + org.objenesis + objenesis + ${objenesis.version} + + + + com.squareup.okhttp3 + mockwebserver + ${mockwebserver.version} + + + org.springframework.security.oauth + spring-security-oauth2 + ${spring-security-oauth2.version} + + + io.zipkin.aws + brave-propagation-aws + ${brave-propagation-aws.version} + + + org.hamcrest + hamcrest-core + ${hamcrest-core.version} + test + + + org.awaitility + awaitility + ${awaitility.version} + test + + + com.tngtech.archunit + archunit-junit5 + ${archunit-junit5.version} + + + org.testcontainers + testcontainers-bom + ${testcontainers.version} + pom + import + + + + + + + spring + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + false + + + + + jfrog-snapshots + JFrog Snapshots + https://oss.jfrog.org/oss-snapshot-local/ + + true + + + false + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + spring-releases + Spring Releases + https://repo.spring.io/release + + false + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + false + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + spring-releases + Spring Releases + https://repo.spring.io/release + + false + + + + + + ide + + false + + + + + maven-compiler-plugin + + ${maven.compiler.testSource} + ${maven.compiler.testTarget} + + + + + + + benchmarks + + false + + + benchmarks + + + + sonar + + + + org.jacoco + jacoco-maven-plugin + + + pre-unit-test + + prepare-agent + + + surefireArgLine + ${project.build.directory}/jacoco.exec + + + + + post-unit-test + test + + report + + + + ${project.build.directory}/jacoco.exec + + + + + + + maven-surefire-plugin + + + ${surefireArgLine} + + + + + + + + diff --git a/spring-cloud-sleuth-api/pom.xml b/spring-cloud-sleuth-api/pom.xml index 9fb4fbeb6..59766a458 100644 --- a/spring-cloud-sleuth-api/pom.xml +++ b/spring-cloud-sleuth-api/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/BaggageInScope.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/BaggageInScope.java index 268aaff40..70f56a5fd 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/BaggageInScope.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/BaggageInScope.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/BaggageManager.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/BaggageManager.java index 459f071e4..861ae6843 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/BaggageManager.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/BaggageManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/CurrentTraceContext.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/CurrentTraceContext.java index c92c7d910..aaece67cb 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/CurrentTraceContext.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/CurrentTraceContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SamplerFunction.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SamplerFunction.java index ded583cea..6edbe35fc 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SamplerFunction.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SamplerFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/ScopedSpan.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/ScopedSpan.java index 44ea086d3..adf4696b2 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/ScopedSpan.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/ScopedSpan.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/Span.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/Span.java index 769f7a3c9..74373c54d 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/Span.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/Span.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -89,6 +89,16 @@ public interface Span extends SpanCustomizer { */ void abandon(); + /** + * Sets the remote service name for the span. + * @param remoteServiceName remote service name + * @return this span + * @since 3.0.3 + */ + default Span remoteServiceName(String remoteServiceName) { + return this; + } + /** * Type of span. Can be used to specify additional relationships between spans in * addition to a parent/child relationship. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanAndScope.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanAndScope.java new file mode 100644 index 000000000..807e871c6 --- /dev/null +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanAndScope.java @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2021 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 + * + * https://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; + +/** + * Container object for {@link Span} and its corresponding {@link Tracer.SpanInScope}. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class SpanAndScope { + + private final Span span; + + private final Tracer.SpanInScope scope; + + public SpanAndScope(Span span, Tracer.SpanInScope scope) { + this.span = span; + this.scope = scope; + } + + public Span getSpan() { + return this.span; + } + + public Tracer.SpanInScope getScope() { + return this.scope; + } + + @Override + public String toString() { + return "SpanAndScope{" + "span=" + this.span + '}'; + } + +} diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanCustomizer.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanCustomizer.java index 8b8718103..a00a108fb 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanCustomizer.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanName.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanName.java index d80e95650..44b17e55d 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanName.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanName.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanNamer.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanNamer.java index e75deb94f..f0cee8e44 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanNamer.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanNamer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/ThreadLocalSpan.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/ThreadLocalSpan.java new file mode 100644 index 000000000..aa2c0226b --- /dev/null +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/ThreadLocalSpan.java @@ -0,0 +1,90 @@ +/* + * Copyright 2013-2021 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 + * + * https://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; + +import java.util.Deque; +import java.util.NoSuchElementException; +import java.util.concurrent.LinkedBlockingDeque; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Represents a {@link Span} stored in thread local. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class ThreadLocalSpan { + + private static final Log log = LogFactory.getLog(ThreadLocalSpan.class); + + private final ThreadLocal threadLocalSpan = new ThreadLocal<>(); + + private final Deque spans = new LinkedBlockingDeque<>(); + + private final Tracer tracer; + + public ThreadLocalSpan(Tracer tracer) { + this.tracer = tracer; + } + + /** + * Sets given span and scope. + * @param span - span to be put in scope + */ + public void set(Span span) { + Tracer.SpanInScope spanInScope = this.tracer.withSpan(span); + SpanAndScope newSpanAndScope = new SpanAndScope(span, spanInScope); + SpanAndScope scope = this.threadLocalSpan.get(); + if (scope != null) { + this.spans.addFirst(scope); + } + this.threadLocalSpan.set(newSpanAndScope); + } + + /** + * @return currently stored span and scope + */ + public SpanAndScope get() { + return this.threadLocalSpan.get(); + } + + /** + * Removes the current span from thread local and brings back the previous span to the + * current thread local. + */ + public void remove() { + this.threadLocalSpan.remove(); + if (this.spans.isEmpty()) { + return; + } + try { + SpanAndScope span = this.spans.removeFirst(); + if (log.isDebugEnabled()) { + log.debug("Took span [" + span + "] from thread local"); + } + this.threadLocalSpan.set(span); + } + catch (NoSuchElementException ex) { + if (log.isTraceEnabled()) { + log.trace("Failed to remove a span from the queue", ex); + } + } + } + +} diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/TraceContext.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/TraceContext.java index 65157b0df..15cb7231e 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/TraceContext.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/TraceContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -51,4 +51,47 @@ public interface TraceContext { */ Boolean sampled(); + /** + * Builder for {@link TraceContext}. + * + * @since 3.1.0 + */ + interface Builder { + + /** + * Sets trace id on the trace context. + * @param traceId trace id + * @return this + */ + TraceContext.Builder traceId(String traceId); + + /** + * Sets parent id on the trace context. + * @param parentId parent trace id + * @return this + */ + TraceContext.Builder parentId(String parentId); + + /** + * Sets span id on the trace context. + * @param spanId span id + * @return this + */ + TraceContext.Builder spanId(String spanId); + + /** + * Sets sampled on the trace context. + * @param sampled if span is sampled + * @return this + */ + TraceContext.Builder sampled(Boolean sampled); + + /** + * Builds the trace context. + * @return trace context + */ + TraceContext build(); + + } + } diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/Tracer.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/Tracer.java index 86a027864..b5a06b5b9 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/Tracer.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/Tracer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -134,6 +134,12 @@ public interface Tracer extends BaggageManager { */ Span.Builder spanBuilder(); + /** + * Builder for {@link TraceContext}. + * @return a trace context builder + */ + TraceContext.Builder traceContextBuilder(); + /** * Allows to customize the current span in scope. * @return current span customizer diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/WithThreadLocalSpan.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/WithThreadLocalSpan.java new file mode 100644 index 000000000..89aec40f8 --- /dev/null +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/WithThreadLocalSpan.java @@ -0,0 +1,91 @@ +/* + * Copyright 2013-2021 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 + * + * https://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; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.lang.Nullable; + +/** + * Represents a {@link Span} stored in thread local. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public interface WithThreadLocalSpan { + + /** + * Logger. + */ + Log log = LogFactory.getLog(WithThreadLocalSpan.class); + + /** + * Sets the span in thread local scope. + * @param span span to put in thread local + */ + default void setSpanInScope(Span span) { + getThreadLocalSpan().set(span); + if (log.isDebugEnabled()) { + log.debug("Put span in scope " + span); + } + } + + /** + * Finishes the thread local span. + * @param error potential error to be stored in span + */ + default void finishSpan(@Nullable Throwable error) { + SpanAndScope spanAndScope = takeSpanFromThreadLocal(); + if (spanAndScope == null) { + return; + } + Span span = spanAndScope.getSpan(); + Tracer.SpanInScope scope = spanAndScope.getScope(); + if (span.isNoop()) { + if (log.isDebugEnabled()) { + log.debug("Span " + span + " is noop - will stope the scope"); + } + scope.close(); + return; + } + if (error != null) { // an error occurred, adding error to span + span.error(error); + } + if (log.isDebugEnabled()) { + log.debug("Will finish the span and its corresponding scope " + span); + } + span.end(); + scope.close(); + } + + /** + * Takes a span from thread local and restores the previous one if present. + * @return span from a thread local span + */ + default SpanAndScope takeSpanFromThreadLocal() { + SpanAndScope span = getThreadLocalSpan().get(); + if (log.isDebugEnabled()) { + log.debug("Took span [" + span + "] from thread local"); + } + getThreadLocalSpan().remove(); + return span; + } + + ThreadLocalSpan getThreadLocalSpan(); + +} diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/ContinueSpan.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/ContinueSpan.java index eebe14a22..f9f625fc0 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/ContinueSpan.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/ContinueSpan.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpan.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpan.java index f68660794..28d9114aa 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpan.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpan.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpanParser.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpanParser.java index bd2d3ffb5..eb4791aed 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpanParser.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpanParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolver.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolver.java index 82e021172..70a91420a 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolver.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthMethodInvocationProcessor.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthMethodInvocationProcessor.java index a6fd706d4..9bfbed59b 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthMethodInvocationProcessor.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthMethodInvocationProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTag.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTag.java index d56a3c9b9..ba812c4fe 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTag.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTag.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueExpressionResolver.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueExpressionResolver.java index 8342a1d3f..662eeeeff 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueExpressionResolver.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueExpressionResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueResolver.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueResolver.java index f5708c46a..8fde99e03 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueResolver.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/autoconfig/SingleSkipPattern.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/autoconfig/SingleSkipPattern.java index 12a5293c1..0c39356ca 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/autoconfig/SingleSkipPattern.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/autoconfig/SingleSkipPattern.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/FinishedSpan.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/FinishedSpan.java index 73d4d121a..5daee0411 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/FinishedSpan.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/FinishedSpan.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -80,7 +80,9 @@ public interface FinishedSpan { * @return span's local ip */ @Nullable - String getLocalIp(); + default String getLocalIp() { + return null; + } /** * @return span's remote port diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/SpanFilter.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/SpanFilter.java index 756b3e044..4b1432ab1 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/SpanFilter.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/SpanFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/SpanIgnoringSpanFilter.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/SpanIgnoringSpanFilter.java index 49a7b8d50..d38cb659b 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/SpanIgnoringSpanFilter.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/SpanIgnoringSpanFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientHandler.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientHandler.java index 5aac0f7f9..afe0fd92a 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientHandler.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientRequest.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientRequest.java index ea5d9fa9f..22b5c037b 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientRequest.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientResponse.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientResponse.java index 99ffa6f87..3c356f2e1 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientResponse.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpRequest.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpRequest.java index 2fa3ce7d4..890257d33 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpRequest.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpRequestParser.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpRequestParser.java index 4edd2c055..001f477fa 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpRequestParser.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpRequestParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpResponse.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpResponse.java index f8b2fc8ee..2c7be8917 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpResponse.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpResponseParser.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpResponseParser.java index eef2026fc..ac129315d 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpResponseParser.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpResponseParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerHandler.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerHandler.java index 47c4f5b20..9d65b65d2 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerHandler.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerRequest.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerRequest.java index 3da043e2c..93f97211d 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerRequest.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerResponse.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerResponse.java index 4c76251e7..76acc57e3 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerResponse.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/Request.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/Request.java index ea7af4287..bd371523a 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/Request.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/Request.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/Response.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/Response.java index 4f74be603..8fffaec45 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/Response.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/Response.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/propagation/Propagator.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/propagation/Propagator.java index bdedb6de0..dfa72c8ba 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/propagation/Propagator.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/propagation/Propagator.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/ArchitectureTests.java b/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/ArchitectureTests.java index 434c404af..53b9421e7 100644 --- a/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/ArchitectureTests.java +++ b/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/ArchitectureTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolverTests.java b/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolverTests.java index 75ce679cd..0fa85b175 100644 --- a/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolverTests.java +++ b/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/exporter/SpanIgnoringSpanFilterTests.java b/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/exporter/SpanIgnoringSpanFilterTests.java index 3a3a14172..7814b8f8a 100644 --- a/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/exporter/SpanIgnoringSpanFilterTests.java +++ b/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/exporter/SpanIgnoringSpanFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/pom.xml b/spring-cloud-sleuth-autoconfigure/pom.xml index 68a1dac05..525554657 100644 --- a/spring-cloud-sleuth-autoconfigure/pom.xml +++ b/spring-cloud-sleuth-autoconfigure/pom.xml @@ -1,446 +1,478 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-autoconfigure - jar - Spring Cloud Sleuth AutoConfigure - Spring Cloud Sleuth AutoConfigure - - - org.springframework.cloud - spring-cloud-sleuth - 3.0.2-SNAPSHOT - .. - - - - - - org.springframework.cloud - spring-cloud-sleuth-instrumentation - - - org.springframework.boot - spring-boot-starter-web - true - - - io.micrometer - micrometer-core - true - - - io.projectreactor - reactor-core - true - - - org.reactivestreams - reactive-streams - true - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-actuator - true - - - org.springframework.integration - spring-integration-core - true - - - org.springframework.cloud - spring-cloud-function-context - true - - - org.springframework.boot - spring-boot-starter-websocket - true - - - org.springframework.cloud - spring-cloud-stream - true - - - org.springframework.cloud - spring-cloud-commons - - - org.springframework - spring-context - - - org.springframework.cloud - spring-cloud-context - true - - - io.reactivex - rxjava - true - - - io.github.openfeign - feign-okhttp - true - - - org.springframework.cloud - spring-cloud-starter-openfeign - true - - - org.springframework.cloud - spring-cloud-starter-loadbalancer - true - - - org.springframework.cloud - spring-cloud-starter-gateway - true - - - org.aspectj - aspectjrt - - - - org.springframework.boot - spring-boot-starter-quartz - true - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - org.springframework.security.oauth - spring-security-oauth2 - true - - - org.springframework.security.oauth.boot - spring-security-oauth2-autoconfigure - true - - - - - org.springframework.cloud - spring-cloud-sleuth-brave - true - - - io.zipkin.brave - brave - - - io.zipkin.reporter2 - * - - - io.zipkin.zipkin2 - * - - - true - - - io.zipkin.brave - brave-context-slf4j - true - - - io.zipkin.brave - brave-instrumentation-messaging - true - - - io.zipkin.brave - brave-instrumentation-rpc - true - - - io.zipkin.brave - brave-instrumentation-spring-rabbit - true - - - io.zipkin.brave - brave-instrumentation-kafka-clients - true - - - io.zipkin.brave - brave-instrumentation-kafka-streams - true - - - io.zipkin.brave - brave-instrumentation-httpclient - true - - - io.zipkin.brave - brave-instrumentation-httpasyncclient - true - - - io.zipkin.brave - brave-instrumentation-jms - true - - - io.zipkin.brave - brave-instrumentation-mongodb - true - - - io.zipkin.aws - brave-propagation-aws - true - - - javax.jms - javax.jms-api - true - - - io.opentracing.brave - brave-opentracing - true - - - org.apache.httpcomponents - httpasyncclient - true - - - org.springframework - spring-jms - true - - - - io.github.lognet - grpc-spring-boot-starter - true - - - org.springframework.boot - spring-boot-starter - - - - - io.zipkin.brave - brave-instrumentation-grpc - true - - - io.zipkin.reporter2 - zipkin-reporter-metrics-micrometer - - - io.micrometer - micrometer-core - - - true - - - - io.lettuce - lettuce-core - true - - - org.springframework.kafka - spring-kafka - true - - - org.apache.kafka - kafka-streams - true - - - org.springframework.amqp - spring-rabbit - true - - - org.springframework.boot - spring-boot-starter-data-mongodb - true - - - - - org.springframework.cloud - spring-cloud-sleuth-zipkin - true - - - io.zipkin.zipkin2 - zipkin - true - - - io.zipkin.reporter2 - zipkin-reporter - true - - - io.zipkin.reporter2 - zipkin-reporter-brave - true - - - io.zipkin.reporter2 - zipkin-sender-kafka - true - - - - org.apache.kafka - kafka-clients - - - - - io.zipkin.reporter2 - zipkin-sender-activemq-client - true - - - org.apache.activemq - activemq-client - - - - - org.apache.activemq - activemq-client - true - - - io.zipkin.reporter2 - zipkin-sender-amqp-client - true - - - - com.rabbitmq - amqp-client - - - - - - - com.wavefront - wavefront-runtime-sdk-jvm - true - - - com.wavefront - wavefront-sdk-java - true - - - io.micrometer - micrometer-registry-wavefront - true - - - - - org.springframework.boot - spring-boot-starter-test - test - - - org.awaitility - awaitility - test - - - - - io.zipkin.brave - brave-instrumentation-http-tests - test - - - com.squareup.okhttp3 - mockwebserver - test - - - - - com.squareup.okhttp3 - okhttp - - 4.8.0 - test - - - com.tngtech.archunit - archunit-junit5 - test - - - - - - - fast - - false - - - - - maven-surefire-plugin - - 4 - true - -Xmx1024m -XX:MaxPermSize=256m - - - - - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-autoconfigure + jar + Spring Cloud Sleuth AutoConfigure + Spring Cloud Sleuth AutoConfigure + + + org.springframework.cloud + spring-cloud-sleuth + 3.1.0-SNAPSHOT + .. + + + + + + org.springframework.cloud + spring-cloud-sleuth-instrumentation + + + org.springframework.boot + spring-boot-starter-web + true + + + io.micrometer + micrometer-core + true + + + io.projectreactor + reactor-core + true + + + org.reactivestreams + reactive-streams + true + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework.boot + spring-boot-starter-actuator + true + + + org.springframework.integration + spring-integration-core + true + + + org.springframework.cloud + spring-cloud-config-server + true + + + org.springframework.cloud + spring-cloud-starter-config + true + + + org.springframework.cloud + spring-cloud-function-context + true + + + org.springframework.boot + spring-boot-starter-websocket + true + + + org.springframework.cloud + spring-cloud-stream + + ${spring-cloud-stream.version} + true + + + org.springframework.cloud + spring-cloud-commons + + + org.springframework + spring-context + + + org.springframework.cloud + spring-cloud-context + true + + + org.springframework.cloud + spring-cloud-starter-task + true + + + org.springframework.cloud + spring-cloud-deployer-spi + true + + + io.reactivex + rxjava + true + + + io.github.openfeign + feign-okhttp + true + + + org.springframework.cloud + spring-cloud-starter-openfeign + true + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + true + + + org.springframework.cloud + spring-cloud-starter-gateway + true + + + org.aspectj + aspectjrt + + + + org.springframework.boot + spring-boot-starter-quartz + true + + + org.springframework.boot + spring-boot-autoconfigure-processor + true + + + org.springframework.security.oauth + spring-security-oauth2 + true + + + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure + true + + + + + org.springframework.cloud + spring-cloud-sleuth-brave + true + + + io.zipkin.brave + brave + + + io.zipkin.reporter2 + * + + + io.zipkin.zipkin2 + * + + + true + + + io.zipkin.brave + brave-context-slf4j + true + + + io.zipkin.brave + brave-instrumentation-messaging + true + + + io.zipkin.brave + brave-instrumentation-rpc + true + + + io.zipkin.brave + brave-instrumentation-spring-rabbit + true + + + io.zipkin.brave + brave-instrumentation-kafka-clients + true + + + io.zipkin.brave + brave-instrumentation-kafka-streams + true + + + io.zipkin.brave + brave-instrumentation-httpclient + true + + + io.zipkin.brave + brave-instrumentation-httpasyncclient + true + + + io.zipkin.brave + brave-instrumentation-jms + true + + + io.zipkin.brave + brave-instrumentation-mongodb + true + + + io.zipkin.aws + brave-propagation-aws + true + + + javax.jms + javax.jms-api + true + + + io.opentracing.brave + brave-opentracing + true + + + org.apache.httpcomponents + httpasyncclient + true + + + org.springframework + spring-jms + true + + + + io.github.lognet + grpc-spring-boot-starter + true + + + org.springframework.boot + spring-boot-starter + + + + + io.zipkin.brave + brave-instrumentation-grpc + true + + + io.zipkin.reporter2 + zipkin-reporter-metrics-micrometer + + + io.micrometer + micrometer-core + + + true + + + + io.lettuce + lettuce-core + true + + + org.springframework.kafka + spring-kafka + true + + + org.apache.kafka + kafka-streams + true + + + org.springframework.amqp + spring-rabbit + true + + + org.springframework.boot + spring-boot-starter-data-mongodb + true + + + org.springframework.boot + spring-boot-starter-rsocket + true + + + + + org.springframework.cloud + spring-cloud-sleuth-zipkin + true + + + io.zipkin.zipkin2 + zipkin + true + + + io.zipkin.reporter2 + zipkin-reporter + true + + + io.zipkin.reporter2 + zipkin-reporter-brave + true + + + io.zipkin.reporter2 + zipkin-sender-kafka + true + + + + org.apache.kafka + kafka-clients + + + + + io.zipkin.reporter2 + zipkin-sender-activemq-client + true + + + org.apache.activemq + activemq-client + + + + + org.apache.activemq + activemq-client + true + + + io.zipkin.reporter2 + zipkin-sender-amqp-client + true + + + + com.rabbitmq + amqp-client + + + + + + + com.wavefront + wavefront-runtime-sdk-jvm + true + + + com.wavefront + wavefront-sdk-java + true + + + io.micrometer + micrometer-registry-wavefront + true + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.awaitility + awaitility + test + + + org.mongodb + mongodb-driver-reactivestreams + test + + + + + io.zipkin.brave + brave-instrumentation-http-tests + test + + + com.squareup.okhttp3 + mockwebserver + test + + + + + com.squareup.okhttp3 + okhttp + + 4.8.0 + test + + + com.tngtech.archunit + archunit-junit5 + test + + + + + + + fast + + false + + + + + maven-surefire-plugin + + 4 + true + -Xmx1024m -XX:MaxPermSize=256m + + + + + + + + diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthAnnotationConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthAnnotationConfiguration.java index 1d5062634..6782c9d15 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthAnnotationConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthAnnotationConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthBaggageProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthBaggageProperties.java index da35ebf8b..9f629e987 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthBaggageProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthBaggageProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthOpentracingProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthOpentracingProperties.java index b697c706e..db087d4eb 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthOpentracingProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthOpentracingProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthSpanFilterProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthSpanFilterProperties.java index 5c53b92c5..03332866b 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthSpanFilterProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthSpanFilterProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthTracerProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthTracerProperties.java index 1c0ff46e5..e06e55c06 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthTracerProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthTracerProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceConfiguration.java index a55d2c28a..9d286d8fb 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java index 56d3879ba..bbcb203fc 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfiguration.java index 7b27b25d6..123f337b3 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveBaggageConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveBaggageConfiguration.java index ced1f1a6c..e307d2b3d 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveBaggageConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveBaggageConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveBridgeConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveBridgeConfiguration.java index 44005ed02..cefcd9574 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveBridgeConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveBridgeConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveSamplerConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveSamplerConfiguration.java index 1369a02e2..0bf5498a2 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveSamplerConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveSamplerConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/ConditionalOnBraveEnabled.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/ConditionalOnBraveEnabled.java index a74ed8636..2436b62d7 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/ConditionalOnBraveEnabled.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/ConditionalOnBraveEnabled.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SamplerCondition.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SamplerCondition.java index 3f5284399..850854f71 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SamplerCondition.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SamplerCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SamplerProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SamplerProperties.java index ca0968ecf..7fbafc457 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SamplerProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SamplerProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SleuthPropagationProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SleuthPropagationProperties.java index e2ecffea0..af02e84de 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SleuthPropagationProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SleuthPropagationProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SleuthProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SleuthProperties.java index 39dc6aaa9..92e635faa 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SleuthProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SleuthProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/grpc/BraveGrpcAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/grpc/BraveGrpcAutoConfiguration.java index d671441b9..b14dce503 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/grpc/BraveGrpcAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/grpc/BraveGrpcAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveKafkaStreamsAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveKafkaStreamsAutoConfiguration.java index 4e5068bb7..80995e822 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveKafkaStreamsAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveKafkaStreamsAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveMessagingAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveMessagingAutoConfiguration.java index 0da77fc78..191d1350c 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveMessagingAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveMessagingAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -132,7 +132,7 @@ public class BraveMessagingAutoConfiguration { } @Bean - KafkaFactoryBeanPostProcessor kafkaFactoryBeanPostProcessor(BeanFactory beanFactory) { + static KafkaFactoryBeanPostProcessor kafkaFactoryBeanPostProcessor(BeanFactory beanFactory) { return new KafkaFactoryBeanPostProcessor(beanFactory); } @@ -171,7 +171,7 @@ public class BraveMessagingAutoConfiguration { // Setup the tracing endpoint registry. @Bean - TracingJmsBeanPostProcessor tracingJmsBeanPostProcessor(BeanFactory beanFactory) { + static TracingJmsBeanPostProcessor tracingJmsBeanPostProcessor(BeanFactory beanFactory) { return new TracingJmsBeanPostProcessor(beanFactory); } diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfiguration.java index bb119746a..0f9d424b8 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -25,6 +25,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; import org.springframework.boot.autoconfigure.mongo.MongoClientSettingsBuilderCustomizer; @@ -41,6 +42,7 @@ import org.springframework.context.annotation.Configuration; * @since 3.0.0 */ @Configuration(proxyBeanMethods = false) +@ConditionalOnMissingClass("com.mongodb.reactivestreams.client.MongoClient") @ConditionalOnBean(Tracing.class) @AutoConfigureAfter(BraveAutoConfiguration.class) @AutoConfigureBefore(MongoAutoConfiguration.class) diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/opentracing/BraveOpentracingAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/opentracing/BraveOpentracingAutoConfiguration.java index 6e8048e0b..717469501 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/opentracing/BraveOpentracingAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/opentracing/BraveOpentracingAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/redis/BraveRedisAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/redis/BraveRedisAutoConfiguration.java index a88eae66d..22cbb4049 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/redis/BraveRedisAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/redis/BraveRedisAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/redis/TraceRedisProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/redis/TraceRedisProperties.java index 3350917e8..16fa29c1f 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/redis/TraceRedisProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/redis/TraceRedisProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/rpc/BraveRpcAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/rpc/BraveRpcAutoConfiguration.java index 2bb708d81..25d54ca60 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/rpc/BraveRpcAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/rpc/BraveRpcAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpBridgeConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpBridgeConfiguration.java index 4fedd8f34..566ceb97c 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpBridgeConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpBridgeConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpConfiguration.java index 6e355fe7a..5732b79b2 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -21,12 +21,15 @@ import java.util.regex.Pattern; import javax.validation.constraints.NotNull; +import brave.Tracer; import brave.Tracing; import brave.http.HttpRequest; import brave.http.HttpTracing; import brave.http.HttpTracingCustomizer; +import brave.propagation.CurrentTraceContext; import brave.sampler.SamplerFunction; import brave.sampler.SamplerFunctions; +import reactor.util.context.Context; import org.springframework.beans.factory.BeanFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -38,6 +41,7 @@ import org.springframework.cloud.sleuth.autoconfig.instrument.web.SleuthWebPrope import org.springframework.cloud.sleuth.brave.bridge.BraveHttpRequestParser; import org.springframework.cloud.sleuth.brave.bridge.BraveHttpResponseParser; import org.springframework.cloud.sleuth.brave.bridge.BraveSamplerFunction; +import org.springframework.cloud.sleuth.brave.instrument.web.BraveSpanFromContextRetriever; import org.springframework.cloud.sleuth.brave.instrument.web.CompositeHttpSampler; import org.springframework.cloud.sleuth.brave.instrument.web.SkipPatternHttpClientSampler; import org.springframework.cloud.sleuth.brave.instrument.web.SkipPatternHttpServerSampler; @@ -50,6 +54,7 @@ import org.springframework.cloud.sleuth.instrument.web.HttpServerRequestParser; import org.springframework.cloud.sleuth.instrument.web.HttpServerResponseParser; import org.springframework.cloud.sleuth.instrument.web.HttpServerSampler; import org.springframework.cloud.sleuth.instrument.web.SkipPatternProvider; +import org.springframework.cloud.sleuth.instrument.web.SpanFromContextRetriever; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -205,4 +210,15 @@ public class BraveHttpConfiguration { return new SkipPatternHttpClientSampler(Pattern.compile(skipPattern)); } + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(Context.class) + static class BraveWebFilterConfiguration { + + @Bean + SpanFromContextRetriever braveSpanFromContextRetriever(CurrentTraceContext currentTraceContext, Tracer tracer) { + return new BraveSpanFromContextRetriever(currentTraceContext, tracer); + } + + } + } diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/client/BraveWebClientAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/client/BraveWebClientAutoConfiguration.java index ee98c220e..49f5b35fd 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/client/BraveWebClientAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/client/BraveWebClientAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/ExecutorBeanPostProcessor.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/ExecutorBeanPostProcessor.java index d15f15679..ee90fcd47 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/ExecutorBeanPostProcessor.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/ExecutorBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/SleuthAsyncProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/SleuthAsyncProperties.java index 2aac2a055..b86ec4328 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/SleuthAsyncProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/SleuthAsyncProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncAutoConfiguration.java index 4605e0c53..ae57cea49 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncCustomAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncCustomAutoConfiguration.java index 4ac599fd4..dcf398ac2 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncCustomAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncCustomAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncDefaultAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncDefaultAutoConfiguration.java index ae9ecffd2..0fa6d75f0 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncDefaultAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncDefaultAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/circuitbreaker/SleuthCircuitBreakerProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/circuitbreaker/SleuthCircuitBreakerProperties.java index f18e802d4..52055d5c5 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/circuitbreaker/SleuthCircuitBreakerProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/circuitbreaker/SleuthCircuitBreakerProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/circuitbreaker/TraceCircuitBreakerAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/circuitbreaker/TraceCircuitBreakerAutoConfiguration.java index 7684a9b50..f724943c5 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/circuitbreaker/TraceCircuitBreakerAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/circuitbreaker/TraceCircuitBreakerAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -21,10 +21,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.circuitbreaker.CircuitBreaker; +import org.springframework.cloud.sleuth.CurrentTraceContext; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration; import org.springframework.cloud.sleuth.instrument.circuitbreaker.TraceCircuitBreakerFactoryAspect; +import org.springframework.cloud.sleuth.instrument.circuitbreaker.TraceReactiveCircuitBreakerFactoryAspect; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -36,7 +37,6 @@ import org.springframework.context.annotation.Configuration; * @since 2.2.1 */ @Configuration(proxyBeanMethods = false) -@ConditionalOnClass(CircuitBreaker.class) @ConditionalOnBean(Tracer.class) @ConditionalOnProperty(value = "spring.sleuth.circuitbreaker.enabled", matchIfMissing = true) @EnableConfigurationProperties(SleuthCircuitBreakerProperties.class) @@ -44,8 +44,17 @@ import org.springframework.context.annotation.Configuration; public class TraceCircuitBreakerAutoConfiguration { @Bean + @ConditionalOnClass(name = "org.springframework.cloud.client.circuitbreaker.CircuitBreaker") TraceCircuitBreakerFactoryAspect traceCircuitBreakerFactoryAspect(Tracer tracer) { return new TraceCircuitBreakerFactoryAspect(tracer); } + @Bean + @ConditionalOnClass(name = { "reactor.core.publisher.Mono", + "org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker" }) + TraceReactiveCircuitBreakerFactoryAspect traceReactiveCircuitBreakerFactoryAspect(Tracer tracer, + CurrentTraceContext currentTraceContext) { + return new TraceReactiveCircuitBreakerFactoryAspect(tracer, currentTraceContext); + } + } diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/config/TraceSpringCloudConfigAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/config/TraceSpringCloudConfigAutoConfiguration.java new file mode 100644 index 000000000..1276618a1 --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/config/TraceSpringCloudConfigAutoConfiguration.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.config; + +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.config.server.config.ConfigServerConfiguration; +import org.springframework.cloud.config.server.config.ConfigServerProperties; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration; +import org.springframework.cloud.sleuth.instrument.config.TraceEnvironmentRepositoryAspect; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration + * Auto-configuration} that registers instrumentation for Spring Cloud Config Server and + * Client. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnBean({ Tracer.class, ConfigServerProperties.class }) +@ConditionalOnClass(ConfigServerConfiguration.class) +@ConditionalOnProperty(value = "spring.sleuth.config.server.enabled", matchIfMissing = true) +@AutoConfigureAfter(BraveAutoConfiguration.class) +public class TraceSpringCloudConfigAutoConfiguration { + + @Bean + TraceEnvironmentRepositoryAspect traceEnvironmentRepositoryAspect(Tracer tracer) { + return new TraceEnvironmentRepositoryAspect(tracer); + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/deployer/TraceDeployerAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/deployer/TraceDeployerAutoConfiguration.java new file mode 100644 index 000000000..45b7b577c --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/deployer/TraceDeployerAutoConfiguration.java @@ -0,0 +1,52 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.deployer; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.deployer.spi.app.AppDeployer; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration; +import org.springframework.cloud.sleuth.instrument.deployer.TraceAppDeployerBeanPostProcessor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; + +/** + * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration + * Auto-configuration} that registers instrumentation for app deployers. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnBean(Tracer.class) +@ConditionalOnProperty(value = "spring.sleuth.deployer.enabled", matchIfMissing = true) +@ConditionalOnClass(AppDeployer.class) +@AutoConfigureAfter(BraveAutoConfiguration.class) +public class TraceDeployerAutoConfiguration { + + @Bean + static TraceAppDeployerBeanPostProcessor traceAppDeployerBeanPostProcessor(BeanFactory beanFactory, + Environment environment) { + return new TraceAppDeployerBeanPostProcessor(beanFactory, environment); + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/SleuthIntegrationMessagingProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/SleuthIntegrationMessagingProperties.java index 86d5a7477..1b16803cc 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/SleuthIntegrationMessagingProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/SleuthIntegrationMessagingProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/SleuthMessagingProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/SleuthMessagingProperties.java index fca89b281..3175d87ee 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/SleuthMessagingProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/SleuthMessagingProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -17,6 +17,7 @@ package org.springframework.cloud.sleuth.autoconfig.instrument.messaging; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.messaging.handler.annotation.MessageMapping; /** * Properties for messaging. @@ -32,6 +33,11 @@ public class SleuthMessagingProperties { */ private boolean enabled; + /** + * Aspect related properties. + */ + private Aspect aspect = new Aspect(); + /** * Rabbit related properties. */ @@ -55,6 +61,14 @@ public class SleuthMessagingProperties { this.enabled = enabled; } + public Aspect getAspect() { + return this.aspect; + } + + public void setAspect(Aspect aspect) { + this.aspect = aspect; + } + public Rabbit getRabbit() { return this.rabbit; } @@ -79,6 +93,26 @@ public class SleuthMessagingProperties { this.jms = jms; } + /** + * Aspect configuration. + */ + public static class Aspect { + + /** + * Should {@link MessageMapping} wrapping be enabled. + */ + private boolean enabled; + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + } + /** * RabbitMQ configuration. */ diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceFunctionAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceFunctionAutoConfiguration.java index 1b9b03342..f0ec48468 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceFunctionAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceFunctionAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringIntegrationAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringIntegrationAutoConfiguration.java index ff2f75d8d..2758e00fa 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringIntegrationAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringIntegrationAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringMessagingAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringMessagingAutoConfiguration.java index 084e6ccf1..a143bdb75 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringMessagingAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringMessagingAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -16,12 +16,16 @@ package org.springframework.cloud.sleuth.autoconfig.instrument.messaging; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.sleuth.SpanNamer; +import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.instrument.messaging.MessageHeaderPropagatorGetter; import org.springframework.cloud.sleuth.instrument.messaging.MessageHeaderPropagatorSetter; +import org.springframework.cloud.sleuth.instrument.messaging.TraceMessagingAspect; import org.springframework.cloud.sleuth.propagation.Propagator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -29,10 +33,17 @@ import org.springframework.messaging.support.MessageHeaderAccessor; @Configuration(proxyBeanMethods = false) @ConditionalOnClass(MessageHeaderAccessor.class) +@ConditionalOnBean(Tracer.class) @ConditionalOnProperty(value = "spring.sleuth.messaging.enabled", matchIfMissing = true) @EnableConfigurationProperties({ SleuthIntegrationMessagingProperties.class, SleuthMessagingProperties.class }) class TraceSpringMessagingAutoConfiguration { + @Bean + @ConditionalOnProperty(value = "spring.sleuth.messaging.aspect.enabled", matchIfMissing = true) + TraceMessagingAspect traceMessagingAspect(Tracer tracer, SpanNamer spanNamer) { + return new TraceMessagingAspect(tracer, spanNamer); + } + @Bean @ConditionalOnMissingBean Propagator.Setter traceMessagePropagationSetter() { diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceWebSocketAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceWebSocketAutoConfiguration.java index 313e3d9d9..694c75400 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceWebSocketAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceWebSocketAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/quartz/TraceQuartzAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/quartz/TraceQuartzAutoConfiguration.java index 24c3e9f4e..b13262208 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/quartz/TraceQuartzAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/quartz/TraceQuartzAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/SleuthReactorProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/SleuthReactorProperties.java index 0c22d1eaf..bb1810243 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/SleuthReactorProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/SleuthReactorProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -20,6 +20,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; /** * Sleuth Reactor settings. @@ -58,6 +59,8 @@ public class SleuthReactorProperties { this.enabled = enabled; } + @DeprecatedConfigurationProperty(reason = "An enum is a more clear solution", + replacement = "spring.sleuth.reactor.instrumentation-type=DECORATE_ON_EACH") @Deprecated public boolean isDecorateOnEach() { warn(); @@ -86,6 +89,13 @@ public class SleuthReactorProperties { public enum InstrumentationType { + /** + * Uses the new decorate queues feature from Project Reactor. Should allow the + * feature set of {@link InstrumentationType#DECORATE_ON_EACH} with the least + * impact on the performance. + */ + DECORATE_QUEUES, + /** * Decorates on each operator, will be less performing, but logging will always * contain the tracing entries in each operator. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/TraceReactorAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/TraceReactorAutoConfiguration.java index e81b12d70..a4bc41fa7 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/TraceReactorAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/TraceReactorAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -18,8 +18,13 @@ package org.springframework.cloud.sleuth.autoconfig.instrument.reactor; import java.io.Closeable; import java.io.IOException; +import java.util.AbstractQueue; +import java.util.Iterator; +import java.util.Queue; import java.util.function.Function; +import brave.propagation.CurrentTraceContext; +import brave.propagation.TraceContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.reactivestreams.Publisher; @@ -47,6 +52,7 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.util.ReflectionUtils; import static org.springframework.cloud.sleuth.autoconfig.instrument.reactor.TraceReactorAutoConfiguration.SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY; import static org.springframework.cloud.sleuth.autoconfig.instrument.reactor.TraceReactorAutoConfiguration.TraceReactorConfiguration.SLEUTH_TRACE_REACTOR_KEY; @@ -78,6 +84,8 @@ public class TraceReactorAutoConfiguration { private static final Log log = LogFactory.getLog(TraceReactorConfiguration.class); + static final boolean IS_QUEUE_WRAPPER_ON_THE_CLASSPATH = isQueueWrapperOnTheClasspath(); + @Autowired ConfigurableApplicationContext springContext; @@ -91,6 +99,10 @@ public class TraceReactorAutoConfiguration { return new HookRegisteringBeanDefinitionRegistryPostProcessor(context); } + private static boolean isQueueWrapperOnTheClasspath() { + return ReflectionUtils.findMethod(Hooks.class, "addQueueWrapper", String.class, Function.class) != null; + } + @Configuration(proxyBeanMethods = false) @ConditionalOnClass(RefreshScope.class) static class HooksRefresherConfiguration { @@ -127,8 +139,19 @@ class HooksRefresher implements ApplicationListener } Hooks.resetOnEachOperator(SLEUTH_TRACE_REACTOR_KEY); Hooks.resetOnLastOperator(SLEUTH_TRACE_REACTOR_KEY); - Hooks.resetOnLastOperator(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY); + Hooks.removeQueueWrapper(SLEUTH_TRACE_REACTOR_KEY); + Schedulers.resetOnScheduleHook(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY); switch (this.reactorProperties.getInstrumentationType()) { + case DECORATE_QUEUES: + if (TraceReactorAutoConfiguration.TraceReactorConfiguration.IS_QUEUE_WRAPPER_ON_THE_CLASSPATH) { + if (log.isTraceEnabled()) { + log.trace("Adding queue wrapper instrumentation"); + } + HookRegisteringBeanDefinitionRegistryPostProcessor.addQueueWrapper(context); + Hooks.onLastOperator(SLEUTH_TRACE_REACTOR_KEY, ReactorSleuth.scopePassingSpanOperator(this.context)); + Schedulers.onScheduleHook(TraceReactorAutoConfiguration.SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY, + ReactorSleuth.scopePassingOnScheduleHook(this.context)); + } case DECORATE_ON_EACH: if (log.isTraceEnabled()) { log.trace("Decorating onEach operator instrumentation"); @@ -178,26 +201,45 @@ class HookRegisteringBeanDefinitionRegistryPostProcessor implements BeanDefiniti SleuthReactorProperties.InstrumentationType property = environment.getProperty( "spring.sleuth.reactor.instrumentation-type", SleuthReactorProperties.InstrumentationType.class, SleuthReactorProperties.InstrumentationType.DECORATE_ON_EACH); - Boolean decorateOnEach = environment.getProperty("spring.sleuth.reactor.decorate-on-each", Boolean.class, true); - if (!decorateOnEach) { + if (wrapperNotOnClasspathHooksPropertyTurnedOn(property)) { log.warn( - "You're using the deprecated [spring.sleuth.reactor.decorate-on-each] property. Please use the [spring.sleuth.reactor.instrumentation-type] one instead."); - decorateOnLast(ReactorSleuth.scopePassingSpanOperator(springContext)); + "You have explicitly set the decorate hooks option but you're using an old version of Reactor. Please upgrade to the latest Boot version (at least 2.4.3). Will fall back to the previous reactor instrumentation mode"); + property = SleuthReactorProperties.InstrumentationType.DECORATE_ON_EACH; } - else if (property == SleuthReactorProperties.InstrumentationType.DECORATE_ON_EACH) { - decorateOnEach(springContext); - decorateOnLast(onLastOperatorForOnEachInstrumentation(springContext)); - decorateScheduler(springContext); - } - else if (property == SleuthReactorProperties.InstrumentationType.DECORATE_ON_LAST) { + if (property == SleuthReactorProperties.InstrumentationType.DECORATE_QUEUES) { + addQueueWrapper(springContext); decorateOnLast(ReactorSleuth.scopePassingSpanOperator(springContext)); decorateScheduler(springContext); } - else if (property == SleuthReactorProperties.InstrumentationType.MANUAL) { - decorateOnLast(ReactorSleuth.springContextSpanOperator(springContext)); + else { + Boolean decorateOnEach = environment.getProperty("spring.sleuth.reactor.decorate-on-each", Boolean.class, + true); + if (!decorateOnEach) { + log.warn( + "You're using the deprecated [spring.sleuth.reactor.decorate-on-each] property. Please use the [spring.sleuth.reactor.instrumentation-type] one instead."); + decorateOnLast(ReactorSleuth.scopePassingSpanOperator(springContext)); + } + else if (property == SleuthReactorProperties.InstrumentationType.DECORATE_ON_EACH) { + decorateOnEach(springContext); + decorateOnLast(onLastOperatorForOnEachInstrumentation(springContext)); + decorateScheduler(springContext); + } + else if (property == SleuthReactorProperties.InstrumentationType.DECORATE_ON_LAST) { + decorateOnLast(ReactorSleuth.scopePassingSpanOperator(springContext)); + decorateScheduler(springContext); + } + else if (property == SleuthReactorProperties.InstrumentationType.MANUAL) { + decorateOnLast(ReactorSleuth.springContextSpanOperator(springContext)); + } } } + private static boolean wrapperNotOnClasspathHooksPropertyTurnedOn( + SleuthReactorProperties.InstrumentationType property) { + return property == SleuthReactorProperties.InstrumentationType.DECORATE_QUEUES + && !TraceReactorAutoConfiguration.TraceReactorConfiguration.IS_QUEUE_WRAPPER_ON_THE_CLASSPATH; + } + private static void decorateScheduler(ConfigurableApplicationContext springContext) { Schedulers.onScheduleHook(TraceReactorAutoConfiguration.SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY, ReactorSleuth.scopePassingOnScheduleHook(springContext)); @@ -218,6 +260,13 @@ class HookRegisteringBeanDefinitionRegistryPostProcessor implements BeanDefiniti ReactorSleuth.onEachOperatorForOnEachInstrumentation(springContext)); } + static void addQueueWrapper(ConfigurableApplicationContext springContext) { + if (log.isTraceEnabled()) { + log.trace("Decorating queues"); + } + Hooks.addQueueWrapper(SLEUTH_TRACE_REACTOR_KEY, queue -> traceQueue(springContext, queue)); + } + @Override public void close() throws IOException { if (log.isTraceEnabled()) { @@ -225,7 +274,97 @@ class HookRegisteringBeanDefinitionRegistryPostProcessor implements BeanDefiniti } Hooks.resetOnEachOperator(SLEUTH_TRACE_REACTOR_KEY); Hooks.resetOnLastOperator(SLEUTH_TRACE_REACTOR_KEY); + Hooks.removeQueueWrapper(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY); Schedulers.resetOnScheduleHook(TraceReactorAutoConfiguration.SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY); } + private static Queue traceQueue(ConfigurableApplicationContext springContext, Queue queue) { + if (!springContext.isActive()) { + return queue; + } + CurrentTraceContext currentTraceContext = springContext.getBean(CurrentTraceContext.class); + @SuppressWarnings("unchecked") + Queue envelopeQueue = queue; + return new AbstractQueue() { + + @Override + public int size() { + return envelopeQueue.size(); + } + + @Override + public boolean offer(Object o) { + TraceContext traceContext = currentTraceContext.get(); + return envelopeQueue.offer(new Envelope(o, traceContext)); + } + + @Override + public Object poll() { + Object object = envelopeQueue.poll(); + if (object == null) { + return null; + } + else if (object instanceof Envelope) { + Envelope envelope = (Envelope) object; + restoreTheContext(envelope); + return envelope.body; + } + return object; + } + + private void restoreTheContext(Envelope envelope) { + if (envelope.traceContext != null) { + currentTraceContext.maybeScope(envelope.traceContext); + } + } + + @Override + public Object peek() { + Object peek = queue.peek(); + if (peek instanceof Envelope) { + Envelope envelope = (Envelope) peek; + restoreTheContext(envelope); + return (envelope).body; + } + return peek; + } + + @Override + @SuppressWarnings("unchecked") + public Iterator iterator() { + Iterator iterator = queue.iterator(); + return new Iterator() { + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public Object next() { + Object next = iterator.next(); + if (next instanceof Envelope) { + Envelope envelope = (Envelope) next; + restoreTheContext(envelope); + return (envelope).body; + } + return next; + } + }; + } + }; + } + + static class Envelope { + + final Object body; + + final TraceContext traceContext; + + Envelope(Object body, TraceContext traceContext) { + this.body = body; + this.traceContext = traceContext; + } + + } + } diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/TraceReactorAutoConfigurationAccessorConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/TraceReactorAutoConfigurationAccessorConfiguration.java index eea405a1a..1e37d95af 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/TraceReactorAutoConfigurationAccessorConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/TraceReactorAutoConfigurationAccessorConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -16,16 +16,13 @@ package org.springframework.cloud.sleuth.autoconfig.instrument.reactor; +import java.io.IOException; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Hooks; -import reactor.core.scheduler.Schedulers; import org.springframework.context.ConfigurableApplicationContext; -import static org.springframework.cloud.sleuth.autoconfig.instrument.reactor.TraceReactorAutoConfiguration.SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY; -import static org.springframework.cloud.sleuth.autoconfig.instrument.reactor.TraceReactorAutoConfiguration.TraceReactorConfiguration.SLEUTH_TRACE_REACTOR_KEY; - /** * @author Marcin Grzejszczak */ @@ -41,9 +38,12 @@ public final class TraceReactorAutoConfigurationAccessorConfiguration { if (log.isTraceEnabled()) { log.trace("Cleaning up hooks"); } - Hooks.resetOnEachOperator(SLEUTH_TRACE_REACTOR_KEY); - Hooks.resetOnLastOperator(SLEUTH_TRACE_REACTOR_KEY); - Schedulers.resetOnScheduleHook(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY); + try { + new HookRegisteringBeanDefinitionRegistryPostProcessor(null).close(); + } + catch (IOException e) { + throw new IllegalStateException(e); + } } public static void setup(ConfigurableApplicationContext context) { diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/redis/TraceLettuceClientResourcesBeanPostProcessor.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/redis/TraceLettuceClientResourcesBeanPostProcessor.java index d7feae1fa..26b31f472 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/redis/TraceLettuceClientResourcesBeanPostProcessor.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/redis/TraceLettuceClientResourcesBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rsocket/SleuthRSocketProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rsocket/SleuthRSocketProperties.java new file mode 100644 index 000000000..7dd0b0776 --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rsocket/SleuthRSocketProperties.java @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.rsocket; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Sleuth RSocket settings. + * + * @author Oleh Dokuka + * @since 3.1.0 + */ +@ConfigurationProperties("spring.sleuth.rsocket") +public class SleuthRSocketProperties { + + /** + * When true enables instrumentation for rsocket. + */ + private boolean enabled = true; + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rsocket/TraceRSocketAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rsocket/TraceRSocketAutoConfiguration.java new file mode 100644 index 000000000..584f76199 --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rsocket/TraceRSocketAutoConfiguration.java @@ -0,0 +1,89 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.rsocket; + +import java.util.List; + +import io.rsocket.RSocket; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration; +import org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.rsocket.server.RSocketServerCustomizer; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration; +import org.springframework.cloud.sleuth.brave.propagation.PropagationType; +import org.springframework.cloud.sleuth.instrument.rsocket.TracingRSocketConnectorConfigurer; +import org.springframework.cloud.sleuth.instrument.rsocket.TracingRSocketServerCustomizer; +import org.springframework.cloud.sleuth.propagation.Propagator; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; +import org.springframework.messaging.rsocket.RSocketConnectorConfigurer; +import org.springframework.messaging.rsocket.RSocketRequester; +import org.springframework.messaging.rsocket.RSocketRequester.Builder; +import org.springframework.messaging.rsocket.RSocketStrategies; + +@Configuration(proxyBeanMethods = false) +@ConditionalOnBean(Tracer.class) +@ConditionalOnProperty(value = "spring.sleuth.rsocket.enabled", matchIfMissing = true) +@ConditionalOnClass({ RSocket.class, RSocketStrategies.class }) +@AutoConfigureAfter(BraveAutoConfiguration.class) +@AutoConfigureBefore({ RSocketRequesterAutoConfiguration.class, RSocketServerAutoConfiguration.class }) +@EnableConfigurationProperties(SleuthRSocketProperties.class) +public class TraceRSocketAutoConfiguration { + + // We're using text instead of objects cause we can have same properties from Brave / + // OTel + @Bean + @Scope("prototype") + @ConditionalOnMissingBean + Builder rSocketRequesterBuilder(RSocketStrategies strategies, + ObjectProvider connectorConfigurerProvider) { + // TODO: should be in spring boot + final Builder builder = RSocketRequester.builder().rsocketStrategies(strategies); + connectorConfigurerProvider.forEach(builder::rsocketConnector); + return builder; + } + + private boolean containsZipkinPropagationType(List types) { + return types.contains(PropagationType.B3); + } + + @Bean + RSocketConnectorConfigurer tracingRSocketConnectorConfigurer(Propagator propagator, Tracer tracer, + @Value("${spring.sleuth.propagation.type:B3}") List types) { + return new TracingRSocketConnectorConfigurer(propagator, tracer, containsZipkinPropagationType(types)); + } + + // We're using text instead of objects cause we can have same properties from Brave / + // OTel + @Bean + RSocketServerCustomizer tracingRSocketServerCustomizer(Propagator propagator, Tracer tracer, + @Value("${spring.sleuth.propagation.type:B3}") List types) { + return new TracingRSocketServerCustomizer(propagator, tracer, containsZipkinPropagationType(types)); + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rxjava/SleuthRxJavaSchedulersProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rxjava/SleuthRxJavaSchedulersProperties.java index 04bfa9f0c..90d954d06 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rxjava/SleuthRxJavaSchedulersProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rxjava/SleuthRxJavaSchedulersProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rxjava/TraceRxJavaAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rxjava/TraceRxJavaAutoConfiguration.java index c3de23c9f..17b4e234b 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rxjava/TraceRxJavaAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rxjava/TraceRxJavaAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/scheduling/SleuthSchedulingProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/scheduling/SleuthSchedulingProperties.java index 194293575..4fa1e1379 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/scheduling/SleuthSchedulingProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/scheduling/SleuthSchedulingProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/scheduling/TraceSchedulingAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/scheduling/TraceSchedulingAutoConfiguration.java index 1cd5b7b33..fe16988a0 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/scheduling/TraceSchedulingAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/scheduling/TraceSchedulingAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceApplicationRunnerBeanPostProcessor.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceApplicationRunnerBeanPostProcessor.java new file mode 100644 index 000000000..5efd90f4c --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceApplicationRunnerBeanPostProcessor.java @@ -0,0 +1,47 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.task; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.boot.ApplicationRunner; +import org.springframework.cloud.sleuth.instrument.task.TraceApplicationRunner; + +/** + * Registers beans related to task scheduling. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class TraceApplicationRunnerBeanPostProcessor implements BeanPostProcessor { + + private final BeanFactory beanFactory; + + public TraceApplicationRunnerBeanPostProcessor(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof ApplicationRunner && !(bean instanceof TraceApplicationRunner)) { + return new TraceApplicationRunner(this.beanFactory, (ApplicationRunner) bean, beanName); + } + return bean; + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceCommandLineRunnerBeanPostProcessor.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceCommandLineRunnerBeanPostProcessor.java new file mode 100644 index 000000000..9fc69d7da --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceCommandLineRunnerBeanPostProcessor.java @@ -0,0 +1,47 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.task; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.boot.CommandLineRunner; +import org.springframework.cloud.sleuth.instrument.task.TraceCommandLineRunner; + +/** + * Registers beans related to task scheduling. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class TraceCommandLineRunnerBeanPostProcessor implements BeanPostProcessor { + + private final BeanFactory beanFactory; + + public TraceCommandLineRunnerBeanPostProcessor(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof CommandLineRunner && !(bean instanceof TraceCommandLineRunner)) { + return new TraceCommandLineRunner(this.beanFactory, (CommandLineRunner) bean, beanName); + } + return bean; + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceTaskAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceTaskAutoConfiguration.java new file mode 100644 index 000000000..591ca5941 --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceTaskAutoConfiguration.java @@ -0,0 +1,61 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.task; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration; +import org.springframework.cloud.sleuth.instrument.task.TraceTaskExecutionListener; +import org.springframework.cloud.task.listener.TaskExecutionListener; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Registers beans related to Spring Cloud Task scheduling. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(TaskExecutionListener.class) +@ConditionalOnProperty(value = "spring.sleuth.task.enabled", matchIfMissing = true) +@ConditionalOnBean(Tracer.class) +@AutoConfigureAfter(BraveAutoConfiguration.class) +public class TraceTaskAutoConfiguration { + + @Bean + TraceTaskExecutionListener traceTaskExecutionListener(Tracer tracer, + @Value("${spring.application.name:default}") String appName) { + return new TraceTaskExecutionListener(tracer, appName); + } + + @Bean + static TraceCommandLineRunnerBeanPostProcessor traceCommandLineRunnerBeanPostProcessor(BeanFactory beanFactory) { + return new TraceCommandLineRunnerBeanPostProcessor(beanFactory); + } + + @Bean + static TraceApplicationRunnerBeanPostProcessor traceApplicationRunnerBeanPostProcessor(BeanFactory beanFactory) { + return new TraceApplicationRunnerBeanPostProcessor(beanFactory); + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/ConditionalOnSleuthHttp.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/ConditionalOnSleuthHttp.java index 4bbc6d0bd..d61353f3d 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/ConditionalOnSleuthHttp.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/ConditionalOnSleuthHttp.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/ConditionalOnSleuthWeb.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/ConditionalOnSleuthWeb.java index a2ee82685..952a70345 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/ConditionalOnSleuthWeb.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/ConditionalOnSleuthWeb.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternConfiguration.java index 1600add7f..49dc59cf6 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -24,6 +24,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import org.springframework.beans.factory.BeanCurrentlyInCreationException; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; @@ -199,6 +200,7 @@ class SkipPatternConfiguration { @Bean @ConditionalOnManagementPort(ManagementPortType.SAME) + @ConditionalOnBean(WebEndpointProperties.class) SingleSkipPattern skipPatternForActuatorEndpointsSamePort(Environment environment, final ServerProperties serverProperties, final WebEndpointProperties webEndpointProperties, final EndpointsSupplier endpointsSupplier) { @@ -210,10 +212,16 @@ class SkipPatternConfiguration { @ConditionalOnManagementPort(ManagementPortType.DIFFERENT) @ConditionalOnProperty(name = "management.server.servlet.context-path", havingValue = "/", matchIfMissing = true) + @ConditionalOnBean(WebEndpointProperties.class) SingleSkipPattern skipPatternForActuatorEndpointsDifferentPort(Environment environment, - final ServerProperties serverProperties, final WebEndpointProperties webEndpointProperties, + final WebEndpointProperties webEndpointProperties, + ObjectProvider managementServerProperties, final EndpointsSupplier endpointsSupplier) { - return () -> getEndpointsPatterns(environment, null, webEndpointProperties, endpointsSupplier); + return () -> { + ManagementServerProperties props = managementServerProperties.getIfAvailable(); + return getEndpointsPatterns(environment, props != null ? props.getBasePath() : null, + webEndpointProperties, endpointsSupplier); + }; } } diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SleuthHttpProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SleuthHttpProperties.java index 8501644d6..ef91e63e9 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SleuthHttpProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SleuthHttpProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SleuthWebProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SleuthWebProperties.java index bcafd6b16..fe4d3fa80 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SleuthWebProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SleuthWebProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceHandlerFunctionAdapterBeanPostProcessor.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceHandlerFunctionAdapterBeanPostProcessor.java new file mode 100644 index 000000000..0953cd888 --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceHandlerFunctionAdapterBeanPostProcessor.java @@ -0,0 +1,42 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.web; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.cloud.sleuth.instrument.web.TraceHandlerAdapter; +import org.springframework.web.reactive.HandlerAdapter; +import org.springframework.web.reactive.function.server.support.HandlerFunctionAdapter; + +class TraceHandlerFunctionAdapterBeanPostProcessor implements BeanPostProcessor { + + private final BeanFactory beanFactory; + + TraceHandlerFunctionAdapterBeanPostProcessor(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof HandlerFunctionAdapter) { + return new TraceHandlerAdapter((HandlerAdapter) bean, this.beanFactory); + } + return bean; + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebAutoConfiguration.java index 0bbb5f248..63067d0bd 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebFluxConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebFluxConfiguration.java index 65a2fd9ec..c38d8275c 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebFluxConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebFluxConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -16,6 +16,7 @@ package org.springframework.cloud.sleuth.autoconfig.instrument.web; +import org.springframework.beans.factory.BeanFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.cloud.sleuth.CurrentTraceContext; @@ -45,4 +46,10 @@ class TraceWebFluxConfiguration { return traceWebFilter; } + @Bean + static TraceHandlerFunctionAdapterBeanPostProcessor traceHandlerFunctionAdapterBeanPostProcessor( + BeanFactory beanFactory) { + return new TraceHandlerFunctionAdapterBeanPostProcessor(beanFactory); + } + } diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebMvcConfigurer.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebMvcConfigurer.java index cda9c2af2..b6d7952d1 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebMvcConfigurer.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebMvcConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebServletConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebServletConfiguration.java index e24c81141..1c0e73d5f 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebServletConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebServletConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -28,7 +28,6 @@ import javax.servlet.ServletResponse; import org.springframework.beans.factory.BeanFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.web.servlet.FilterRegistrationBean; @@ -79,12 +78,6 @@ class TraceWebServletConfiguration { return filterRegistrationBean; } - @Bean - @ConditionalOnMissingBean - TracingFilter tracingFilter(CurrentTraceContext currentTraceContext, HttpServerHandler httpServerHandler) { - return TracingFilter.create(currentTraceContext, httpServerHandler); - } - /** * Nested config that configures Web MVC if it's present (without adding a runtime * dependency to it). @@ -128,7 +121,8 @@ final class LazyTracingFilter implements Filter { private Filter tracingFilter() { if (this.tracingFilter == null) { - this.tracingFilter = this.beanFactory.getBean(TracingFilter.class); + this.tracingFilter = TracingFilter.create(this.beanFactory.getBean(CurrentTraceContext.class), + this.beanFactory.getBean(HttpServerHandler.class)); } return this.tracingFilter; } diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/ConditionalnOnSleuthWebClient.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/ConditionalnOnSleuthWebClient.java index b87e09ef4..3e4920bd1 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/ConditionalnOnSleuthWebClient.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/ConditionalnOnSleuthWebClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceGatewayEnvironmentPostProcessor.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceGatewayEnvironmentPostProcessor.java index 7956868c6..eac858499 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceGatewayEnvironmentPostProcessor.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceGatewayEnvironmentPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebAsyncClientAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebAsyncClientAutoConfiguration.java index 0638d66e6..bcdb60b1e 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebAsyncClientAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebAsyncClientAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebClientAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebClientAutoConfiguration.java index cc14fa30e..3e7d85c46 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebClientAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebClientAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -26,6 +26,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoRestTemplateCustomizer; import org.springframework.boot.web.client.RestTemplateCustomizer; @@ -104,6 +105,7 @@ class TraceWebClientAutoConfiguration { @Configuration(proxyBeanMethods = false) @ConditionalOnClass(HttpHeadersFilter.class) + @ConditionalOnMissingClass("reactor.netty.http.client.HttpClient") static class HttpHeadersFilterConfig { @Bean diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/feign/SleuthFeignProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/feign/SleuthFeignProperties.java index 04eebd04a..cab1c5df2 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/feign/SleuthFeignProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/feign/SleuthFeignProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java index 69dc11de2..82be97f8f 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -35,6 +35,7 @@ import org.springframework.cloud.sleuth.instrument.web.client.feign.FeignContext import org.springframework.cloud.sleuth.instrument.web.client.feign.OkHttpFeignClientBeanPostProcessor; import org.springframework.cloud.sleuth.instrument.web.client.feign.SleuthFeignBuilder; import org.springframework.cloud.sleuth.instrument.web.client.feign.TraceFeignAspect; +import org.springframework.cloud.sleuth.instrument.web.client.feign.TraceFeignBuilderBeanPostProcessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @@ -68,6 +69,11 @@ public class TraceFeignClientAutoConfiguration { return new FeignContextBeanPostProcessor(beanFactory); } + @Bean + static TraceFeignBuilderBeanPostProcessor traceFeignBuilderBeanPostProcessor(BeanFactory beanFactory) { + return new TraceFeignBuilderBeanPostProcessor(beanFactory); + } + } @Configuration(proxyBeanMethods = false) diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinActiveMqSenderConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinActiveMqSenderConfiguration.java index d1357afa1..8829c93fe 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinActiveMqSenderConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinActiveMqSenderConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinAutoConfiguration.java index 99c3ba13a..1b1559997 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinBraveConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinBraveConfiguration.java index 1b465ae7f..66e3de35f 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinBraveConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinBraveConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinKafkaSenderConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinKafkaSenderConfiguration.java index d4820a631..2f9a43577 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinKafkaSenderConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinKafkaSenderConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinRabbitSenderConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinRabbitSenderConfiguration.java index 39d165836..829ffce26 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinRabbitSenderConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinRabbitSenderConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinRestTemplateSenderConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinRestTemplateSenderConfiguration.java index 26ccb2a97..8fa5f2358 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinRestTemplateSenderConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinRestTemplateSenderConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -54,7 +54,7 @@ class ZipkinRestTemplateSenderConfiguration { ZipkinUrlExtractor extractor) { RestTemplate restTemplate = new ZipkinRestTemplateWrapper(zipkin, extractor); restTemplate = zipkinRestTemplateCustomizer.customizeTemplate(restTemplate); - return new RestTemplateSender(restTemplate, zipkin.getBaseUrl(), zipkin.getEncoder()); + return new RestTemplateSender(restTemplate, zipkin.getBaseUrl(), zipkin.getApiPath(), zipkin.getEncoder()); } @Bean diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinSenderCondition.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinSenderCondition.java index cd59c2735..01890c081 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinSenderCondition.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinSenderCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinSenderConfigurationImportSelector.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinSenderConfigurationImportSelector.java index 6886f8be6..31cca6154 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinSenderConfigurationImportSelector.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinSenderConfigurationImportSelector.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinSenderProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinSenderProperties.java index 546142f4f..7a58d42da 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinSenderProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinSenderProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index d655251ff..ef1e667b5 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -1,135 +1,159 @@ -{ - "properties": [ - { - "name": "spring.zipkin.kafka.topic", - "type": "java.lang.String", - "description": "Name of the Kafka topic where spans should be sent to Zipkin.", - "defaultValue": "zipkin" - }, - { - "name": "spring.zipkin.rabbitmq.queue", - "type": "java.lang.String", - "description": "Name of the RabbitMQ queue where spans should be sent to Zipkin.", - "defaultValue": "zipkin" - }, - { - "name": "spring.zipkin.rabbitmq.addresses", - "type": "java.lang.String", - "description": "Addresses of the RabbitMQ brokers used to send spans to Zipkin" - }, - { - "name": "spring.zipkin.activemq.queue", - "type": "java.lang.String", - "description": "Name of the ActiveMQ queue where spans should be sent to Zipkin.", - "defaultValue": "zipkin" - }, - { - "name": "spring.zipkin.activemq.message-max-bytes", - "type": "java.lang.String", - "description": "Maximum number of bytes for a given message with spans sent to Zipkin over ActiveMQ.", - "defaultValue": 100000 - }, - { - "name": "spring.sleuth.function.enabled", - "type": "java.lang.Boolean", - "description": "Enable instrumenting of Spring Cloud Function and Spring Cloud Function based projects (e.g. Spring Cloud Stream).", - "defaultValue": true - }, - { - "name": "spring.sleuth.integration.websockets.enabled", - "type": "java.lang.Boolean", - "description": "Enable tracing for WebSockets.", - "defaultValue": true - }, - { - "name": "spring.sleuth.async.enabled", - "type": "java.lang.Boolean", - "description": "Enable instrumenting async related components so that the tracing information is passed between threads.", - "defaultValue": true - }, - { - "name": "spring.sleuth.async.configurer.enabled", - "type": "java.lang.Boolean", - "description": "Enable default AsyncConfigurer.", - "defaultValue": true - }, - { - "name": "spring.sleuth.feign.enabled", - "type": "java.lang.Boolean", - "description": "Enable span information propagation when using Feign.", - "defaultValue": true - }, - { - "name": "spring.sleuth.feign.processor.enabled", - "type": "java.lang.Boolean", - "description": "Enable post processor that wraps Feign Context in its tracing representations.", - "defaultValue": true - }, - { - "name": "spring.sleuth.grpc.enabled", - "type": "java.lang.Boolean", - "description": "Enable span information propagation when using GRPC.", - "defaultValue": true - }, - { - "name": "spring.sleuth.messaging.jms.enabled", - "type": "java.lang.Boolean", - "description": "Enable tracing of JMS.", - "defaultValue": true - }, - { - "name": "spring.sleuth.messaging.rabbit.enabled", - "type": "java.lang.Boolean", - "description": "Enable tracing of RabbitMQ.", - "defaultValue": true - }, - { - "name": "spring.sleuth.messaging.kafka.enabled", - "type": "java.lang.Boolean", - "description": "Enable tracing of Kafka.", - "defaultValue": true - }, - { - "name": "spring.sleuth.messaging.kafka.mapper.enabled", - "type": "java.lang.Boolean", - "description": "Enable DefaultKafkaHeaderMapper tracing for Kafka.", - "defaultValue": true - }, - { - "name": "spring.sleuth.quartz.enabled", - "type": "java.lang.Boolean", - "description": "Enable tracing for Quartz.", - "defaultValue": true - }, - { - "name": "spring.sleuth.mongodb.enabled", - "type": "java.lang.Boolean", - "description": "Enable tracing for MongoDb.", - "defaultValue": true - }, - { - "name": "spring.sleuth.rpc.enabled", - "type": "java.lang.Boolean", - "description": "Enable tracing of RPC.", - "defaultValue": true - }, - { - "name": "spring.sleuth.sampler.refresh.enabled", - "type": "java.lang.Boolean", - "description": "Enable refresh scope for sampler.", - "defaultValue": true - }, - { - "name": "spring.sleuth.web.webclient.enabled", - "type": "java.lang.Boolean", - "description": "Enable tracing instrumentation for WebClient.", - "defaultValue": true - }, - { - "name": "spring.sleuth.integration.enabled", - "type": "java.lang.Boolean", - "description": "Enable Spring Integration sleuth instrumentation.", - "defaultValue": true - } - ] -} +{ + "properties": [ + { + "name": "spring.zipkin.kafka.topic", + "type": "java.lang.String", + "description": "Name of the Kafka topic where spans should be sent to Zipkin.", + "defaultValue": "zipkin" + }, + { + "name": "spring.zipkin.rabbitmq.queue", + "type": "java.lang.String", + "description": "Name of the RabbitMQ queue where spans should be sent to Zipkin.", + "defaultValue": "zipkin" + }, + { + "name": "spring.zipkin.rabbitmq.addresses", + "type": "java.lang.String", + "description": "Addresses of the RabbitMQ brokers used to send spans to Zipkin" + }, + { + "name": "spring.zipkin.activemq.queue", + "type": "java.lang.String", + "description": "Name of the ActiveMQ queue where spans should be sent to Zipkin.", + "defaultValue": "zipkin" + }, + { + "name": "spring.zipkin.activemq.message-max-bytes", + "type": "java.lang.String", + "description": "Maximum number of bytes for a given message with spans sent to Zipkin over ActiveMQ.", + "defaultValue": 100000 + }, + { + "name": "spring.sleuth.function.enabled", + "type": "java.lang.Boolean", + "description": "Enable instrumenting of Spring Cloud Function and Spring Cloud Function based projects (e.g. Spring Cloud Stream).", + "defaultValue": true + }, + { + "name": "spring.sleuth.integration.websockets.enabled", + "type": "java.lang.Boolean", + "description": "Enable tracing for WebSockets.", + "defaultValue": true + }, + { + "name": "spring.sleuth.async.enabled", + "type": "java.lang.Boolean", + "description": "Enable instrumenting async related components so that the tracing information is passed between threads.", + "defaultValue": true + }, + { + "name": "spring.sleuth.async.configurer.enabled", + "type": "java.lang.Boolean", + "description": "Enable default AsyncConfigurer.", + "defaultValue": true + }, + { + "name": "spring.sleuth.feign.enabled", + "type": "java.lang.Boolean", + "description": "Enable span information propagation when using Feign.", + "defaultValue": true + }, + { + "name": "spring.sleuth.feign.processor.enabled", + "type": "java.lang.Boolean", + "description": "Enable post processor that wraps Feign Context in its tracing representations.", + "defaultValue": true + }, + { + "name": "spring.sleuth.grpc.enabled", + "type": "java.lang.Boolean", + "description": "Enable span information propagation when using GRPC.", + "defaultValue": true + }, + { + "name": "spring.sleuth.messaging.jms.enabled", + "type": "java.lang.Boolean", + "description": "Enable tracing of JMS.", + "defaultValue": true + }, + { + "name": "spring.sleuth.messaging.rabbit.enabled", + "type": "java.lang.Boolean", + "description": "Enable tracing of RabbitMQ.", + "defaultValue": true + }, + { + "name": "spring.sleuth.messaging.kafka.enabled", + "type": "java.lang.Boolean", + "description": "Enable tracing of Kafka.", + "defaultValue": true + }, + { + "name": "spring.sleuth.messaging.kafka.mapper.enabled", + "type": "java.lang.Boolean", + "description": "Enable DefaultKafkaHeaderMapper tracing for Kafka.", + "defaultValue": true + }, + { + "name": "spring.sleuth.quartz.enabled", + "type": "java.lang.Boolean", + "description": "Enable tracing for Quartz.", + "defaultValue": true + }, + { + "name": "spring.sleuth.mongodb.enabled", + "type": "java.lang.Boolean", + "description": "Enable tracing for MongoDb.", + "defaultValue": true + }, + { + "name": "spring.sleuth.rpc.enabled", + "type": "java.lang.Boolean", + "description": "Enable tracing of RPC.", + "defaultValue": true + }, + { + "name": "spring.sleuth.sampler.refresh.enabled", + "type": "java.lang.Boolean", + "description": "Enable refresh scope for sampler.", + "defaultValue": true + }, + { + "name": "spring.sleuth.web.webclient.enabled", + "type": "java.lang.Boolean", + "description": "Enable tracing instrumentation for WebClient.", + "defaultValue": true + }, + { + "name": "spring.sleuth.integration.enabled", + "type": "java.lang.Boolean", + "description": "Enable Spring Integration instrumentation.", + "defaultValue": true + }, + { + "name": "spring.sleuth.task.enabled", + "type": "java.lang.Boolean", + "description": "Enable Spring Cloud Task instrumentation.", + "defaultValue": true + }, + { + "name": "spring.sleuth.deployer.enabled", + "type": "java.lang.Boolean", + "description": "Enable Spring Cloud Deployer instrumentation.", + "defaultValue": true + }, + { + "name": "spring.sleuth.deployer.status-poll-delay", + "type": "java.lang.Long", + "description": "Default poll delay to retrieve the deployed application status.", + "defaultValue": 500 + }, + { + "name": "spring.sleuth.config.server.enabled", + "type": "java.lang.Boolean", + "description": "Enable Spring Cloud Config Server instrumentation.", + "defaultValue": true + } + ] +} diff --git a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories index 02e2a0409..89df7248f 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories @@ -1,33 +1,37 @@ -# Auto Configuration -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.sleuth.autoconfig.instrument.async.TraceAsyncAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.async.TraceAsyncCustomAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.async.TraceAsyncDefaultAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.circuitbreaker.TraceCircuitBreakerAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.rxjava.TraceRxJavaAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.quartz.TraceQuartzAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.web.TraceWebAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.web.client.TraceWebClientAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.web.client.feign.TraceFeignClientAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.web.client.TraceWebAsyncClientAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.scheduling.TraceSchedulingAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.reactor.TraceReactorAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceFunctionAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceSpringIntegrationAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceSpringMessagingAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceWebSocketAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.instrument.web.client.BraveWebClientAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.instrument.rpc.BraveRpcAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.instrument.grpc.BraveGrpcAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.instrument.messaging.BraveKafkaStreamsAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.instrument.messaging.BraveMessagingAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.instrument.opentracing.BraveOpentracingAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.instrument.redis.BraveRedisAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.instrument.mongodb.BraveMongoDbAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.zipkin2.ZipkinAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.wavefront.WavefrontSleuthAutoConfiguration -# Environment Post Processor -org.springframework.boot.env.EnvironmentPostProcessor=\ -org.springframework.cloud.sleuth.autoconfig.TraceEnvironmentPostProcessor,\ -org.springframework.cloud.sleuth.autoconfig.instrument.web.client.TraceGatewayEnvironmentPostProcessor \ No newline at end of file +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.cloud.sleuth.autoconfig.instrument.async.TraceAsyncAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.async.TraceAsyncCustomAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.async.TraceAsyncDefaultAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.config.TraceSpringCloudConfigAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.circuitbreaker.TraceCircuitBreakerAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.deployer.TraceDeployerAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.rxjava.TraceRxJavaAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.quartz.TraceQuartzAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.task.TraceTaskAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.web.TraceWebAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.web.client.TraceWebClientAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.web.client.feign.TraceFeignClientAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.web.client.TraceWebAsyncClientAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.scheduling.TraceSchedulingAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.reactor.TraceReactorAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceFunctionAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceSpringIntegrationAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceSpringMessagingAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceWebSocketAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.rsocket.TraceRSocketAutoConfiguration, \ +org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.brave.instrument.web.client.BraveWebClientAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.brave.instrument.rpc.BraveRpcAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.brave.instrument.grpc.BraveGrpcAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.brave.instrument.messaging.BraveKafkaStreamsAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.brave.instrument.messaging.BraveMessagingAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.brave.instrument.opentracing.BraveOpentracingAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.brave.instrument.redis.BraveRedisAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.brave.instrument.mongodb.BraveMongoDbAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.zipkin2.ZipkinAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.wavefront.WavefrontSleuthAutoConfiguration +# Environment Post Processor +org.springframework.boot.env.EnvironmentPostProcessor=\ +org.springframework.cloud.sleuth.autoconfig.TraceEnvironmentPostProcessor,\ +org.springframework.cloud.sleuth.autoconfig.instrument.web.client.TraceGatewayEnvironmentPostProcessor diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/DisableSecurity.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/DisableSecurity.java index f70f3c635..77de3d315 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/DisableSecurity.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/DisableSecurity.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/DisableWebFluxSecurity.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/DisableWebFluxSecurity.java index eac93610a..da65f6cf4 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/DisableWebFluxSecurity.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/DisableWebFluxSecurity.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/PermitAllServletConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/PermitAllServletConfiguration.java index e597420ff..511a9a5ae 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/PermitAllServletConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/PermitAllServletConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/PermitAllWebFluxSecurityConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/PermitAllWebFluxSecurityConfiguration.java index 6341101cb..e3a81ffb9 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/PermitAllWebFluxSecurityConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/PermitAllWebFluxSecurityConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/SleuthTestAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/SleuthTestAutoConfiguration.java index 4756e5b9b..9f5aee12f 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/SleuthTestAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/SleuthTestAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpBaggageInScope.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpBaggageInScope.java index 858ab72e3..a06d1e5eb 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpBaggageInScope.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpBaggageInScope.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpCurrentTraceContext.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpCurrentTraceContext.java index 2435f85a0..16a7305e0 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpCurrentTraceContext.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpCurrentTraceContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpHttpClientHandler.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpHttpClientHandler.java index e958d7240..20d625782 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpHttpClientHandler.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpHttpClientHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpHttpServerHandler.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpHttpServerHandler.java index 87357ed29..40a6b5359 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpHttpServerHandler.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpHttpServerHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpPropagator.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpPropagator.java index 60368f0b4..d4fd97a92 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpPropagator.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpPropagator.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpScopedSpan.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpScopedSpan.java index 4a2b1e64a..79a6bc9d3 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpScopedSpan.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpScopedSpan.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpan.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpan.java index 266e8b2ff..e12d42b04 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpan.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpan.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -72,4 +72,9 @@ class NoOpSpan implements Span { } + @Override + public Span remoteServiceName(String remoteServiceName) { + return this; + } + } diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpanBuilder.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpanBuilder.java index 52e0ac5ce..80501d0fb 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpanBuilder.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpanBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpanCustomizer.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpanCustomizer.java index 75caa6dd4..467137c8b 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpanCustomizer.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpanCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpanInScope.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpanInScope.java index b34cc321d..c746e5f31 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpanInScope.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpanInScope.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTraceContext.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTraceContext.java index 73d19902a..c5b337b6b 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTraceContext.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTraceContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTraceContextBuilder.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTraceContextBuilder.java new file mode 100644 index 000000000..c0b17da52 --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTraceContextBuilder.java @@ -0,0 +1,54 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig; + +import org.springframework.cloud.sleuth.TraceContext; + +/** + * A noop implementation. Does nothing. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +class NoOpTraceContextBuilder implements TraceContext.Builder { + + @Override + public TraceContext.Builder traceId(String traceId) { + return this; + } + + @Override + public TraceContext.Builder parentId(String traceId) { + return this; + } + + @Override + public TraceContext.Builder spanId(String spanId) { + return null; + } + + @Override + public TraceContext.Builder sampled(Boolean sampled) { + return this; + } + + @Override + public TraceContext build() { + return new NoOpTraceContext(); + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTracer.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTracer.java index 0b5413a8b..08d4d99ea 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTracer.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTracer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -69,6 +69,11 @@ class NoOpTracer implements Tracer { return new NoOpSpanBuilder(); } + @Override + public TraceContext.Builder traceContextBuilder() { + return new NoOpTraceContextBuilder(); + } + @Override public Map getAllBaggage() { return new HashMap<>(); diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/SleuthNewSpanParserAnnotationDisableTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/SleuthNewSpanParserAnnotationDisableTests.java index cc3da1ef1..7974663da 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/SleuthNewSpanParserAnnotationDisableTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/SleuthNewSpanParserAnnotationDisableTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/SleuthNewSpanParserAnnotationNoSleuthTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/SleuthNewSpanParserAnnotationNoSleuthTests.java index 40260f261..d19e833c7 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/SleuthNewSpanParserAnnotationNoSleuthTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/SleuthNewSpanParserAnnotationNoSleuthTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/SpanIgnoringSpanFilterTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/SpanIgnoringSpanFilterTests.java index 84030c105..88c9d8ad8 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/SpanIgnoringSpanFilterTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/SpanIgnoringSpanFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceNoOpAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceNoOpAutoConfiguration.java index 2c5dc905b..2446ae330 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceNoOpAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceNoOpAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfigurationCustomizersTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfigurationCustomizersTests.java index d6c74d5b7..f323fbc09 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfigurationCustomizersTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfigurationCustomizersTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfigurationPropagationCustomizationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfigurationPropagationCustomizationTests.java index b19eeacad..17ca7c2d2 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfigurationPropagationCustomizationTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfigurationPropagationCustomizationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfigurationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfigurationTests.java index 3667325a9..abd440e65 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfigurationTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfigurationWithDisabledSleuthTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfigurationWithDisabledSleuthTests.java index 5e99f8efb..8b7434b84 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfigurationWithDisabledSleuthTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfigurationWithDisabledSleuthTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BravePropagationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BravePropagationTests.java index c4006c520..96a2f0f94 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BravePropagationTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BravePropagationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveSamplerConfigurationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveSamplerConfigurationTests.java index 3af0c2d60..98f44dae1 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveSamplerConfigurationTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveSamplerConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/SpanHandlerTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/SpanHandlerTests.java index fc060c426..ec5fdc125 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/SpanHandlerTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/SpanHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/TraceBaggageEntryConfigurationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/TraceBaggageEntryConfigurationTests.java index 3a400c16f..557c8738d 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/TraceBaggageEntryConfigurationTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/TraceBaggageEntryConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/baggage/CompositePropagationFactoryTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/baggage/CompositePropagationFactoryTests.java new file mode 100644 index 000000000..08076e397 --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/baggage/CompositePropagationFactoryTests.java @@ -0,0 +1,80 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.brave.baggage; + +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; +import reactor.util.context.ContextView; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.cloud.sleuth.DisableWebFluxSecurity; +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration; +import org.springframework.cloud.sleuth.autoconfig.instrument.reactor.TraceReactorAutoConfiguration; +import org.springframework.cloud.sleuth.autoconfig.instrument.web.TraceWebAutoConfiguration; +import org.springframework.context.annotation.Import; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static org.hamcrest.core.IsEqual.equalTo; + +@WebFluxTest(controllers = TracingResource.class, properties = "spring.main.web-application-type=reactive") +@ImportAutoConfiguration({ BraveAutoConfiguration.class, TraceWebAutoConfiguration.class, + TraceReactorAutoConfiguration.class }) +@Import(TracingResource.class) +@DisableWebFluxSecurity +public class CompositePropagationFactoryTests { + + @Autowired + TracingResource tracingResource; + + @Test + void should_delegate_configuration_to_propagation_factory(@Autowired WebTestClient webTestClient) { + // issue 1846 - without the fix supportJoin is assumed to be false + // because it's not taken from the configuration but from not overridden + // methods from CompositePropagationFactorySupplier + String spanId = "a2fb4a1d1a96d312"; + webTestClient.get().uri("/api/tracing/spanId").header("X-B3-TraceId", "463ac35c9f6413ad48485a3953bb6124") + .header("X-B3-SpanId", spanId).header("X-B3-ParentSpanId", "0020000000000001").header("X-B3-Flags", "1") + .exchange().expectStatus().isOk().expectBody(String.class) + .value(returnedSpanId -> returnedSpanId, equalTo(spanId)); + + } + +} + +@RestController +@RequestMapping("/api/tracing") +class TracingResource { + + private static final Class KEY = TraceContext.class; + + @GetMapping("spanId") + public Mono spanId() { + return Mono.deferContextual(view -> traceContext(view)).map(c -> c.spanId()); + + } + + private Mono traceContext(ContextView contextView) { + return Mono.justOrEmpty(contextView.get(KEY)); + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/baggage/CorrelationScopeDecoratorTest.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/baggage/CorrelationScopeDecoratorTest.java index 02720df5e..048103ead 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/baggage/CorrelationScopeDecoratorTest.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/baggage/CorrelationScopeDecoratorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveKafkaStreamsAutoConfigurationIntegrationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveKafkaStreamsAutoConfigurationIntegrationTests.java index a74554233..19fd0c0a2 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveKafkaStreamsAutoConfigurationIntegrationTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveKafkaStreamsAutoConfigurationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveMessagingAutoConfigurationIntegrationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveMessagingAutoConfigurationIntegrationTests.java index 3fe52218f..86cc9da85 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveMessagingAutoConfigurationIntegrationTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveMessagingAutoConfigurationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfigurationAsyncDriverTest.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfigurationAsyncDriverTest.java new file mode 100644 index 000000000..7d9139d0a --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfigurationAsyncDriverTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.brave.instrument.mongodb; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Chintan Radia + */ +class BraveMongoDbAutoConfigurationAsyncDriverTest { + + @Test + void should_not_auto_configure_brave_mongo_db() { + new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(BraveAutoConfiguration.class, BraveMongoDbAutoConfiguration.class)) + .run(context -> assertThat(context).doesNotHaveBean(BraveMongoDbAutoConfiguration.class)); + } + + @Test + void should_auto_configure_brave_mongo_db() { + new ApplicationContextRunner() + .withClassLoader(new FilteredClassLoader("com.mongodb.reactivestreams.client.MongoClient")) + .withConfiguration( + AutoConfigurations.of(BraveAutoConfiguration.class, BraveMongoDbAutoConfiguration.class)) + .run(context -> assertThat(context).hasSingleBean(BraveMongoDbAutoConfiguration.class)); + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfigurationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfigurationTests.java index 8570e8a66..c240a0374 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfigurationTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/opentracing/OpenTracingTest.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/opentracing/OpenTracingTest.java index 0afae9e92..3e19f084e 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/opentracing/OpenTracingTest.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/opentracing/OpenTracingTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/rpc/BraveRpcAutoConfigurationIntegrationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/rpc/BraveRpcAutoConfigurationIntegrationTests.java index 84c5d1c6d..43c4f9420 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/rpc/BraveRpcAutoConfigurationIntegrationTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/rpc/BraveRpcAutoConfigurationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpConfigurationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpConfigurationTests.java index fa2314a92..d3d1ffef0 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpConfigurationTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/EndpointWithCyclicDependenciesTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/EndpointWithCyclicDependenciesTests.java index 4f7ebd80c..427c37097 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/EndpointWithCyclicDependenciesTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/EndpointWithCyclicDependenciesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/client/WebClientTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/client/WebClientTests.java index 6831e1e95..d874d7544 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/client/WebClientTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/client/WebClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -19,6 +19,7 @@ package org.springframework.cloud.sleuth.autoconfig.brave.instrument.web.client; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Future; +import java.util.stream.Collectors; import brave.Span; import brave.Tracer; @@ -104,7 +105,7 @@ public class WebClientTests { then(this.tracer.currentSpan()).isNull(); then(this.spans).isNotEmpty().extracting("traceId", String.class).containsOnly(span.context().traceIdString()); - then(this.spans).extracting("kind.name").contains("CLIENT"); + then(this.spans.spans().stream().map(s -> s.kind().name()).collect(Collectors.toList())).contains("CLIENT"); } @Test @@ -140,7 +141,7 @@ public class WebClientTests { then(this.tracer.currentSpan()).isNull(); then(this.spans).isNotEmpty().extracting("traceId", String.class).containsOnly(span.context().traceIdString()); - then(this.spans).extracting("kind.name").contains("CLIENT"); + then(this.spans.spans().stream().map(s -> s.kind().name()).collect(Collectors.toList())).contains("CLIENT"); } @Configuration(proxyBeanMethods = false) diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncCustomAutoConfigurationTest.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncCustomAutoConfigurationTest.java index bd4fd4ac3..00d1e0521 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncCustomAutoConfigurationTest.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncCustomAutoConfigurationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncDefaultAutoConfigurationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncDefaultAutoConfigurationTests.java index 94566769b..18bf5a1dd 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncDefaultAutoConfigurationTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncDefaultAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/config/TraceSpringCloudConfigAutoConfigurationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/config/TraceSpringCloudConfigAutoConfigurationTests.java new file mode 100644 index 000000000..8d75ab817 --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/config/TraceSpringCloudConfigAutoConfigurationTests.java @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.config; + +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.cloud.config.server.config.ConfigServerProperties; +import org.springframework.cloud.sleuth.autoconfig.TraceNoOpAutoConfiguration; +import org.springframework.cloud.sleuth.instrument.config.TraceEnvironmentRepositoryAspect; + +class TraceSpringCloudConfigAutoConfigurationTests { + + @Test + void should_register_the_aspect() { + new ApplicationContextRunner().withPropertyValues("spring.sleuth.noop.enabled=true") + .withBean(ConfigServerProperties.class) + .withConfiguration(AutoConfigurations.of(TraceNoOpAutoConfiguration.class, + TraceSpringCloudConfigAutoConfiguration.class)) + .run(context -> BDDAssertions.then(context).hasSingleBean(TraceEnvironmentRepositoryAspect.class)); + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringIntegrationAutoConfigurationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringIntegrationAutoConfigurationTests.java index 33e0f20b7..77e92316d 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringIntegrationAutoConfigurationTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringIntegrationAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceWebSocketAutoConfigurationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceWebSocketAutoConfigurationTests.java index 1b4494cda..f97fecad2 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceWebSocketAutoConfigurationTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceWebSocketAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/quartz/TraceQuartzAutoConfigurationTest.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/quartz/TraceQuartzAutoConfigurationTest.java index 709453023..8ed2cd5be 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/quartz/TraceQuartzAutoConfigurationTest.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/quartz/TraceQuartzAutoConfigurationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/scheduling/TraceSchedulingAutoConfigurationTest.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/scheduling/TraceSchedulingAutoConfigurationTest.java index 291b07fce..04af68065 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/scheduling/TraceSchedulingAutoConfigurationTest.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/scheduling/TraceSchedulingAutoConfigurationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternProviderConfigTest.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternProviderConfigTest.java index bc120be58..aca9c1387 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternProviderConfigTest.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternProviderConfigTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -106,7 +106,9 @@ public class SkipPatternProviderConfigTest { contextRunner .withConfiguration( UserConfigurations.of(ManagementContextAutoConfiguration.class, ServerPropertiesConfig.class)) - .withPropertyValues("management.server.servlet.context-path=foo").run(context -> { + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.server.servlet.context-path=foo") + .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "/actuator(/|/(health|health/.*|info|info/.*))?", "foo.*", SleuthWebProperties.DEFAULT_SKIP_PATTERN); @@ -118,7 +120,9 @@ public class SkipPatternProviderConfigTest { contextRunner .withConfiguration( UserConfigurations.of(ManagementContextAutoConfiguration.class, ServerPropertiesConfig.class)) - .withPropertyValues("management.server.servlet.context-path=${test:value}").run(context -> { + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.server.servlet.context-path=${test:value}") + .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "/actuator(/|/(health|health/.*|info|info/.*))?", "value.*", SleuthWebProperties.DEFAULT_SKIP_PATTERN); @@ -137,16 +141,19 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_without_context_path() { - contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)).run(context -> { - BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( - "/actuator(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); - }); + contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) + .withPropertyValues("management.endpoints.web.exposure.include=health,info").run(context -> { + BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( + "/actuator(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); + }); } @Test public void should_return_endpoints_with_context_path() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("server.servlet.context-path=foo").run(context -> { + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "server.servlet.context-path=foo") + .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "foo/actuator(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); @@ -156,7 +163,9 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_context_path_with_placeholders() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("server.servlet.context-path=${test:foo}").run(context -> { + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "server.servlet.context-path=${test:foo}") + .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "foo/actuator(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); @@ -166,7 +175,9 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_without_context_path_and_base_path_set_to_root() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=/").run(context -> { + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=/") + .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "/(health|health/.*|info|info/.*)", SleuthWebProperties.DEFAULT_SKIP_PATTERN); }); @@ -175,7 +186,9 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_without_context_path_and_base_path_set_to_root_with_placeholders() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=${test:/}").run(context -> { + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=${test:/}") + .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "/(health|health/.*|info|info/.*)", SleuthWebProperties.DEFAULT_SKIP_PATTERN); }); @@ -184,7 +197,8 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_context_path_and_base_path_set_to_root() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=/", "server.servlet.context-path=foo") + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=/", "server.servlet.context-path=foo") .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "foo(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); @@ -194,7 +208,8 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_context_path_and_base_path_set_to_root_with_placeholder() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=${test:/}", "server.servlet.context-path=foo") + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=${test:/}", "server.servlet.context-path=foo") .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "foo(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); @@ -204,7 +219,8 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_context_path_and_base_path_set_to_root_different_port() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=/", "management.server.port=0", + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=/", "management.server.port=0", "server.servlet.context-path=foo") .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( @@ -212,10 +228,26 @@ public class SkipPatternProviderConfigTest { }); } + @Test + public void should_return_endpoints_with_base_path_when_management_port_is_different() { + contextRunner + .withConfiguration( + UserConfigurations.of(ServerPropertiesConfig.class, ManagementServerPropertiesConfig.class)) + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.server.base-path=/foo", "management.endpoints.web.base-path=/actuator", + "management.server.port=0") + .run(context -> { + BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( + "/foo/actuator(/|/(health|health/.*|info|info/.*))?", + SleuthWebProperties.DEFAULT_SKIP_PATTERN); + }); + } + @Test public void should_return_endpoints_with_context_path_and_base_path_set_to_root_different_port_with_placeholder() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=/", "management.server.port=${some-port:0}", + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=/", "management.server.port=${some-port:0}", "server.servlet.context-path=${some-path:foo}") .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( @@ -226,7 +258,8 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_actuator_context_path_only() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=/mgt", "server.servlet.context-path=foo") + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=/mgt", "server.servlet.context-path=foo") .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "foo/mgt(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); @@ -236,8 +269,8 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_actuator_context_path_only_with_placeholder() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=/${test:mgt}", - "server.servlet.context-path=${test2:foo}") + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=/${test:mgt}", "server.servlet.context-path=${test2:foo}") .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "foo/mgt(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); @@ -247,7 +280,9 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_actuator_default_context_path_different_port() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.server.port=0", "server.servlet.context-path=foo").run(context -> { + .withPropertyValues("management.endpoints.web.exposure.include=health,info", "management.server.port=0", + "server.servlet.context-path=foo") + .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "/actuator(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); }); @@ -256,7 +291,8 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_actuator_context_path_only_different_port() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=/mgt", "management.server.port=0", + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=/mgt", "management.server.port=0", "server.servlet.context-path=foo") .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( @@ -267,7 +303,9 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_context_path_different_port() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.server.port=0", "server.servlet.context-path=foo").run(context -> { + .withPropertyValues("management.endpoints.web.exposure.include=health,info", "management.server.port=0", + "server.servlet.context-path=foo") + .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "/actuator(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); }); @@ -313,6 +351,12 @@ public class SkipPatternProviderConfigTest { } + @Configuration(proxyBeanMethods = false) + @EnableConfigurationProperties(ManagementServerProperties.class) + static class ManagementServerPropertiesConfig { + + } + @Configuration(proxyBeanMethods = false) static class EmptyEndpoints { diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebServletConfigurationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebServletConfigurationTests.java index 37c3367d3..5f65da710 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebServletConfigurationTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebServletConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/BraveWebClientAutoConfigurationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/BraveWebClientAutoConfigurationTests.java index 516a4066b..4767c32cf 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/BraveWebClientAutoConfigurationTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/BraveWebClientAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/GH846Tests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/GH846Tests.java index 7e0053341..9e0bf7b62 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/GH846Tests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/GH846Tests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/GatewayAutoConfigurationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/GatewayAutoConfigurationTests.java new file mode 100644 index 000000000..94711c59f --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/GatewayAutoConfigurationTests.java @@ -0,0 +1,50 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.web.client; + +import org.junit.jupiter.api.Test; +import reactor.netty.http.client.HttpClient; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter; +import org.springframework.cloud.sleuth.autoconfig.TraceNoOpAutoConfiguration; +import org.springframework.cloud.sleuth.instrument.web.client.TraceRequestHttpHeadersFilter; +import org.springframework.cloud.sleuth.instrument.web.client.TraceResponseHttpHeadersFilter; + +import static org.assertj.core.api.Assertions.assertThat; + +class GatewayAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withPropertyValues("spring.sleuth.noop.enabled=true").withConfiguration( + AutoConfigurations.of(TraceNoOpAutoConfiguration.class, TraceWebClientAutoConfiguration.class)); + + @Test + void should_not_create_gateway_trace_filters_when_reactor_netty_client_on_classpath() { + this.contextRunner.run(context -> assertThat(context).doesNotHaveBean(HttpHeadersFilter.class)); + } + + @Test + void should_create_gateway_trace_filters_when_reactor_netty_client_not_on_classpath() { + this.contextRunner.withClassLoader(new FilteredClassLoader(HttpClient.class)) + .run(context -> assertThat(context).hasSingleBean(TraceResponseHttpHeadersFilter.class) + .hasSingleBean(TraceRequestHttpHeadersFilter.class)); + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebClientDisabledTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebClientDisabledTests.java index 513857ebc..6875a7dc9 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebClientDisabledTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebClientDisabledTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/feign/TraceNoWebEnvironmentTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/feign/TraceNoWebEnvironmentTests.java index a9dce11b3..9c9b1794d 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/feign/TraceNoWebEnvironmentTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/feign/TraceNoWebEnvironmentTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -47,7 +47,8 @@ public class TraceNoWebEnvironmentTests { client.createSomeTestRequest(); } catch (Exception e) { - then(e.getCause().getClass()).isNotEqualTo(NoSuchBeanDefinitionException.class); + Throwable cause = e.getCause() != null ? e.getCause() : e; + then(cause.getClass()).isNotEqualTo(NoSuchBeanDefinitionException.class); } } diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinSamplerTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinSamplerTests.java index 40a92cc1f..11d7aa2f0 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinSamplerTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinSamplerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinWithDisabledSleuthTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinWithDisabledSleuthTests.java index 27e9fd61e..62c1ae7fd 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinWithDisabledSleuthTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinWithDisabledSleuthTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/pom.xml b/spring-cloud-sleuth-brave/pom.xml index 80ab5d2b9..1069e4dbe 100644 --- a/spring-cloud-sleuth-brave/pom.xml +++ b/spring-cloud-sleuth-brave/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/LocalServiceName.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/LocalServiceName.java index 47e01f134..39ffe5ad1 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/LocalServiceName.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/LocalServiceName.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveBaggageInScope.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveBaggageInScope.java index cd49c33a5..e9f666a71 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveBaggageInScope.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveBaggageInScope.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveBaggageManager.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveBaggageManager.java index 319a8178e..9970342ff 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveBaggageManager.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveBaggageManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveCurrentTraceContext.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveCurrentTraceContext.java index 4ac699153..2bc97d580 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveCurrentTraceContext.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveCurrentTraceContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveFinishedSpan.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveFinishedSpan.java index e24700ae0..2536d33ad 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveFinishedSpan.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveFinishedSpan.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpClientHandler.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpClientHandler.java index ac7fe3ea9..996efed6c 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpClientHandler.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpClientHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpClientRequest.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpClientRequest.java index 641b3124c..20c71aed5 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpClientRequest.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpClientRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpClientResponse.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpClientResponse.java index 0a0a50030..85f665a19 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpClientResponse.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpClientResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpRequest.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpRequest.java index ad94603c1..be64cbb4b 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpRequest.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpRequestParser.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpRequestParser.java index 79d9a616e..e49f0ee85 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpRequestParser.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpRequestParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpResponse.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpResponse.java index 1157daafc..3d8a99b69 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpResponse.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpResponseParser.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpResponseParser.java index dcbce9ec0..d1a31034f 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpResponseParser.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpResponseParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpServerHandler.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpServerHandler.java index bb62e8b52..456a87c8d 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpServerHandler.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpServerHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpServerRequest.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpServerRequest.java index 5cc784ffa..d6c8f4446 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpServerRequest.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpServerRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpServerResponse.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpServerResponse.java index f0bf8e539..f760b7697 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpServerResponse.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpServerResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BravePropagator.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BravePropagator.java index f27c79862..64d2afec4 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BravePropagator.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BravePropagator.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSamplerFunction.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSamplerFunction.java index 57c42a876..9b85feec6 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSamplerFunction.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSamplerFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveScopedSpan.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveScopedSpan.java index 5349e7820..e760c4239 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveScopedSpan.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveScopedSpan.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpan.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpan.java index 0b3662821..abf330535 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpan.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpan.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -27,11 +27,11 @@ import org.springframework.cloud.sleuth.TraceContext; * @author Marcin Grzejszczak * @since 3.0.0 */ -class BraveSpan implements Span { +public class BraveSpan implements Span { final brave.Span delegate; - BraveSpan(brave.Span delegate) { + public BraveSpan(brave.Span delegate) { this.delegate = delegate; } @@ -86,16 +86,22 @@ class BraveSpan implements Span { this.delegate.abandon(); } + @Override + public Span remoteServiceName(String remoteServiceName) { + this.delegate.remoteServiceName(remoteServiceName); + return this; + } + @Override public String toString() { return this.delegate != null ? this.delegate.toString() : "null"; } - static brave.Span toBrave(Span span) { + public static brave.Span toBrave(Span span) { return ((BraveSpan) span).delegate; } - static Span fromBrave(brave.Span span) { + public static Span fromBrave(brave.Span span) { return new BraveSpan(span); } diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpanBuilder.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpanBuilder.java index 20057bc7c..f47a0d12c 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpanBuilder.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpanBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpanCustomizer.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpanCustomizer.java index 7e8cb1b11..59058cfe6 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpanCustomizer.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpanCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContext.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContext.java index f1d0d6fd9..cd2473a6f 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContext.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContextBuilder.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContextBuilder.java new file mode 100644 index 000000000..0c19ac5b8 --- /dev/null +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContextBuilder.java @@ -0,0 +1,71 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.bridge; + +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.cloud.sleuth.internal.EncodingUtils; + +/** + * Brave implementation of a {@link TraceContext.Builder}. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +class BraveTraceContextBuilder implements TraceContext.Builder { + + brave.propagation.TraceContext.Builder delegate = brave.propagation.TraceContext.newBuilder(); + + @Override + public TraceContext.Builder traceId(String traceId) { + long[] fromString = EncodingUtils.fromString(traceId); + if (fromString.length == 2) { + this.delegate.traceIdHigh(fromString[0]); + this.delegate.traceId(fromString[1]); + } + else { + this.delegate.traceId(fromString[0]); + } + return this; + } + + @Override + public TraceContext.Builder parentId(String traceId) { + long[] fromString = EncodingUtils.fromString(traceId); + this.delegate.parentId(fromString[fromString.length == 2 ? 1 : 0]); + return this; + } + + @Override + public TraceContext.Builder spanId(String spanId) { + long[] fromString = EncodingUtils.fromString(spanId); + this.delegate.spanId(fromString[fromString.length == 2 ? 1 : 0]); + return this; + } + + @Override + public TraceContext.Builder sampled(Boolean sampled) { + this.delegate.sampled(sampled); + return this; + } + + @Override + public TraceContext build() { + brave.propagation.TraceContext context = this.delegate.build(); + return BraveTraceContext.fromBrave(context); + } + +} diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTracer.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTracer.java index b1ca67640..258a5c53b 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTracer.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTracer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -90,6 +90,11 @@ public class BraveTracer implements Tracer { return new BraveSpanBuilder(this.tracer); } + @Override + public TraceContext.Builder traceContextBuilder() { + return new BraveTraceContextBuilder(); + } + @Override public Map getAllBaggage() { return this.braveBaggageManager.getAllBaggage(); diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplier.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplier.java index 09821ca99..269dedef2 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplier.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplier.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -16,6 +16,7 @@ package org.springframework.cloud.sleuth.brave.bridge; +import java.util.AbstractMap; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -30,6 +31,7 @@ import brave.propagation.TraceContextOrSamplingFlags; import brave.propagation.aws.AWSPropagation; import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.cloud.sleuth.brave.propagation.PropagationFactorySupplier; import org.springframework.cloud.sleuth.brave.propagation.PropagationType; @@ -56,7 +58,7 @@ public class CompositePropagationFactorySupplier implements PropagationFactorySu @Override public Propagation.Factory get() { - return new CompositePropagationFactory( + return new CompositePropagationFactory(this.beanFactory, this.beanFactory.getBeanProvider(BraveBaggageManager.class).getIfAvailable(BraveBaggageManager::new), this.localFields, this.types); } @@ -65,32 +67,43 @@ public class CompositePropagationFactorySupplier implements PropagationFactorySu class CompositePropagationFactory extends Propagation.Factory implements Propagation { - private final Map> mapping = new HashMap<>(); + private final Map>> mapping = new HashMap<>(); private final List types; - CompositePropagationFactory(BraveBaggageManager braveBaggageManager, List localFields, - List types) { + CompositePropagationFactory(BeanFactory beanFactory, BraveBaggageManager braveBaggageManager, + List localFields, List types) { this.types = types; - this.mapping.put(PropagationType.AWS, AWSPropagation.FACTORY.get()); + this.mapping.put(PropagationType.AWS, + new AbstractMap.SimpleEntry<>(AWSPropagation.FACTORY, AWSPropagation.FACTORY.get())); // Note: Versions <2.2.3 use injectFormat(MULTI) for non-remote (ex // spring-messaging) // See #1643 - this.mapping.put(PropagationType.B3, - B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build().get()); - this.mapping.put(PropagationType.W3C, new W3CPropagation(braveBaggageManager, localFields)); - this.mapping.put(PropagationType.CUSTOM, NoOpPropagation.INSTANCE); + Factory b3Factory = b3Factory(); + this.mapping.put(PropagationType.B3, new AbstractMap.SimpleEntry<>(b3Factory, b3Factory.get())); + W3CPropagation w3CPropagation = new W3CPropagation(braveBaggageManager, localFields); + this.mapping.put(PropagationType.W3C, new AbstractMap.SimpleEntry<>(w3CPropagation, w3CPropagation.get())); + LazyPropagationFactory lazyPropagationFactory = new LazyPropagationFactory( + beanFactory.getBeanProvider(Factory.class)); + this.mapping.put(PropagationType.CUSTOM, + new AbstractMap.SimpleEntry<>(lazyPropagationFactory, lazyPropagationFactory.get())); + } + + private Factory b3Factory() { + return B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build(); } @Override public List keys() { - return this.types.stream().map(this.mapping::get).flatMap(p -> p.keys().stream()).collect(Collectors.toList()); + return this.types.stream().map(this.mapping::get).flatMap(p -> p.getValue().keys().stream()) + .collect(Collectors.toList()); } @Override public TraceContext.Injector injector(Setter setter) { return (traceContext, request) -> { - this.types.stream().map(this.mapping::get).forEach(p -> p.injector(setter).inject(traceContext, request)); + this.types.stream().map(this.mapping::get) + .forEach(p -> p.getValue().injector(setter).inject(traceContext, request)); }; } @@ -98,7 +111,11 @@ class CompositePropagationFactory extends Propagation.Factory implements Propaga public TraceContext.Extractor extractor(Getter getter) { return request -> { for (PropagationType type : this.types) { - Propagation propagator = this.mapping.get(type); + Map.Entry> entry = this.mapping.get(type); + if (entry == null) { + continue; + } + Propagation propagator = entry.getValue(); if (propagator == null || propagator == NoOpPropagation.INSTANCE) { continue; } @@ -116,7 +133,112 @@ class CompositePropagationFactory extends Propagation.Factory implements Propaga return StringPropagationAdapter.create(this, keyFactory); } - private static class NoOpPropagation implements Propagation { + @Override + public boolean supportsJoin() { + return this.types.stream().map(this.mapping::get).allMatch(e -> e.getKey().supportsJoin()); + } + + @Override + public boolean requires128BitTraceId() { + return this.types.stream().map(this.mapping::get).allMatch(e -> e.getKey().requires128BitTraceId()); + } + + @Override + public TraceContext decorate(TraceContext context) { + for (PropagationType type : this.types) { + Map.Entry> entry = this.mapping.get(type); + if (entry == null) { + continue; + } + TraceContext decorate = entry.getKey().decorate(context); + if (decorate != context) { + return decorate; + } + } + return super.decorate(context); + } + + @SuppressWarnings("unchecked") + private static final class LazyPropagationFactory extends Propagation.Factory { + + private final ObjectProvider delegate; + + private volatile Propagation.Factory propagationFactory; + + private LazyPropagationFactory(ObjectProvider delegate) { + this.delegate = delegate; + } + + private Propagation.Factory propagationFactory() { + if (this.propagationFactory == null) { + this.propagationFactory = this.delegate.getIfAvailable(() -> NoOpPropagation.INSTANCE); + } + return this.propagationFactory; + } + + @Override + public Propagation create(KeyFactory keyFactory) { + return propagationFactory().create(keyFactory); + } + + @Override + public boolean supportsJoin() { + return propagationFactory().supportsJoin(); + } + + @Override + public boolean requires128BitTraceId() { + return propagationFactory().requires128BitTraceId(); + } + + @Override + public Propagation get() { + return new LazyPropagation(this); + } + + @Override + public TraceContext decorate(TraceContext context) { + return propagationFactory().decorate(context); + } + + } + + @SuppressWarnings("unchecked") + private static final class LazyPropagation implements Propagation { + + private final LazyPropagationFactory delegate; + + private volatile Propagation propagation; + + private LazyPropagation(LazyPropagationFactory delegate) { + this.delegate = delegate; + } + + private Propagation propagation() { + if (this.propagation == null) { + this.propagation = this.delegate.propagationFactory().get(); + } + return this.propagation; + } + + @Override + public List keys() { + return propagation().keys(); + } + + @Override + public TraceContext.Injector injector(Setter setter) { + return propagation().injector(setter); + } + + @Override + public TraceContext.Extractor extractor(Getter getter) { + return propagation().extractor(getter); + } + + } + + private static class NoOpPropagation extends Propagation.Factory implements Propagation { static final NoOpPropagation INSTANCE = new NoOpPropagation(); @@ -137,6 +259,11 @@ class CompositePropagationFactory extends Propagation.Factory implements Propaga return request -> TraceContextOrSamplingFlags.EMPTY; } + @Override + public Propagation create(KeyFactory keyFactory) { + return StringPropagationAdapter.create(this, keyFactory); + } + } } diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/CompositeSpanHandler.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/CompositeSpanHandler.java index 16398220f..beee3f488 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/CompositeSpanHandler.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/CompositeSpanHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/W3CPropagation.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/W3CPropagation.java index bb006cb2f..4f8a87207 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/W3CPropagation.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/W3CPropagation.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -37,6 +37,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.cloud.sleuth.BaggageInScope; +import org.springframework.cloud.sleuth.internal.EncodingUtils; import static java.util.Collections.singletonList; @@ -219,12 +220,12 @@ class W3CPropagation extends Propagation.Factory implements Propagation private static boolean isTraceIdValid(CharSequence traceId) { return (traceId.length() == TRACE_ID_HEX_SIZE) && !INVALID_TRACE_ID.contentEquals(traceId) - && BigendianEncoding.isValidBase16String(traceId); + && EncodingUtils.isValidBase16String(traceId); } private static boolean isSpanIdValid(String spanId) { return (spanId.length() == SPAN_ID_HEX_SIZE) && !INVALID_SPAN_ID.equals(spanId) - && BigendianEncoding.isValidBase16String(spanId); + && EncodingUtils.isValidBase16String(spanId); } private static TraceContext extractContextFromTraceParent(String traceparent) { @@ -257,10 +258,10 @@ class W3CPropagation extends Propagation.Factory implements Propagation String traceIdLow = traceId.substring(traceId.length() / 2); byte isSampled = TraceFlags.byteFromHex(traceparent, TRACE_OPTION_OFFSET); return TraceContext.newBuilder().shared(true) - .traceIdHigh(BigendianEncoding.longFromBase16String(traceIdHigh)) - .traceId(BigendianEncoding.longFromBase16String(traceIdLow)) - .spanId(BigendianEncoding.longFromBase16String(spanId)) - .sampled(isSampled == TraceFlags.IS_SAMPLED).build(); + .traceIdHigh(EncodingUtils.longFromBase16String(traceIdHigh)) + .traceId(EncodingUtils.longFromBase16String(traceIdLow)) + .spanId(EncodingUtils.longFromBase16String(spanId)).sampled(isSampled == TraceFlags.IS_SAMPLED) + .build(); } return null; } @@ -421,41 +422,6 @@ final class TemporaryBuffers { } -/** - * Taken from OpenTelemetry API. - */ -final class Utils { - - private Utils() { - - } - - /** - * Throws an {@link IllegalArgumentException} if the argument is false. This method is - * similar to {@code Preconditions.checkArgument(boolean, Object)} from Guava. - * @param isValid whether the argument check passed. - * @param errorMessage the message to use for the exception. - */ - static void checkArgument(boolean isValid, String errorMessage) { - if (!isValid) { - throw new IllegalArgumentException(errorMessage); - } - } - - /** - * Throws an {@link IllegalStateException} if the argument is false. This method is - * similar to {@code Preconditions.checkState(boolean, Object)} from Guava. - * @param isValid whether the state check passed. - * @param errorMessage the message to use for the exception. - */ - static void checkState(boolean isValid, String errorMessage) { - if (!isValid) { - throw new IllegalStateException(String.valueOf(errorMessage)); - } - } - -} - /** * Taken from OpenTelemetry API. */ @@ -469,131 +435,7 @@ final class TraceFlags { /** Extract the byte representation of the flags from a hex-representation. */ static byte byteFromHex(CharSequence src, int srcOffset) { - return BigendianEncoding.byteFromBase16String(src, srcOffset); - } - -} - -/** - * Taken from OpenTelemetry API. - */ -final class BigendianEncoding { - - private BigendianEncoding() { - } - - static final int LONG_BYTES = Long.SIZE / Byte.SIZE; - - static final int BYTE_BASE16 = 2; - - static final int LONG_BASE16 = BYTE_BASE16 * LONG_BYTES; - - private static final String ALPHABET = "0123456789abcdef"; - - private static final int ASCII_CHARACTERS = 128; - - private static final char[] ENCODING = buildEncodingArray(); - - private static final byte[] DECODING = buildDecodingArray(); - - private static char[] buildEncodingArray() { - char[] encoding = new char[512]; - for (int i = 0; i < 256; ++i) { - encoding[i] = ALPHABET.charAt(i >>> 4); - encoding[i | 0x100] = ALPHABET.charAt(i & 0xF); - } - return encoding; - } - - private static byte[] buildDecodingArray() { - byte[] decoding = new byte[ASCII_CHARACTERS]; - Arrays.fill(decoding, (byte) -1); - for (int i = 0; i < ALPHABET.length(); i++) { - char c = ALPHABET.charAt(i); - decoding[c] = (byte) i; - } - return decoding; - } - - /** - * Returns the {@code long} value whose base16 representation is stored in the first - * 16 chars of {@code chars} starting from the {@code offset}. - * @param chars the base16 representation of the {@code long}. - */ - static long longFromBase16String(CharSequence chars) { - return longFromBase16String(chars, 0); - } - - /** - * Returns the {@code long} value whose base16 representation is stored in the first - * 16 chars of {@code chars} starting from the {@code offset}. - * @param chars the base16 representation of the {@code long}. - */ - static long longFromBase16String(CharSequence chars, int offset) { - Utils.checkArgument(chars.length() >= offset + LONG_BASE16, "chars too small"); - return (decodeByte(chars.charAt(offset), chars.charAt(offset + 1)) & 0xFFL) << 56 - | (decodeByte(chars.charAt(offset + 2), chars.charAt(offset + 3)) & 0xFFL) << 48 - | (decodeByte(chars.charAt(offset + 4), chars.charAt(offset + 5)) & 0xFFL) << 40 - | (decodeByte(chars.charAt(offset + 6), chars.charAt(offset + 7)) & 0xFFL) << 32 - | (decodeByte(chars.charAt(offset + 8), chars.charAt(offset + 9)) & 0xFFL) << 24 - | (decodeByte(chars.charAt(offset + 10), chars.charAt(offset + 11)) & 0xFFL) << 16 - | (decodeByte(chars.charAt(offset + 12), chars.charAt(offset + 13)) & 0xFFL) << 8 - | (decodeByte(chars.charAt(offset + 14), chars.charAt(offset + 15)) & 0xFFL); - } - - /** - * Decodes the specified two character sequence, and returns the resulting - * {@code byte}. - * @param chars the character sequence to be decoded. - * @param offset the starting offset in the {@code CharSequence}. - * @return the resulting {@code byte} - * @throws IllegalArgumentException if the input is not a valid encoded string - * according to this encoding. - */ - static byte byteFromBase16String(CharSequence chars, int offset) { - Utils.checkArgument(chars.length() >= offset + 2, "chars too small"); - return decodeByte(chars.charAt(offset), chars.charAt(offset + 1)); - } - - private static byte decodeByte(char hi, char lo) { - Utils.checkArgument(lo < ASCII_CHARACTERS && DECODING[lo] != -1, "invalid character " + lo); - Utils.checkArgument(hi < ASCII_CHARACTERS && DECODING[hi] != -1, "invalid character " + hi); - int decoded = DECODING[hi] << 4 | DECODING[lo]; - return (byte) decoded; - } - - /** - * Returns the {@code long} value whose big-endian representation is stored in the - * first 8 bytes of {@code bytes} starting from the {@code offset}. - * @param bytes the byte array representation of the {@code long}. - * @param offset the starting offset in the byte array. - * @return the {@code long} value whose big-endian representation is given. - * @throws IllegalArgumentException if {@code bytes} has fewer than 8 elements. - */ - static long longFromByteArray(byte[] bytes, int offset) { - Utils.checkArgument(bytes.length >= offset + LONG_BYTES, "array too small"); - return (bytes[offset] & 0xFFL) << 56 | (bytes[offset + 1] & 0xFFL) << 48 | (bytes[offset + 2] & 0xFFL) << 40 - | (bytes[offset + 3] & 0xFFL) << 32 | (bytes[offset + 4] & 0xFFL) << 24 - | (bytes[offset + 5] & 0xFFL) << 16 | (bytes[offset + 6] & 0xFFL) << 8 | (bytes[offset + 7] & 0xFFL); - } - - static boolean isValidBase16String(CharSequence value) { - for (int i = 0; i < value.length(); i++) { - char b = value.charAt(i); - // 48..57 && 97..102 are valid - if (!isDigit(b) && !isLowercaseHexCharacter(b)) { - return false; - } - } - return true; - } - - private static boolean isLowercaseHexCharacter(char b) { - return 97 <= b && b <= 102; - } - - private static boolean isDigit(char b) { - return 48 <= b && b <= 57; + return EncodingUtils.byteFromBase16String(src, srcOffset); } } diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/grpc/GrpcManagedChannelBuilderCustomizer.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/grpc/GrpcManagedChannelBuilderCustomizer.java index c9cae1265..0dfc6323d 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/grpc/GrpcManagedChannelBuilderCustomizer.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/grpc/GrpcManagedChannelBuilderCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/grpc/SpringAwareManagedChannelBuilder.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/grpc/SpringAwareManagedChannelBuilder.java index ff568262a..cadbde181 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/grpc/SpringAwareManagedChannelBuilder.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/grpc/SpringAwareManagedChannelBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/grpc/TracingManagedChannelBuilderCustomizer.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/grpc/TracingManagedChannelBuilderCustomizer.java index 33956d849..81364855c 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/grpc/TracingManagedChannelBuilderCustomizer.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/grpc/TracingManagedChannelBuilderCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/ConditionalOnMessagingEnabled.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/ConditionalOnMessagingEnabled.java index acfb3e2d4..db83d4869 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/ConditionalOnMessagingEnabled.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/ConditionalOnMessagingEnabled.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/ConsumerSampler.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/ConsumerSampler.java index b86c7c3b0..3ae8e3c6f 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/ConsumerSampler.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/ConsumerSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/KafkaFactoryBeanPostProcessor.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/KafkaFactoryBeanPostProcessor.java index 12f6cb1e9..11e67aa75 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/KafkaFactoryBeanPostProcessor.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/KafkaFactoryBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/MessageListenerMethodInterceptor.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/MessageListenerMethodInterceptor.java index cf22aed8f..7e9ff996b 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/MessageListenerMethodInterceptor.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/MessageListenerMethodInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/ProducerSampler.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/ProducerSampler.java index c00948986..14a28d8da 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/ProducerSampler.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/ProducerSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/SleuthKafkaAspect.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/SleuthKafkaAspect.java index 6a7da2c96..8c084dc25 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/SleuthKafkaAspect.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/SleuthKafkaAspect.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -64,6 +64,10 @@ public class SleuthKafkaAspect { private void anyProducerFactory() { } // NOSONAR + @Pointcut("execution(public * org.springframework.kafka.core.ProducerFactory.createNonTransactionalProducer(..))") + private void anyNonTransactionalProducerFactory() { + } // NOSONAR + @Pointcut("execution(public * org.springframework.kafka.core.ConsumerFactory.createConsumer(..))") private void anyConsumerFactory() { } // NOSONAR @@ -76,7 +80,7 @@ public class SleuthKafkaAspect { private void anyCreateContainer() { } // NOSONAR - @Around("anyProducerFactory()") + @Around("anyProducerFactory() || anyNonTransactionalProducerFactory()") public Object wrapProducerFactory(ProceedingJoinPoint pjp) throws Throwable { Producer producer = (Producer) pjp.proceed(); return this.kafkaTracing.producer(producer); diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/SleuthRabbitBeanPostProcessor.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/SleuthRabbitBeanPostProcessor.java index 88c24141e..284d7f25b 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/SleuthRabbitBeanPostProcessor.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/SleuthRabbitBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TraceConsumerPostProcessor.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TraceConsumerPostProcessor.java index 27c676823..3375b568f 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TraceConsumerPostProcessor.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TraceConsumerPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TraceProducerPostProcessor.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TraceProducerPostProcessor.java index efcc83304..52f4a95ac 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TraceProducerPostProcessor.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TraceProducerPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingConnectionFactoryBeanPostProcessor.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingConnectionFactoryBeanPostProcessor.java index 545ea7053..132dea7b1 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingConnectionFactoryBeanPostProcessor.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingConnectionFactoryBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingJmsBeanPostProcessor.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingJmsBeanPostProcessor.java index a2820f8b1..2cd230168 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingJmsBeanPostProcessor.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingJmsBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/mongodb/TraceMongoClientSettingsBuilderCustomizer.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/mongodb/TraceMongoClientSettingsBuilderCustomizer.java index 87d275bae..6dcd24d06 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/mongodb/TraceMongoClientSettingsBuilderCustomizer.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/mongodb/TraceMongoClientSettingsBuilderCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/rpc/RpcClientSampler.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/rpc/RpcClientSampler.java index 905669c59..af7fb6c4d 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/rpc/RpcClientSampler.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/rpc/RpcClientSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/rpc/RpcServerSampler.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/rpc/RpcServerSampler.java index e9c58e678..1db5cf3c9 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/rpc/RpcServerSampler.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/rpc/RpcServerSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetriever.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetriever.java new file mode 100644 index 000000000..a2107fcd3 --- /dev/null +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetriever.java @@ -0,0 +1,61 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.web; + +import brave.Tracer; +import brave.propagation.CurrentTraceContext; +import brave.propagation.TraceContext; +import reactor.util.context.Context; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.brave.bridge.BraveSpan; +import org.springframework.cloud.sleuth.instrument.web.SpanFromContextRetriever; + +/** + * Retrieves Brave specific classes from Reactor context. + * + * @author Marcin Grzejszczak + * @since 3.0.2 + */ +public class BraveSpanFromContextRetriever implements SpanFromContextRetriever { + + private final CurrentTraceContext currentTraceContext; + + private final Tracer tracer; + + public BraveSpanFromContextRetriever(CurrentTraceContext currentTraceContext, Tracer tracer) { + this.currentTraceContext = currentTraceContext; + this.tracer = tracer; + } + + @Override + public Span findSpan(Context context) { + Object braveSpan = context.getOrDefault(brave.Span.class, null); + if (braveSpan != null) { + return BraveSpan.fromBrave((brave.Span) braveSpan); + } + Object braveContext = context.getOrDefault(TraceContext.class, null); + if (braveContext != null) { + TraceContext traceContext = (TraceContext) braveContext; + try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(traceContext)) { + return BraveSpan.fromBrave(this.tracer.currentSpan()); + } + } + return null; + } + +} diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/CompositeHttpSampler.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/CompositeHttpSampler.java index c93a6095d..358b0bb66 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/CompositeHttpSampler.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/CompositeHttpSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/ServletUtils.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/ServletUtils.java index 4746a0743..963b20284 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/ServletUtils.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/ServletUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipPatternHttpClientSampler.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipPatternHttpClientSampler.java index cd7649615..6be04ed40 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipPatternHttpClientSampler.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipPatternHttpClientSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipPatternHttpServerSampler.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipPatternHttpServerSampler.java index 29fac88c4..17c77d04d 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipPatternHttpServerSampler.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipPatternHttpServerSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipPatternSampler.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipPatternSampler.java index 68b4e3313..1aec8fc78 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipPatternSampler.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipPatternSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/propagation/PropagationFactorySupplier.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/propagation/PropagationFactorySupplier.java index fe7755277..802e1ea71 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/propagation/PropagationFactorySupplier.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/propagation/PropagationFactorySupplier.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/propagation/PropagationType.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/propagation/PropagationType.java index 33dc21b6a..ffc744e8c 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/propagation/PropagationType.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/propagation/PropagationType.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/sampler/ProbabilityBasedSampler.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/sampler/ProbabilityBasedSampler.java index 27a16fd60..f2cd99cfc 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/sampler/ProbabilityBasedSampler.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/sampler/ProbabilityBasedSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/sampler/RateLimitingSampler.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/sampler/RateLimitingSampler.java index aa7335ce4..6bd9e1bdd 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/sampler/RateLimitingSampler.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/sampler/RateLimitingSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/jms/config/TracingJmsListenerEndpointRegistry.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/jms/config/TracingJmsListenerEndpointRegistry.java index cd13b82b9..292324507 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/jms/config/TracingJmsListenerEndpointRegistry.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/jms/config/TracingJmsListenerEndpointRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/ArchitectureTests.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/ArchitectureTests.java index 434c404af..53b9421e7 100644 --- a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/ArchitectureTests.java +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/ArchitectureTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java index 8949528cd..bc7514b08 100644 --- a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpClientHandlerTests.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpClientHandlerTests.java index f7adeb607..21004729e 100644 --- a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpClientHandlerTests.java +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/BraveHttpClientHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContextBuilderTests.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContextBuilderTests.java new file mode 100644 index 000000000..570d6e70a --- /dev/null +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContextBuilderTests.java @@ -0,0 +1,54 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.bridge; + +import org.junit.jupiter.api.Test; + +import org.springframework.cloud.sleuth.TraceContext; + +import static org.assertj.core.api.BDDAssertions.then; + +class BraveTraceContextBuilderTests { + + @Test + void should_set_trace_context_for_64_bit() { + BraveTraceContextBuilder builder = new BraveTraceContextBuilder(); + + TraceContext traceContext = builder.parentId("7c6239a5ad0a4287").spanId("caff89f7f0f229dd") + .traceId("596e1787feb11040").sampled(true).build(); + + then(traceContext.parentId()).isEqualTo("7c6239a5ad0a4287"); + then(traceContext.spanId()).isEqualTo("caff89f7f0f229dd"); + then(traceContext.traceId()).isEqualTo("596e1787feb11040"); + then(traceContext.sampled()).isTrue(); + } + + @Test + void should_set_trace_context_for_128_bit() { + BraveTraceContextBuilder builder = new BraveTraceContextBuilder(); + + TraceContext traceContext = builder.parentId("00000000000000007c6239a5ad0a4287") + .spanId("0000000000000000caff89f7f0f229dd").traceId("596e1787feb11040caff89f7f0f229dd").sampled(true) + .build(); + + then(traceContext.parentId()).isEqualTo("7c6239a5ad0a4287"); + then(traceContext.spanId()).isEqualTo("caff89f7f0f229dd"); + then(traceContext.traceId()).isEqualTo("596e1787feb11040caff89f7f0f229dd"); + then(traceContext.sampled()).isTrue(); + } + +} diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplierTests.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplierTests.java new file mode 100644 index 000000000..236bf90d7 --- /dev/null +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplierTests.java @@ -0,0 +1,120 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.bridge; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import brave.internal.codec.HexCodec; +import brave.internal.propagation.StringPropagationAdapter; +import brave.propagation.Propagation; +import brave.propagation.TraceContext; +import brave.propagation.TraceContextOrSamplingFlags; +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.cloud.loadbalancer.support.SimpleObjectProvider; +import org.springframework.cloud.sleuth.brave.propagation.PropagationType; +import org.springframework.util.StringUtils; + +class CompositePropagationFactorySupplierTests { + + @Test + void should_pick_custom_registered_propagation_when_custom_mode_picked() { + BeanFactory beanFactory = Mockito.mock(BeanFactory.class); + Mockito.when(beanFactory.getBeanProvider(BraveBaggageManager.class)) + .thenReturn(new SimpleObjectProvider(new BraveBaggageManager())); + Mockito.when(beanFactory.getBeanProvider(Propagation.Factory.class)) + .thenReturn(new SimpleObjectProvider(new CustomTracePropagation())); + Mockito.when(beanFactory.getBeanProvider(Propagation.class)) + .thenReturn(new SimpleObjectProvider(new CustomTracePropagation())); + + CompositePropagationFactorySupplier supplier = new CompositePropagationFactorySupplier(beanFactory, + Collections.emptyList(), Collections.singletonList(PropagationType.CUSTOM)); + + BDDAssertions.then(supplier.get().get().keys()).containsExactly(CustomTraceExtractor.CUSTOM_TRACE_HEADER); + } + +} + +class CustomTracePropagation extends Propagation.Factory implements Propagation { + + public static final List KEYS = Collections.singletonList(CustomTraceExtractor.CUSTOM_TRACE_HEADER); + + @Override + public List keys() { + return KEYS; + } + + @Override + public TraceContext.Injector injector(Setter setter) { + return (traceContext, request) -> { + String trace = traceContext.traceIdString() + ":" + traceContext.spanIdString(); + setter.put(request, CustomTraceExtractor.CUSTOM_TRACE_HEADER, trace); + }; + } + + @Override + public TraceContext.Extractor extractor(Getter getter) { + Objects.requireNonNull(getter); + return new CustomTraceExtractor<>(getter); + } + + @Override + public Propagation create(KeyFactory keyFactory) { + return StringPropagationAdapter.create(this, keyFactory); + } + +} + +class CustomTraceExtractor implements TraceContext.Extractor { + + static final String CUSTOM_TRACE_HEADER = "x-custom-trace"; + + final Propagation.Getter getter; + + CustomTraceExtractor(Propagation.Getter getter) { + this.getter = getter; + } + + @Override + @SuppressWarnings("ReturnCount") + public TraceContextOrSamplingFlags extract(R request) { + String traceString = getter.get(request, CUSTOM_TRACE_HEADER); + if (!StringUtils.hasText(traceString)) { + return TraceContextOrSamplingFlags.EMPTY; + } + String[] trace = traceString.split(":"); + if (trace.length != 2) { + return TraceContextOrSamplingFlags.EMPTY; + } + + try { + TraceContext traceContext = TraceContext.newBuilder().traceId(HexCodec.lowerHexToUnsignedLong(trace[0])) + .spanId(HexCodec.lowerHexToUnsignedLong(trace[1])).build(); + + return TraceContextOrSamplingFlags.create(traceContext); + } + catch (NumberFormatException ex) { + return TraceContextOrSamplingFlags.EMPTY; + } + } + +} diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/W3CBaggagePropagatorTest.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/W3CBaggagePropagatorTest.java index 5ae82de49..ed5887c58 100644 --- a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/W3CBaggagePropagatorTest.java +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/W3CBaggagePropagatorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/W3CPropagationTest.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/W3CPropagationTest.java index 1fb49f49e..7d56613da 100644 --- a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/W3CPropagationTest.java +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/W3CPropagationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -27,6 +27,8 @@ import brave.propagation.TraceContext; import brave.propagation.TraceContextOrSamplingFlags; import org.junit.jupiter.api.Test; +import org.springframework.cloud.sleuth.internal.EncodingUtils; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; import static org.springframework.cloud.sleuth.brave.bridge.W3CPropagation.TRACE_PARENT; @@ -68,9 +70,9 @@ class W3CPropagationTest { private TraceContext.Builder sampledTraceContext(String traceIdHigh, String traceId, String spanId) { return TraceContext.newBuilder().sampled(SAMPLED_TRACE_OPTIONS) - .traceIdHigh(BigendianEncoding.longFromBase16String(traceIdHigh)) - .traceId(BigendianEncoding.longFromBase16String(traceId)) - .spanId(BigendianEncoding.longFromBase16String(spanId)); + .traceIdHigh(EncodingUtils.longFromBase16String(traceIdHigh)) + .traceId(EncodingUtils.longFromBase16String(traceId)) + .spanId(EncodingUtils.longFromBase16String(spanId)); } @Test diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/KafkaFactoryBeanPostProcessorTests.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/KafkaFactoryBeanPostProcessorTests.java index 368b07d45..234c54cef 100644 --- a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/KafkaFactoryBeanPostProcessorTests.java +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/KafkaFactoryBeanPostProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetrieverTests.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetrieverTests.java new file mode 100644 index 000000000..5a5eea915 --- /dev/null +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetrieverTests.java @@ -0,0 +1,64 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.web; + +import brave.Span; +import brave.Tracing; +import brave.propagation.StrictCurrentTraceContext; +import brave.propagation.TraceContext; +import brave.sampler.Sampler; +import brave.test.TestSpanHandler; +import org.junit.jupiter.api.Test; +import reactor.util.context.Context; + +import org.springframework.cloud.sleuth.brave.bridge.BraveSpan; + +import static org.assertj.core.api.BDDAssertions.then; + +class BraveSpanFromContextRetrieverTests { + + TestSpanHandler spans = new TestSpanHandler(); + + StrictCurrentTraceContext traceContext = StrictCurrentTraceContext.create(); + + Tracing tracing = Tracing.newBuilder().currentTraceContext(this.traceContext).sampler(Sampler.ALWAYS_SAMPLE) + .addSpanHandler(this.spans).build(); + + brave.Tracer tracer = this.tracing.tracer(); + + BraveSpanFromContextRetriever retriever = new BraveSpanFromContextRetriever(this.traceContext, this.tracer); + + @Test + void should_return_null_when_no_brave_specific_entries_are_present_in_context() { + then(retriever.findSpan(Context.empty())).isNull(); + } + + @Test + void should_return_span_when_brave_span_present_in_context() { + Span span = this.tracer.nextSpan(); + + then(BraveSpan.toBrave(retriever.findSpan(Context.of(Span.class, span)))).isSameAs(span); + } + + @Test + void should_return_span_when_brave_trace_context_present_in_context() { + Span span = this.tracer.nextSpan(); + + then(BraveSpan.toBrave(retriever.findSpan(Context.of(TraceContext.class, span.context())))).isEqualTo(span); + } + +} diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/CompositeHttpSamplerTests.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/CompositeHttpSamplerTests.java index 939b0c785..73aff3704 100644 --- a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/CompositeHttpSamplerTests.java +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/CompositeHttpSamplerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipPatternSamplerTests.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipPatternSamplerTests.java index 951811e06..7c8325332 100644 --- a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipPatternSamplerTests.java +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipPatternSamplerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/sampler/ProbabilityBasedSamplerTests.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/sampler/ProbabilityBasedSamplerTests.java index 8732f3bf5..20131cfd2 100644 --- a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/sampler/ProbabilityBasedSamplerTests.java +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/sampler/ProbabilityBasedSamplerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/internal/LazyBeanTests.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/internal/LazyBeanTests.java index ec32d8298..366366aeb 100644 --- a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/internal/LazyBeanTests.java +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/internal/LazyBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/internal/SpanNameUtilTests.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/internal/SpanNameUtilTests.java index 31597f003..7c97b4614 100644 --- a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/internal/SpanNameUtilTests.java +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/internal/SpanNameUtilTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-dependencies/pom.xml b/spring-cloud-sleuth-dependencies/pom.xml index 78bd736ed..3f2160aa4 100644 --- a/spring-cloud-sleuth-dependencies/pom.xml +++ b/spring-cloud-sleuth-dependencies/pom.xml @@ -22,14 +22,25 @@ spring-cloud-dependencies-parent org.springframework.cloud - 3.0.2-SNAPSHOT + 3.0.2 spring-cloud-sleuth-dependencies - 3.0.2-SNAPSHOT + 3.1.0-SNAPSHOT pom spring-cloud-sleuth-dependencies Spring Cloud Sleuth Dependencies + + + https://github.com/spring-cloud/spring-cloud-sleuth + scm:git:git://github.com/spring-cloud/spring-cloud-sleuth.git + + + scm:git:ssh://git@github.com/spring-cloud/spring-cloud-sleuth.git + + HEAD + + 5.13.2 0.37.4 diff --git a/spring-cloud-sleuth-instrumentation/pom.xml b/spring-cloud-sleuth-instrumentation/pom.xml index 51daaf149..3b2d48a01 100644 --- a/spring-cloud-sleuth-instrumentation/pom.xml +++ b/spring-cloud-sleuth-instrumentation/pom.xml @@ -1,197 +1,234 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-instrumentation - jar - Spring Cloud Sleuth Instrumentation - Spring Cloud Sleuth Instrumentation - - - org.springframework.cloud - spring-cloud-sleuth - 3.0.2-SNAPSHOT - .. - - - - - org.springframework.cloud - spring-cloud-sleuth-api - - - org.springframework.boot - spring-boot-starter-web - true - - - io.micrometer - micrometer-core - true - - - io.projectreactor - reactor-core - true - - - org.reactivestreams - reactive-streams - true - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-actuator - true - - - org.springframework.integration - spring-integration-core - true - - - org.springframework.cloud - spring-cloud-function-context - true - - - org.springframework.boot - spring-boot-starter-websocket - true - - - org.springframework.cloud - spring-cloud-stream - true - - - org.springframework.cloud - spring-cloud-commons - - - org.springframework - spring-context - - - org.springframework.cloud - spring-cloud-context - true - - - io.reactivex - rxjava - true - - - io.github.openfeign - feign-okhttp - true - - - org.springframework.cloud - spring-cloud-starter-openfeign - true - - - org.springframework.cloud - spring-cloud-starter-loadbalancer - true - - - org.springframework.cloud - spring-cloud-starter-gateway - true - - - org.aspectj - aspectjrt - - - - org.springframework.boot - spring-boot-starter-quartz - true - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - org.springframework.security.oauth - spring-security-oauth2 - true - - - org.springframework.security.oauth.boot - spring-security-oauth2-autoconfigure - true - - - - org.springframework.boot - spring-boot-starter-test - test - - - org.awaitility - awaitility - test - - - com.tngtech.archunit - archunit-junit5 - test - - - io.projectreactor - reactor-test - test - - - - - - fast - - false - - - - - maven-surefire-plugin - - 4 - true - -Xmx1024m -XX:MaxPermSize=256m - - - - - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation + jar + Spring Cloud Sleuth Instrumentation + Spring Cloud Sleuth Instrumentation + + + org.springframework.cloud + spring-cloud-sleuth + 3.1.0-SNAPSHOT + .. + + + + + org.springframework.cloud + spring-cloud-sleuth-api + + + org.springframework.boot + spring-boot-starter-web + true + + + org.springframework.boot + spring-boot-starter-rsocket + true + + + io.micrometer + micrometer-core + true + + + io.projectreactor + reactor-core + true + + + io.rsocket + rsocket-core + true + + + io.projectreactor.kafka + reactor-kafka + true + + + org.reactivestreams + reactive-streams + true + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework.boot + spring-boot-starter-actuator + true + + + org.springframework.integration + spring-integration-core + true + + + org.springframework.cloud + spring-cloud-config-server + true + + + org.springframework.cloud + spring-cloud-starter-config + true + + + org.springframework.cloud + spring-cloud-function-context + true + + + org.springframework.boot + spring-boot-starter-websocket + true + + + org.springframework.cloud + spring-cloud-stream + + ${spring-cloud-stream.version} + true + + + org.springframework.cloud + spring-cloud-commons + + + org.springframework + spring-context + + + org.springframework.cloud + spring-cloud-context + true + + + io.reactivex + rxjava + true + + + io.github.openfeign + feign-okhttp + true + + + org.springframework.cloud + spring-cloud-starter-openfeign + true + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + true + + + org.springframework.cloud + spring-cloud-starter-gateway + true + + + org.springframework.cloud + spring-cloud-starter-task + true + + + org.springframework.cloud + spring-cloud-deployer-spi + true + + + org.aspectj + aspectjrt + + + + org.springframework.boot + spring-boot-starter-quartz + true + + + org.springframework.boot + spring-boot-autoconfigure-processor + true + + + org.springframework.security.oauth + spring-security-oauth2 + true + + + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.awaitility + awaitility + test + + + com.tngtech.archunit + archunit-junit5 + test + + + io.projectreactor + reactor-test + test + + + + + + fast + + false + + + + + maven-surefire-plugin + + 4 + true + -Xmx1024m -XX:MaxPermSize=256m + + + + + + + + diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/AbstractSleuthMethodInvocationProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/AbstractSleuthMethodInvocationProcessor.java index d0f8d0f48..f845aafea 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/AbstractSleuthMethodInvocationProcessor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/AbstractSleuthMethodInvocationProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/DefaultSpanCreator.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/DefaultSpanCreator.java index 2fe930486..e499b52ea 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/DefaultSpanCreator.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/DefaultSpanCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/NonReactorSleuthMethodInvocationProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/NonReactorSleuthMethodInvocationProcessor.java index 57efa26a6..f46a0ca56 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/NonReactorSleuthMethodInvocationProcessor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/NonReactorSleuthMethodInvocationProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/ReactorSleuthMethodInvocationProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/ReactorSleuthMethodInvocationProcessor.java index 76c0a34d5..23949b7df 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/ReactorSleuthMethodInvocationProcessor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/ReactorSleuthMethodInvocationProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthAdvisorConfig.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthAdvisorConfig.java index 01c14d8dc..41261ab65 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthAdvisorConfig.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthAdvisorConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthAnnotatedParameter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthAnnotatedParameter.java index 8c8719985..ddb9110d8 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthAnnotatedParameter.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthAnnotatedParameter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthAnnotationUtils.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthAnnotationUtils.java index f27fa77c0..c8bfa97ac 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthAnnotationUtils.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthAnnotationUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SpanTagAnnotationHandler.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SpanTagAnnotationHandler.java index 79a938fb2..2bbbd1c55 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SpanTagAnnotationHandler.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SpanTagAnnotationHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SpelTagValueExpressionResolver.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SpelTagValueExpressionResolver.java index 60e04c3f1..5b648915b 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SpelTagValueExpressionResolver.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SpelTagValueExpressionResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/ExecutorInstrumentor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/ExecutorInstrumentor.java index 08479cf2c..4157fb4fe 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/ExecutorInstrumentor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/ExecutorInstrumentor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncCustomizer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncCustomizer.java index efda3414a..883f3c7c8 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncCustomizer.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncTaskExecutor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncTaskExecutor.java index e18e527ef..4755ceace 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncTaskExecutor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncTaskExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceExecutor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceExecutor.java index db822c899..d7e26471d 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceExecutor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutor.java index c75331036..b8d534f65 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutor.java @@ -66,8 +66,6 @@ class LazyTraceScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { private final Method decorateTaskCallable; - private final Method finalize; - private final Method beforeExecute; private final Method afterExecute; @@ -88,32 +86,66 @@ class LazyTraceScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { this.beanFactory = beanFactory; this.delegate = delegate; this.beanName = beanName; - this.decorateTaskRunnable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "decorateTask", + Method decorateTaskRunnable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "decorateTask", Runnable.class, RunnableScheduledFuture.class); - makeAccessibleIfNotNull(this.decorateTaskRunnable); - this.decorateTaskCallable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "decorateTask", + this.decorateTaskRunnable = makeAccessibleIfNotNullAndOverridden(decorateTaskRunnable); + Method decorateTaskCallable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "decorateTask", Callable.class, RunnableScheduledFuture.class); - makeAccessibleIfNotNull(this.decorateTaskCallable); - this.finalize = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "finalize", null); - makeAccessibleIfNotNull(this.finalize); - this.beforeExecute = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "beforeExecute", null); - makeAccessibleIfNotNull(this.beforeExecute); - this.afterExecute = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "afterExecute", null); - makeAccessibleIfNotNull(this.afterExecute); - this.terminated = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "terminated", null); - makeAccessibleIfNotNull(this.terminated); - this.newTaskForRunnable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "newTaskFor", + this.decorateTaskCallable = makeAccessibleIfNotNullAndOverridden(decorateTaskCallable); + Method beforeExecute = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "beforeExecute", null); + this.beforeExecute = makeAccessibleIfNotNullAndOverridden(beforeExecute); + Method afterExecute = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "afterExecute", null); + this.afterExecute = makeAccessibleIfNotNullAndOverridden(afterExecute); + Method terminated = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "terminated", null); + this.terminated = makeAccessibleIfNotNullAndOverridden(terminated); + Method newTaskForRunnable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "newTaskFor", Runnable.class, Object.class); - makeAccessibleIfNotNull(this.newTaskForRunnable); - this.newTaskForCallable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "newTaskFor", + this.newTaskForRunnable = makeAccessibleIfNotNullAndOverridden(newTaskForRunnable); + Method newTaskForCallable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "newTaskFor", Callable.class); - makeAccessibleIfNotNull(this.newTaskForCallable); + this.newTaskForCallable = makeAccessibleIfNotNullAndOverridden(newTaskForCallable); } - private void makeAccessibleIfNotNull(Method method) { + private Method makeAccessibleIfNotNullAndOverridden(Method method) { if (method != null) { - ReflectionUtils.makeAccessible(method); + if (isMethodOverridden(method)) { + try { + ReflectionUtils.makeAccessible(method); + return method; + } + catch (Throwable ex) { + if (anyCauseIsInaccessibleObjectException(ex)) { + throw new IllegalStateException("The executor [" + this.delegate.getClass() + + "] has overridden a method with name [" + method.getName() + + "] and the object is inaccessible. You have to run your JVM with [--add-opens] switch to allow such access. Example: [--add-opens java.base/java.util.concurrent=ALL-UNNAMED].", + ex); + } + throw ex; + } + } } + return null; + } + + private boolean anyCauseIsInaccessibleObjectException(Throwable t) { + Throwable parent = t; + Throwable cause = t.getCause(); + while (cause != null && cause != parent) { + if (cause.getClass().toString().contains("InaccessibleObjectException")) { + return true; + } + parent = cause; + cause = parent.getCause(); + } + return false; + } + + boolean isMethodOverridden(Method originalMethod) { + Method delegateMethod = ReflectionUtils.findMethod(this.delegate.getClass(), originalMethod.getName()); + if (delegateMethod == null) { + return false; + } + return !delegateMethod.equals(originalMethod); } LazyTraceScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory, @@ -123,26 +155,24 @@ class LazyTraceScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { this.beanFactory = beanFactory; this.delegate = delegate; this.beanName = beanName; - this.decorateTaskRunnable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "decorateTask", + Method decorateTaskRunnable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "decorateTask", Runnable.class, RunnableScheduledFuture.class); - makeAccessibleIfNotNull(this.decorateTaskRunnable); - this.decorateTaskCallable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "decorateTask", + this.decorateTaskRunnable = makeAccessibleIfNotNullAndOverridden(decorateTaskRunnable); + Method decorateTaskCallable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "decorateTask", Callable.class, RunnableScheduledFuture.class); - makeAccessibleIfNotNull(this.decorateTaskCallable); - this.finalize = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "finalize", null); - makeAccessibleIfNotNull(this.finalize); - this.beforeExecute = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "beforeExecute", null); - makeAccessibleIfNotNull(this.beforeExecute); - this.afterExecute = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "afterExecute", null); - makeAccessibleIfNotNull(this.afterExecute); - this.terminated = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "terminated"); - makeAccessibleIfNotNull(this.terminated); - this.newTaskForRunnable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "newTaskFor", + this.decorateTaskCallable = makeAccessibleIfNotNullAndOverridden(decorateTaskCallable); + Method beforeExecute = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "beforeExecute", null); + this.beforeExecute = makeAccessibleIfNotNullAndOverridden(beforeExecute); + Method afterExecute = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "afterExecute", null); + this.afterExecute = makeAccessibleIfNotNullAndOverridden(afterExecute); + Method terminated = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "terminated", null); + this.terminated = makeAccessibleIfNotNullAndOverridden(terminated); + Method newTaskForRunnable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "newTaskFor", Runnable.class, Object.class); - makeAccessibleIfNotNull(this.newTaskForRunnable); - this.newTaskForCallable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "newTaskFor", + this.newTaskForRunnable = makeAccessibleIfNotNullAndOverridden(newTaskForRunnable); + Method newTaskForCallable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "newTaskFor", Callable.class); - makeAccessibleIfNotNull(this.newTaskForCallable); + this.newTaskForCallable = makeAccessibleIfNotNullAndOverridden(newTaskForCallable); } private Runnable traceRunnableWhenContextReady(Runnable delegate) { @@ -166,6 +196,9 @@ class LazyTraceScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { @Override @SuppressWarnings("unchecked") public RunnableScheduledFuture decorateTask(Runnable runnable, RunnableScheduledFuture task) { + if (this.decorateTaskRunnable == null) { + return super.decorateTask(traceRunnableWhenContextReady(runnable), task); + } return (RunnableScheduledFuture) ReflectionUtils.invokeMethod(this.decorateTaskRunnable, this.delegate, traceRunnableWhenContextReady(runnable), task); } @@ -173,6 +206,9 @@ class LazyTraceScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { @Override @SuppressWarnings("unchecked") public RunnableScheduledFuture decorateTask(Callable callable, RunnableScheduledFuture task) { + if (this.decorateTaskCallable == null) { + return super.decorateTask(traceCallableWhenContextReady(callable), task); + } return (RunnableScheduledFuture) ReflectionUtils.invokeMethod(this.decorateTaskCallable, this.delegate, traceCallableWhenContextReady(callable), task); } @@ -358,7 +394,7 @@ class LazyTraceScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { @Override public boolean remove(Runnable task) { - return this.delegate.remove(task); + return this.delegate.remove(traceRunnableWhenContextReady(task)); } @Override @@ -398,22 +434,37 @@ class LazyTraceScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { @Override public void beforeExecute(Thread t, Runnable r) { + if (this.beforeExecute == null) { + super.beforeExecute(t, traceRunnableWhenContextReady(r)); + return; + } ReflectionUtils.invokeMethod(this.beforeExecute, this.delegate, t, traceRunnableWhenContextReady(r)); } @Override public void afterExecute(Runnable r, Throwable t) { + if (this.afterExecute == null) { + super.afterExecute(traceRunnableWhenContextReady(r), t); + return; + } ReflectionUtils.invokeMethod(this.afterExecute, this.delegate, traceRunnableWhenContextReady(r), t); } @Override public void terminated() { + if (this.terminated == null) { + super.terminated(); + return; + } ReflectionUtils.invokeMethod(this.terminated, this.delegate); } @Override @SuppressWarnings("unchecked") public RunnableFuture newTaskFor(Runnable runnable, T value) { + if (this.newTaskForRunnable == null) { + return super.newTaskFor(traceRunnableWhenContextReady(runnable), value); + } return (RunnableFuture) ReflectionUtils.invokeMethod(this.newTaskForRunnable, this.delegate, traceRunnableWhenContextReady(runnable), value); } @@ -421,6 +472,9 @@ class LazyTraceScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { @Override @SuppressWarnings("unchecked") public RunnableFuture newTaskFor(Callable callable) { + if (this.newTaskForRunnable == null) { + return super.newTaskFor(traceCallableWhenContextReady(callable)); + } return (RunnableFuture) ReflectionUtils.invokeMethod(this.newTaskForCallable, this.delegate, traceCallableWhenContextReady(callable)); } diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskExecutor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskExecutor.java index 20f2ee431..0a5ad92ee 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskExecutor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -70,38 +70,32 @@ public class LazyTraceThreadPoolTaskExecutor extends ThreadPoolTaskExecutor { @Override public void execute(Runnable task) { - this.delegate.execute(ContextUtil.isContextUnusable(this.beanFactory) ? task - : new TraceRunnable(tracing(), spanNamer(), task, this.beanName)); + this.delegate.execute(wrap(task)); } @Override public void execute(Runnable task, long startTimeout) { - this.delegate.execute(ContextUtil.isContextUnusable(this.beanFactory) ? task - : new TraceRunnable(tracing(), spanNamer(), task, this.beanName), startTimeout); + this.delegate.execute(wrap(task), startTimeout); } @Override public Future submit(Runnable task) { - return this.delegate.submit(ContextUtil.isContextUnusable(this.beanFactory) ? task - : new TraceRunnable(tracing(), spanNamer(), task, this.beanName)); + return this.delegate.submit(wrap(task)); } @Override public Future submit(Callable task) { - return this.delegate.submit(ContextUtil.isContextUnusable(this.beanFactory) ? task - : new TraceCallable<>(tracing(), spanNamer(), task, this.beanName)); + return this.delegate.submit(wrap(task)); } @Override public ListenableFuture submitListenable(Runnable task) { - return this.delegate.submitListenable(ContextUtil.isContextUnusable(this.beanFactory) ? task - : new TraceRunnable(tracing(), spanNamer(), task, this.beanName)); + return this.delegate.submitListenable(wrap(task)); } @Override public ListenableFuture submitListenable(Callable task) { - return this.delegate.submitListenable(ContextUtil.isContextUnusable(this.beanFactory) ? task - : new TraceCallable<>(tracing(), spanNamer(), task, this.beanName)); + return this.delegate.submitListenable(wrap(task)); } @Override @@ -174,7 +168,23 @@ public class LazyTraceThreadPoolTaskExecutor extends ThreadPoolTaskExecutor { @Override public Thread newThread(Runnable runnable) { - return this.delegate.newThread(runnable); + return this.delegate.newThread(wrap(runnable)); + } + + private Runnable wrap(Runnable runnable) { + if (runnable instanceof TraceRunnable) { + return runnable; + } + return ContextUtil.isContextUnusable(this.beanFactory) ? runnable + : new TraceRunnable(tracer(), spanNamer(), runnable, this.beanName); + } + + private Callable wrap(Callable callable) { + if (callable instanceof TraceCallable) { + return callable; + } + return ContextUtil.isContextUnusable(this.beanFactory) ? callable + : new TraceCallable<>(tracer(), spanNamer(), callable, this.beanName); } @Override @@ -224,7 +234,7 @@ public class LazyTraceThreadPoolTaskExecutor extends ThreadPoolTaskExecutor { @Override public Thread createThread(Runnable runnable) { - return this.delegate.createThread(runnable); + return this.delegate.createThread(wrap(runnable)); } @Override @@ -272,7 +282,7 @@ public class LazyTraceThreadPoolTaskExecutor extends ThreadPoolTaskExecutor { this.delegate.setTaskDecorator(taskDecorator); } - private Tracer tracing() { + private Tracer tracer() { if (this.tracer == null) { this.tracer = this.beanFactory.getBean(Tracer.class); } diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskScheduler.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskScheduler.java index e9f435a54..136ef830a 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskScheduler.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskScheduler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -28,6 +28,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -106,6 +107,9 @@ class LazyTraceThreadPoolTaskScheduler extends ThreadPoolTaskScheduler { if (ContextUtil.isContextUnusable(this.beanFactory)) { return delegate; } + if (delegate instanceof TraceRunnable) { + return delegate; + } return new TraceRunnable(tracing(), spanNamer(), delegate, this.beanName); } @@ -113,6 +117,9 @@ class LazyTraceThreadPoolTaskScheduler extends ThreadPoolTaskScheduler { if (ContextUtil.isContextUnusable(this.beanFactory)) { return delegate; } + if (delegate instanceof TraceCallable) { + return delegate; + } return new TraceCallable<>(tracing(), spanNamer(), delegate, this.beanName); } @@ -135,15 +142,25 @@ class LazyTraceThreadPoolTaskScheduler extends ThreadPoolTaskScheduler { public ExecutorService initializeExecutor(ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) { ExecutorService executorService = (ExecutorService) ReflectionUtils.invokeMethod(this.initializeExecutor, - this.delegate, traceThreadFactory(threadFactory), rejectedExecutionHandler); + this.delegate, traceThreadFactory(threadFactory), + traceRejectedExecutionHandler(rejectedExecutionHandler)); if (executorService instanceof TraceableScheduledExecutorService) { return executorService; } return new TraceableExecutorService(this.beanFactory, executorService, this.beanName); } + private RejectedExecutionHandler traceRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler) { + return new RejectedExecutionHandler() { + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + rejectedExecutionHandler.rejectedExecution(traceRunnableWhenContextReady(r), executor); + } + }; + } + private ThreadFactory traceThreadFactory(ThreadFactory threadFactory) { - return r -> threadFactory.newThread(new TraceRunnable(tracing(), spanNamer(), r, this.beanName)); + return r -> threadFactory.newThread(traceRunnableWhenContextReady(r)); } @Override @@ -151,7 +168,7 @@ class LazyTraceThreadPoolTaskScheduler extends ThreadPoolTaskScheduler { RejectedExecutionHandler rejectedExecutionHandler) { ScheduledExecutorService executorService = (ScheduledExecutorService) ReflectionUtils.invokeMethod( this.createExecutor, this.delegate, poolSize, traceThreadFactory(threadFactory), - rejectedExecutionHandler); + traceRejectedExecutionHandler(rejectedExecutionHandler)); if (executorService instanceof TraceableScheduledExecutorService) { return executorService; } @@ -313,7 +330,7 @@ class LazyTraceThreadPoolTaskScheduler extends ThreadPoolTaskScheduler { @Override public Thread newThread(Runnable runnable) { - return this.delegate.newThread(runnable); + return this.delegate.newThread(traceRunnableWhenContextReady(runnable)); } @Override @@ -359,7 +376,7 @@ class LazyTraceThreadPoolTaskScheduler extends ThreadPoolTaskScheduler { @Override public Thread createThread(Runnable runnable) { - return this.delegate.createThread(runnable); + return this.delegate.createThread(traceRunnableWhenContextReady(runnable)); } @Override diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspect.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspect.java index 78bffe0c4..6be996c8d 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspect.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspect.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -62,6 +62,7 @@ public class TraceAsyncAspect { } span = span.name(spanName); try (Tracer.SpanInScope ws = this.tracer.withSpan(span.start())) { + // TODO: Make this less generic span.tag(CLASS_KEY, pjp.getTarget().getClass().getSimpleName()); span.tag(METHOD_KEY, pjp.getSignature().getName()); return pjp.proceed(); diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncListenableTaskExecutor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncListenableTaskExecutor.java index e807f83ff..fc0cd327d 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncListenableTaskExecutor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncListenableTaskExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceCallable.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceCallable.java index 22d722b37..856968ed6 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceCallable.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceCallable.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnable.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnable.java index 0d5cebb2a..bc093f6de 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnable.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnable.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorService.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorService.java index 781b00a3a..0b36394d2 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorService.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorService.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableScheduledExecutorService.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableScheduledExecutorService.java index 699f44887..abccba742 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableScheduledExecutorService.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableScheduledExecutorService.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceCircuitBreaker.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceCircuitBreaker.java index f4a430356..bd27b24e3 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceCircuitBreaker.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceCircuitBreaker.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceCircuitBreakerFactoryAspect.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceCircuitBreakerFactoryAspect.java index 422571e93..32505fbc7 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceCircuitBreakerFactoryAspect.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceCircuitBreakerFactoryAspect.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2021 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. @@ -19,7 +19,6 @@ package org.springframework.cloud.sleuth.instrument.circuitbreaker; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Pointcut; import org.springframework.cloud.client.circuitbreaker.CircuitBreaker; import org.springframework.cloud.sleuth.Tracer; @@ -39,11 +38,7 @@ public class TraceCircuitBreakerFactoryAspect { this.tracer = tracer; } - @Pointcut("execution(public * org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory.create(..))") - private void anyCircuitBreakerFactoryCreate() { - } // NOSONAR - - @Around("anyCircuitBreakerFactoryCreate()") + @Around("execution(public * org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory.create(..))") public Object wrapFactory(ProceedingJoinPoint pjp) throws Throwable { CircuitBreaker circuitBreaker = (CircuitBreaker) pjp.proceed(); return new TraceCircuitBreaker(circuitBreaker, this.tracer); diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceFunction.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceFunction.java index 89c8d1b61..d5f8f6df8 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceFunction.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2021 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. @@ -44,6 +44,7 @@ class TraceFunction implements Function { @Override public T apply(Throwable throwable) { + // TODO: This name needs to be better String name = this.delegate.getClass().getSimpleName(); Span span = this.span.get().name(name); Throwable tr = null; diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreaker.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreaker.java new file mode 100644 index 000000000..ecf8cce3c --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreaker.java @@ -0,0 +1,75 @@ +/* + * Copyright 2018-2021 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 + * + * https://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.circuitbreaker; + +import java.util.function.Function; +import java.util.function.Supplier; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker; +import org.springframework.cloud.sleuth.CurrentTraceContext; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.instrument.reactor.ReactorSleuth; + +class TraceReactiveCircuitBreaker implements ReactiveCircuitBreaker { + + private final ReactiveCircuitBreaker delegate; + + private final Tracer tracer; + + private final CurrentTraceContext currentTraceContext; + + TraceReactiveCircuitBreaker(ReactiveCircuitBreaker delegate, Tracer tracer, + CurrentTraceContext currentTraceContext) { + this.delegate = delegate; + this.tracer = tracer; + this.currentTraceContext = currentTraceContext; + } + + @Override + public Mono run(Mono toRun) { + return runAndTraceMono(() -> this.delegate.run(toRun)); + } + + @Override + public Mono run(Mono toRun, Function> fallback) { + return runAndTraceMono( + () -> this.delegate.run(toRun, fallback != null ? new TraceFunction<>(this.tracer, fallback) : null)); + } + + @Override + public Flux run(Flux toRun) { + return runAndTraceFlux(() -> this.delegate.run(toRun)); + } + + @Override + public Flux run(Flux toRun, Function> fallback) { + return runAndTraceFlux( + () -> this.delegate.run(toRun, fallback != null ? new TraceFunction<>(this.tracer, fallback) : null)); + } + + private Mono runAndTraceMono(Supplier> mono) { + return ReactorSleuth.tracedMono(this.tracer, this.currentTraceContext, "function", mono); + } + + private Flux runAndTraceFlux(Supplier> flux) { + return ReactorSleuth.tracedFlux(this.tracer, this.currentTraceContext, "function", flux); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreakerFactoryAspect.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreakerFactoryAspect.java new file mode 100644 index 000000000..ea2d99f1e --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreakerFactoryAspect.java @@ -0,0 +1,45 @@ +/* + * Copyright 2018-2021 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 + * + * https://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.circuitbreaker; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; + +import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker; +import org.springframework.cloud.sleuth.CurrentTraceContext; +import org.springframework.cloud.sleuth.Tracer; + +@Aspect +public class TraceReactiveCircuitBreakerFactoryAspect { + + private final Tracer tracer; + + private final CurrentTraceContext currentTraceContext; + + public TraceReactiveCircuitBreakerFactoryAspect(Tracer tracer, CurrentTraceContext currentTraceContext) { + this.tracer = tracer; + this.currentTraceContext = currentTraceContext; + } + + @Around("execution(public * org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory.create(..))") + public Object wrapFactory(ProceedingJoinPoint pjp) throws Throwable { + ReactiveCircuitBreaker circuitBreaker = (ReactiveCircuitBreaker) pjp.proceed(); + return new TraceReactiveCircuitBreaker(circuitBreaker, this.tracer, this.currentTraceContext); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceSupplier.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceSupplier.java index cb453ce50..503229151 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceSupplier.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceSupplier.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2021 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. @@ -44,6 +44,7 @@ class TraceSupplier implements Supplier { @Override public T get() { + // TODO: This name needs to be better String name = this.delegate.getClass().getSimpleName(); Span span = this.span.get().name(name); Throwable tr = null; diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/config/TraceEnvironmentRepositoryAspect.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/config/TraceEnvironmentRepositoryAspect.java new file mode 100644 index 000000000..93b420f00 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/config/TraceEnvironmentRepositoryAspect.java @@ -0,0 +1,54 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.config; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; + +/** + * Aspect wrapping resolution of properties. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +@Aspect +public class TraceEnvironmentRepositoryAspect { + + private final Tracer tracer; + + public TraceEnvironmentRepositoryAspect(Tracer tracer) { + this.tracer = tracer; + } + + @Around("execution (* org.springframework.cloud.config.server.environment.EnvironmentRepository.*(..))") + public Object traceFindEnvironment(final ProceedingJoinPoint pjp) throws Throwable { + Span findOneSpan = this.tracer.nextSpan().name("find"); + findOneSpan.tag("config.environment.class", pjp.getTarget().getClass().getName()); + findOneSpan.tag("config.environment.method", pjp.getSignature().getName()); + try (Tracer.SpanInScope ws = this.tracer.withSpan(findOneSpan.start())) { + return pjp.proceed(); + } + finally { + findOneSpan.end(); + } + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployer.java new file mode 100644 index 000000000..b4f2febe5 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployer.java @@ -0,0 +1,268 @@ +/* + * Copyright 2018-2021 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 + * + * https://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.deployer; + +import java.time.Duration; +import java.util.Arrays; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.cloud.deployer.spi.app.AppDeployer; +import org.springframework.cloud.deployer.spi.app.AppScaleRequest; +import org.springframework.cloud.deployer.spi.app.AppStatus; +import org.springframework.cloud.deployer.spi.app.DeploymentState; +import org.springframework.cloud.deployer.spi.core.AppDeploymentRequest; +import org.springframework.cloud.deployer.spi.core.RuntimeEnvironmentInfo; +import org.springframework.cloud.sleuth.CurrentTraceContext; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.instrument.reactor.ReactorSleuth; +import org.springframework.core.env.Environment; + +/** + * Trace representation of an {@link AppDeployer}. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class TraceAppDeployer implements AppDeployer { + + private static final Log log = LogFactory.getLog(TraceAppDeployer.class); + + private final AppDeployer delegate; + + private final BeanFactory beanFactory; + + private final Environment environment; + + private Tracer tracer; + + private CurrentTraceContext currentTraceContext; + + private Long pollDelay; + + public TraceAppDeployer(AppDeployer delegate, BeanFactory beanFactory, Environment environment) { + this.delegate = delegate; + this.beanFactory = beanFactory; + this.environment = environment; + } + + @Override + public String deploy(AppDeploymentRequest request) { + Span span = tracer().nextSpan().name("deploy"); + // TODO: Is this secure to pass? + // TODO: Does it make sense? + // if (!request.getCommandlineArguments().isEmpty()) { + // span.tag("commandlineArguments", request.getCommandlineArguments().toString()); + // } + // if (!request.getDeploymentProperties().isEmpty()) { + // span.tag("deploymentProperties", request.getDeploymentProperties().toString()); + // } + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + span.event("start"); + String id = this.delegate.deploy(request); + span.tag("deployer.app.id", id); + registerListener(span, id); + return id; + } + } + + private void registerListener(Span span, String id) { + PreviousAndCurrentStatus previousAndCurrentStatus = new PreviousAndCurrentStatus(span); + // @formatter:off + this.delegate.statusReactive(id) + .map(previousAndCurrentStatus::updateCurrent) + .repeatWhen(repeat -> repeat.flatMap(i -> Mono.delay(Duration.ofMillis(pollDelay())))) + .takeUntil(PreviousAndCurrentStatus::isFinished) + .last() + .doOnNext(PreviousAndCurrentStatus::annotateSpan) + .doOnError(span::error) + // we will close the span in the reactive part + .doFinally(signalType -> span.end()).subscribe(); + // @formatter:on + } + + @Override + public void undeploy(String id) { + Span span = tracer().nextSpan().name("undeploy"); + span.tag("deployer.app.id", id); + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + span.event("start"); + this.delegate.undeploy(id); + registerListener(span, id); + } + finally { + span.end(); + } + } + + @Override + public AppStatus status(String id) { + Span span = tracer().nextSpan().name("status"); + span.tag("deployer.app.id", id); + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + return this.delegate.status(id); + } + finally { + span.end(); + } + } + + @Override + public Mono statusReactive(String id) { + return ReactorSleuth.tracedMono(tracer(), currentTraceContext(), "status", + () -> this.delegate.statusReactive(id), span -> span.tag("deployer.app.id", id)); + } + + @Override + public Flux statusesReactive(String... ids) { + return ReactorSleuth.tracedFlux(tracer(), currentTraceContext(), "statuses", + () -> this.delegate.statusesReactive(ids), span -> span.tag("deployer.app.ids", Arrays.toString(ids))); + } + + @Override + public RuntimeEnvironmentInfo environmentInfo() { + return this.delegate.environmentInfo(); + } + + @Override + public String getLog(String id) { + Span span = tracer().nextSpan().name("getLog"); + span.tag("deployer.app.id", id); + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + return this.delegate.getLog(id); + } + finally { + span.end(); + } + } + + @Override + public void scale(AppScaleRequest appScaleRequest) { + Span span = tracer().nextSpan().name("scale"); + span.tag("deployer.scale.deploymentId", appScaleRequest.getDeploymentId()); + span.tag("deployer.scale.count", String.valueOf(appScaleRequest.getCount())); + // TODO: Is this secure to pass? + // TODO: Does it make sense? + // if (appScaleRequest.getProperties().isPresent() && + // !appScaleRequest.getProperties().get().isEmpty()) { + // span.tag("properties", appScaleRequest.getProperties().get().toString()); + // } + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + this.delegate.scale(appScaleRequest); + } + finally { + span.end(); + } + } + + private Tracer tracer() { + if (this.tracer == null) { + this.tracer = this.beanFactory.getBean(Tracer.class); + } + return this.tracer; + } + + private CurrentTraceContext currentTraceContext() { + if (this.currentTraceContext == null) { + this.currentTraceContext = this.beanFactory.getBean(CurrentTraceContext.class); + } + return this.currentTraceContext; + } + + private long pollDelay() { + if (this.pollDelay == null) { + this.pollDelay = this.environment.getProperty("spring.sleuth.deployer.status-poll-delay", Long.class, 500L); + } + return this.pollDelay; + } + + private static final class PreviousAndCurrentStatus { + + private final Span span; + + private AppStatus current; + + private AppStatus previous; + + private PreviousAndCurrentStatus(Span span) { + this.span = span; + if (log.isDebugEnabled()) { + log.debug("Current span is [" + span + "]"); + } + } + + private PreviousAndCurrentStatus updateCurrent(AppStatus current) { + if (log.isTraceEnabled()) { + log.trace("State before change: current [" + this.current + "], previous [" + this.previous + "]"); + } + this.previous = this.current; + this.current = current; + if (log.isTraceEnabled()) { + log.trace("State after change: current [" + this.current + "], previous [" + this.previous + "]"); + } + if (statusChanged()) { + annotateSpan(); + } + else if (log.isTraceEnabled()) { + log.trace("State has not changed, will not annotate the span"); + } + return this; + } + + private void annotateSpan() { + String name = this.current.getState().name(); + if (log.isDebugEnabled()) { + log.debug("Will annotate its state with [" + name + "]"); + } + this.span.event(name); + } + + private boolean statusChanged() { + if (this.previous == null && this.current != null) { + if (log.isDebugEnabled()) { + log.debug("Previous is null, current is not null"); + } + return true; + } + else if (this.current == null) { + throw new IllegalStateException("Current state can't be null"); + } + DeploymentState currentState = this.current.getState(); + DeploymentState previousState = this.previous.getState(); + return currentState != previousState; + } + + private boolean isFinished() { + boolean finished = this.current.getState() == DeploymentState.deployed + || this.current.getState() == DeploymentState.undeployed + || this.current.getState() == DeploymentState.failed + || this.current.getState() == DeploymentState.error + || this.current.getState() == DeploymentState.unknown; + if (log.isTraceEnabled()) { + log.trace("Status is finished [" + finished + "]"); + } + return finished; + } + + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployerBeanPostProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployerBeanPostProcessor.java new file mode 100644 index 000000000..616ba68df --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployerBeanPostProcessor.java @@ -0,0 +1,55 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.deployer; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.cloud.deployer.spi.app.AppDeployer; +import org.springframework.core.env.Environment; + +/** + * {@link BeanPostProcessor} to wrap a {@link AppDeployer} instance into its trace + * representation. + * + * @author Marcin Grzejszczak + * @since 2.0.0 + */ +public class TraceAppDeployerBeanPostProcessor implements BeanPostProcessor { + + private final BeanFactory beanFactory; + + private final Environment environment; + + public TraceAppDeployerBeanPostProcessor(BeanFactory beanFactory, Environment environment) { + this.beanFactory = beanFactory; + this.environment = environment; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) { + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) { + if (bean instanceof AppDeployer && !(bean instanceof TraceAppDeployer)) { + return new TraceAppDeployer((AppDeployer) bean, this.beanFactory, this.environment); + } + return bean; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingCallback.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingCallback.java new file mode 100644 index 000000000..4e8dfd44a --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingCallback.java @@ -0,0 +1,70 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.kafka; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.kafka.clients.producer.Callback; +import org.apache.kafka.clients.producer.RecordMetadata; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; + +/** + * This decorates a Kafka {@link Callback} and completes the {@link Span.Kind#PRODUCER} + * span created for the record when {@code onCompletion()} is invoked (i.e. the broker has + * acknowledged or an {@link Exception}) was thrown. + * + * @author Anders Clausen + * @author Flaviu Muresan + * @since 3.0.3 + */ +public class KafkaTracingCallback implements Callback { + + private static final Log log = LogFactory.getLog(KafkaTracingCallback.class); + + private final Callback callback; + + private final Tracer tracer; + + private final Span span; + + public KafkaTracingCallback(Callback callback, Tracer tracer, Span span) { + this.callback = callback; + this.tracer = tracer; + this.span = span; + } + + @Override + public void onCompletion(RecordMetadata recordMetadata, Exception e) { + try (Tracer.SpanInScope spanInScope = tracer.withSpan(this.span)) { + if (this.callback != null) { + this.callback.onCompletion(recordMetadata, e); + } + } + finally { + if (e != null) { + this.span.error(e); + } + this.span.end(); + if (log.isDebugEnabled()) { + log.debug("Finished producer span " + span); + } + } + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingUtils.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingUtils.java new file mode 100644 index 000000000..3c3b23461 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingUtils.java @@ -0,0 +1,46 @@ +/* + * Copyright 2013-2020 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 + * + * https://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.kafka; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.kafka.clients.consumer.ConsumerRecord; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.propagation.Propagator; + +final class KafkaTracingUtils { + + private static final Log log = LogFactory.getLog(KafkaTracingUtils.class); + + private KafkaTracingUtils() { + } + + static void buildAndFinishSpan(ConsumerRecord consumerRecord, Propagator propagator, + Propagator.Getter> extractor) { + Span.Builder spanBuilder = propagator.extract(consumerRecord, extractor).kind(Span.Kind.CONSUMER) + .name("kafka.consume").tag("kafka.topic", consumerRecord.topic()) + .tag("kafka.offset", Long.toString(consumerRecord.offset())) + .tag("kafka.partition", Integer.toString(consumerRecord.partition())); + Span span = spanBuilder.start(); + if (log.isDebugEnabled()) { + log.debug("Extracted span from event headers " + span); + } + span.end(); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaConsumer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaConsumer.java new file mode 100644 index 000000000..9698f15cd --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaConsumer.java @@ -0,0 +1,314 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.kafka; + +import java.time.Duration; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; + +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.consumer.ConsumerGroupMetadata; +import org.apache.kafka.clients.consumer.ConsumerRebalanceListener; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.OffsetAndMetadata; +import org.apache.kafka.clients.consumer.OffsetAndTimestamp; +import org.apache.kafka.clients.consumer.OffsetCommitCallback; +import org.apache.kafka.common.Metric; +import org.apache.kafka.common.MetricName; +import org.apache.kafka.common.PartitionInfo; +import org.apache.kafka.common.TopicPartition; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.propagation.Propagator; + +/** + * This decorates a Kafka {@link Consumer}. It creates and completes a + * {@link Span.Kind#CONSUMER} span for each record received. This span will be a child + * span of the one extracted from the record headers. + * + * @author Anders Clausen + * @author Flaviu Muresan + * @since 3.0.3 + */ +public class TracingKafkaConsumer implements Consumer { + + private final Consumer delegate; + + private final Propagator propagator; + + private final Propagator.Getter> extractor; + + public TracingKafkaConsumer(Consumer consumer, Propagator propagator, + Propagator.Getter> getter) { + this.delegate = consumer; + this.propagator = propagator; + this.extractor = getter; + } + + @Override + public Set assignment() { + return this.delegate.assignment(); + } + + @Override + public Set subscription() { + return this.delegate.subscription(); + } + + @Override + public void subscribe(Collection collection) { + this.delegate.subscribe(collection); + } + + @Override + public void subscribe(Collection collection, ConsumerRebalanceListener consumerRebalanceListener) { + this.delegate.subscribe(collection, consumerRebalanceListener); + } + + @Override + public void assign(Collection collection) { + this.delegate.assign(collection); + } + + @Override + public void subscribe(Pattern pattern, ConsumerRebalanceListener consumerRebalanceListener) { + this.delegate.subscribe(pattern, consumerRebalanceListener); + } + + @Override + public void subscribe(Pattern pattern) { + this.delegate.subscribe(pattern); + } + + @Override + public void unsubscribe() { + this.delegate.unsubscribe(); + } + + @Deprecated + @Override + public ConsumerRecords poll(long l) { + ConsumerRecords consumerRecords = this.delegate.poll(l); + for (ConsumerRecord consumerRecord : consumerRecords) { + KafkaTracingUtils.buildAndFinishSpan(consumerRecord, this.propagator, this.extractor); + } + return consumerRecords; + } + + @Override + public ConsumerRecords poll(Duration duration) { + ConsumerRecords consumerRecords = this.delegate.poll(duration); + for (ConsumerRecord consumerRecord : consumerRecords) { + KafkaTracingUtils.buildAndFinishSpan(consumerRecord, this.propagator, this.extractor); + } + return consumerRecords; + } + + @Override + public void commitSync() { + this.delegate.commitSync(); + } + + @Override + public void commitSync(Duration duration) { + this.delegate.commitSync(duration); + } + + @Override + public void commitSync(Map map) { + this.delegate.commitSync(map); + } + + @Override + public void commitSync(Map map, Duration duration) { + this.delegate.commitSync(map, duration); + } + + @Override + public void commitAsync() { + this.delegate.commitAsync(); + } + + @Override + public void commitAsync(OffsetCommitCallback offsetCommitCallback) { + this.delegate.commitAsync(offsetCommitCallback); + } + + @Override + public void commitAsync(Map map, OffsetCommitCallback offsetCommitCallback) { + this.delegate.commitAsync(map, offsetCommitCallback); + } + + @Override + public void seek(TopicPartition topicPartition, long l) { + this.delegate.seek(topicPartition, l); + } + + @Override + public void seek(TopicPartition topicPartition, OffsetAndMetadata offsetAndMetadata) { + this.delegate.seek(topicPartition, offsetAndMetadata); + } + + @Override + public void seekToBeginning(Collection collection) { + this.delegate.seekToBeginning(collection); + } + + @Override + public void seekToEnd(Collection collection) { + this.delegate.seekToEnd(collection); + } + + @Override + public long position(TopicPartition topicPartition) { + return this.delegate.position(topicPartition); + } + + @Override + public long position(TopicPartition topicPartition, Duration duration) { + return this.delegate.position(topicPartition, duration); + } + + @Override + @Deprecated + public OffsetAndMetadata committed(TopicPartition topicPartition) { + return this.delegate.committed(topicPartition); + } + + @Override + @Deprecated + public OffsetAndMetadata committed(TopicPartition topicPartition, Duration duration) { + return this.delegate.committed(topicPartition, duration); + } + + @Override + public Map committed(Set set) { + return this.delegate.committed(set); + } + + @Override + public Map committed(Set set, Duration duration) { + return this.delegate.committed(set, duration); + } + + @Override + public Map metrics() { + return this.delegate.metrics(); + } + + @Override + public List partitionsFor(String s) { + return this.delegate.partitionsFor(s); + } + + @Override + public List partitionsFor(String s, Duration duration) { + return this.delegate.partitionsFor(s, duration); + } + + @Override + public Map> listTopics() { + return this.delegate.listTopics(); + } + + @Override + public Map> listTopics(Duration duration) { + return this.delegate.listTopics(duration); + } + + @Override + public Set paused() { + return this.delegate.paused(); + } + + @Override + public void pause(Collection collection) { + this.delegate.pause(collection); + } + + @Override + public void resume(Collection collection) { + this.delegate.resume(collection); + } + + @Override + public Map offsetsForTimes(Map map) { + return this.delegate.offsetsForTimes(map); + } + + @Override + public Map offsetsForTimes(Map map, Duration duration) { + return this.delegate.offsetsForTimes(map, duration); + } + + @Override + public Map beginningOffsets(Collection collection) { + return this.delegate.beginningOffsets(collection); + } + + @Override + public Map beginningOffsets(Collection collection, Duration duration) { + return this.delegate.beginningOffsets(collection, duration); + } + + @Override + public Map endOffsets(Collection collection) { + return this.delegate.endOffsets(collection); + } + + @Override + public Map endOffsets(Collection collection, Duration duration) { + return this.delegate.endOffsets(collection, duration); + } + + @Override + public ConsumerGroupMetadata groupMetadata() { + return this.delegate.groupMetadata(); + } + + @Override + public void enforceRebalance() { + this.delegate.enforceRebalance(); + } + + @Override + public void close() { + this.delegate.close(); + } + + @Override + @Deprecated + public void close(long l, TimeUnit timeUnit) { + this.delegate.close(l, timeUnit); + } + + @Override + public void close(Duration duration) { + this.delegate.close(duration); + } + + @Override + public void wakeup() { + this.delegate.wakeup(); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducer.java new file mode 100644 index 000000000..51d778076 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducer.java @@ -0,0 +1,147 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.kafka; + +import java.time.Duration; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Future; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.kafka.clients.consumer.ConsumerGroupMetadata; +import org.apache.kafka.clients.consumer.OffsetAndMetadata; +import org.apache.kafka.clients.producer.Callback; +import org.apache.kafka.clients.producer.Producer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.clients.producer.RecordMetadata; +import org.apache.kafka.common.Metric; +import org.apache.kafka.common.MetricName; +import org.apache.kafka.common.PartitionInfo; +import org.apache.kafka.common.TopicPartition; +import org.apache.kafka.common.errors.ProducerFencedException; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.propagation.Propagator; + +/** + * This decorates a Kafka {@link Producer} and creates a {@link Span.Kind#PRODUCER} span + * for each record sent. This span is also injected onto each record (via headers) so it + * becomes the parent when a consumer later receives the record. + * + * @author Anders Clausen + * @author Flaviu Muresan + * @since 3.0.3 + */ +public class TracingKafkaProducer implements Producer { + + private static final Log log = LogFactory.getLog(TracingKafkaProducer.class); + + private final Producer delegate; + + private final Tracer tracer; + + private final Propagator propagator; + + private final Propagator.Setter> injector; + + public TracingKafkaProducer(Producer producer, Tracer tracer, Propagator propagator, + Propagator.Setter> setter) { + this.delegate = producer; + this.tracer = tracer; + this.propagator = propagator; + this.injector = setter; + } + + @Override + public void initTransactions() { + this.delegate.initTransactions(); + } + + @Override + public void beginTransaction() throws ProducerFencedException { + this.delegate.beginTransaction(); + } + + @Override + public void sendOffsetsToTransaction(Map map, String s) + throws ProducerFencedException { + this.delegate.sendOffsetsToTransaction(map, s); + } + + @Override + public void sendOffsetsToTransaction(Map map, + ConsumerGroupMetadata consumerGroupMetadata) throws ProducerFencedException { + this.delegate.sendOffsetsToTransaction(map, consumerGroupMetadata); + } + + @Override + public void commitTransaction() throws ProducerFencedException { + this.delegate.commitTransaction(); + } + + @Override + public void abortTransaction() throws ProducerFencedException { + this.delegate.abortTransaction(); + } + + @Override + public Future send(ProducerRecord producerRecord) { + return send(producerRecord, null); + } + + @Override + public Future send(ProducerRecord producerRecord, Callback callback) { + Span.Builder spanBuilder = tracer.spanBuilder().kind(Span.Kind.PRODUCER).name("kafka.produce") + .tag("kafka.topic", producerRecord.topic()); + Span span = spanBuilder.start(); + this.propagator.inject(span.context(), producerRecord, this.injector); + try (Tracer.SpanInScope spanInScope = tracer.withSpan(span)) { + if (log.isDebugEnabled()) { + log.debug("Created producer span " + span); + } + return this.delegate.send(producerRecord, new KafkaTracingCallback(callback, tracer, span)); + } + } + + @Override + public void flush() { + this.delegate.flush(); + } + + @Override + public List partitionsFor(String s) { + return this.delegate.partitionsFor(s); + } + + @Override + public Map metrics() { + return this.delegate.metrics(); + } + + @Override + public void close() { + this.delegate.close(); + } + + @Override + public void close(Duration duration) { + this.delegate.close(duration); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducerFactory.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducerFactory.java new file mode 100644 index 000000000..184df69b7 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducerFactory.java @@ -0,0 +1,54 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.kafka; + +import org.apache.kafka.clients.producer.Producer; +import reactor.kafka.sender.KafkaSender; +import reactor.kafka.sender.SenderOptions; +import reactor.kafka.sender.internals.ProducerFactory; + +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.propagation.Propagator; + +/** + * This decorates a Reactor Kafka {@link ProducerFactory} to create decorated producers of + * type {@link TracingKafkaProducer}. This can be used by the {@link KafkaSender} factory + * methods to create instrumented senders. + * + * @author Anders Clausen + * @author Flaviu Muresan + * @since 3.0.3 + */ +public class TracingKafkaProducerFactory extends ProducerFactory { + + private final Tracer tracer; + + private final Propagator propagator; + + public TracingKafkaProducerFactory(Tracer tracer, Propagator propagator) { + super(); + this.tracer = tracer; + this.propagator = propagator; + } + + @Override + public Producer createProducer(SenderOptions senderOptions) { + return new TracingKafkaProducer<>(super.createProducer(senderOptions), tracer, propagator, + new TracingKafkaPropagatorSetter()); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaPropagatorGetter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaPropagatorGetter.java new file mode 100644 index 000000000..e09988e5c --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaPropagatorGetter.java @@ -0,0 +1,44 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.kafka; + +import java.util.Iterator; +import java.util.Optional; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.common.header.Header; + +import org.springframework.cloud.sleuth.propagation.Propagator; + +/** + * Getter extracting the values from the {@link ConsumerRecord} headers for Kafka based + * communication. + * + * @author Anders Clausen + * @author Flaviu Muresan + * @since 3.0.3 + */ +public class TracingKafkaPropagatorGetter implements Propagator.Getter> { + + @Override + public String get(ConsumerRecord carrier, String key) { + return Optional.ofNullable(carrier).map(ConsumerRecord::headers).map(headers -> headers.headers(key)) + .map(Iterable::iterator).filter(Iterator::hasNext).map(Iterator::next).map(Header::value) + .map(String::new).orElse(null); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaPropagatorSetter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaPropagatorSetter.java new file mode 100644 index 000000000..afdb9b955 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaPropagatorSetter.java @@ -0,0 +1,40 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.kafka; + +import org.apache.kafka.clients.producer.ProducerRecord; + +import org.springframework.cloud.sleuth.propagation.Propagator; + +/** + * Setter injecting the values onto the {@link ProducerRecord} headers for Kafka based + * communication. + * + * @author Anders Clausen + * @author Flaviu Muresan + * @since 3.0.3 + */ +public class TracingKafkaPropagatorSetter implements Propagator.Setter> { + + @Override + public void set(ProducerRecord carrier, String key, String value) { + if (carrier != null) { + carrier.headers().add(key, value.getBytes()); + } + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaReceiver.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaReceiver.java new file mode 100644 index 000000000..f855b5595 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaReceiver.java @@ -0,0 +1,112 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.kafka; + +import java.util.function.Function; + +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.kafka.receiver.KafkaReceiver; +import reactor.kafka.receiver.ReceiverRecord; +import reactor.kafka.sender.TransactionManager; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.propagation.Propagator; + +/** + * This decorates a reactive {@link KafkaReceiver} and creates and completes a + * {@link Span.Kind#CONSUMER} span for each record received. This span will be a child + * span of the one extracted from the record headers. + * + * @author Anders Clausen + * @author Flaviu Muresan + * @since 3.0.3 + */ +public class TracingKafkaReceiver implements KafkaReceiver { + + private final KafkaReceiver delegate; + + private final Propagator propagator; + + private final Propagator.Getter> extractor; + + public TracingKafkaReceiver(KafkaReceiver receiver, Propagator propagator, + Propagator.Getter> getter) { + this.delegate = receiver; + this.propagator = propagator; + this.extractor = getter; + } + + @Override + public Flux> receive(Integer integer) { + return buildAndFinishSpanOnNextReceiverRecord(this.delegate.receive(integer)); + } + + @Override + public Flux> receive() { + return buildAndFinishSpanOnNextReceiverRecord(this.delegate.receive()); + } + + @Override + public Flux>> receiveAutoAck(Integer integer) { + return this.delegate.receiveAutoAck(integer).map(this::buildAndFinishSpanOnNextConsumerRecord); + } + + @Override + public Flux>> receiveAutoAck() { + return this.delegate.receiveAutoAck().map(this::buildAndFinishSpanOnNextConsumerRecord); + } + + @Override + public Flux> receiveAtmostOnce(Integer integer) { + return this.buildAndFinishSpanOnNextConsumerRecord(this.delegate.receiveAtmostOnce(integer)); + } + + @Override + public Flux> receiveAtmostOnce() { + return this.buildAndFinishSpanOnNextConsumerRecord(this.delegate.receiveAtmostOnce()); + } + + @Override + public Flux>> receiveExactlyOnce(TransactionManager transactionManager) { + return this.delegate.receiveExactlyOnce(transactionManager).map(this::buildAndFinishSpanOnNextConsumerRecord); + } + + @Override + public Flux>> receiveExactlyOnce(TransactionManager transactionManager, Integer integer) { + return this.delegate.receiveExactlyOnce(transactionManager, integer) + .map(this::buildAndFinishSpanOnNextConsumerRecord); + } + + @Override + public Mono doOnConsumer(Function, ? extends T> function) { + return this.delegate.doOnConsumer(function); + } + + private Flux> buildAndFinishSpanOnNextConsumerRecord(Flux> flux) { + return flux.doOnNext(consumerRecord -> KafkaTracingUtils.buildAndFinishSpan(consumerRecord, this.propagator, + this.extractor)); + } + + private Flux> buildAndFinishSpanOnNextReceiverRecord(Flux> flux) { + return flux.doOnNext(consumerRecord -> KafkaTracingUtils.buildAndFinishSpan(consumerRecord, this.propagator, + this.extractor)); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/DefaultMessageSpanCustomizer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/DefaultMessageSpanCustomizer.java index b8a178abd..29be5c7e6 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/DefaultMessageSpanCustomizer.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/DefaultMessageSpanCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java index b45a71511..c9726fe60 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -19,6 +19,7 @@ package org.springframework.cloud.sleuth.instrument.messaging; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -60,26 +61,51 @@ public class MessageHeaderPropagatorGetter implements Propagator.Getter> nativeHeadersMap = nativeAccessor.toNativeHeaderMap(); + if (!nativeHeadersMap.isEmpty()) { + return getFromNativeHeaders(nativeHeadersMap, key); } } else { Object nativeHeaders = accessor.getHeader(NativeMessageHeaderAccessor.NATIVE_HEADERS); if (nativeHeaders instanceof Map) { - Object result = ((Map) nativeHeaders).get(key); - if (result instanceof List && !((List) result).isEmpty()) { - return String.valueOf(((List) result).get(0)); + Map nativeHeadersMap = (Map) nativeHeaders; + if (!nativeHeadersMap.isEmpty()) { + return getFromNativeHeaders(nativeHeadersMap, key); } } } - Object result = accessor.getHeader(key); - if (result != null) { - if (result instanceof byte[]) { - return new String((byte[]) result, StandardCharsets.UTF_8); + Set> headerEntries = accessor.getMessageHeaders().entrySet(); + return getFromHeaders(headerEntries, key); + } + + private String getFromHeaders(Set> headerEntries, String key) { + for (Map.Entry entry : headerEntries) { + if (entry.getKey().equalsIgnoreCase(key)) { + Object result = entry.getValue(); + if (result != null) { + if (result instanceof byte[]) { + return new String((byte[]) result, StandardCharsets.UTF_8); + } + return result.toString(); + } + } + } + return null; + } + + private String getFromNativeHeaders(Map nativeHeaders, String key) { + Set entrySet = nativeHeaders.entrySet(); + for (Map.Entry entries : entrySet) { + if (entries.getKey() instanceof String) { + String headersKey = (String) entries.getKey(); + if (headersKey.equalsIgnoreCase(key)) { + Object result = entries.getValue(); + if (result instanceof List && !((List) result).isEmpty()) { + return String.valueOf(((List) result).get(0)); + } + } } - return result.toString(); } return null; } diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorSetter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorSetter.java index 45fdbe1cc..562cb4766 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorSetter.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorSetter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageSpanCustomizer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageSpanCustomizer.java index db761f716..064478148 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageSpanCustomizer.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageSpanCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessagingSleuthOperators.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessagingSleuthOperators.java index 05578a596..8a548b8c8 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessagingSleuthOperators.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessagingSleuthOperators.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapper.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapper.java index 6ce93702c..95ec169f2 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapper.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -37,6 +37,7 @@ import org.springframework.messaging.support.MessageHeaderAccessor; * Trace representation of a {@link FunctionAroundWrapper}. * * @author Marcin Grzejszczak + * @author Oleg Zhurakousky * @since 3.0.0 */ public class TraceFunctionAroundWrapper extends FunctionAroundWrapper @@ -73,7 +74,7 @@ public class TraceFunctionAroundWrapper extends FunctionAroundWrapper log.debug("Will retrieve the tracing headers from the message"); } MessageAndSpans wrappedInputMessage = traceMessageHandler.wrapInputMessage(message, - inputDestination(targetFunction)); + inputDestination(targetFunction.getFunctionDefinition())); if (log.isDebugEnabled()) { log.debug("Wrapped input msg " + wrappedInputMessage); } @@ -97,7 +98,7 @@ public class TraceFunctionAroundWrapper extends FunctionAroundWrapper } Message msgResult = toMessage(result); MessageAndSpan wrappedOutputMessage = traceMessageHandler.wrapOutputMessage(msgResult, - wrappedInputMessage.parentSpan, outputDestination(targetFunction)); + wrappedInputMessage.parentSpan, outputDestination(targetFunction.getFunctionDefinition())); if (log.isDebugEnabled()) { log.debug("Wrapped output msg " + wrappedOutputMessage); } @@ -112,16 +113,22 @@ public class TraceFunctionAroundWrapper extends FunctionAroundWrapper return (Message) result; } - private String inputDestination(SimpleFunctionRegistry.FunctionInvocationWrapper targetFunction) { - String functionDefinition = targetFunction.getFunctionDefinition(); - return this.functionToDestinationCache.computeIfAbsent(functionDefinition, - s -> this.environment.getProperty("spring.cloud.stream.bindings." + s + "-in-0.destination", s)); + String inputDestination(String functionDefinition) { + return this.functionToDestinationCache.computeIfAbsent(functionDefinition, s -> { + String bindingMappingProperty = "spring.cloud.stream.function.bindings." + s + "-in-0"; + String bindingProperty = this.environment.containsProperty(bindingMappingProperty) + ? this.environment.getProperty(bindingMappingProperty) : s + "-in-0"; + return this.environment.getProperty("spring.cloud.stream.bindings." + bindingProperty + ".destination", s); + }); } - private String outputDestination(SimpleFunctionRegistry.FunctionInvocationWrapper targetFunction) { - String functionDefinition = targetFunction.getFunctionDefinition(); - return functionToDestinationCache.computeIfAbsent(functionDefinition, - s -> this.environment.getProperty("spring.cloud.stream.bindings." + s + "-out-0.destination", s)); + String outputDestination(String functionDefinition) { + return this.functionToDestinationCache.computeIfAbsent(functionDefinition, s -> { + String bindingMappingProperty = "spring.cloud.stream.function.bindings." + s + "-out-0"; + String bindingProperty = this.environment.containsProperty(bindingMappingProperty) + ? this.environment.getProperty(bindingMappingProperty) : s + "-out-0"; + return this.environment.getProperty("spring.cloud.stream.bindings." + bindingProperty + ".destination", s); + }); } @Override diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessageHandler.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessageHandler.java index f6d89ae97..52d02ffb3 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessageHandler.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -191,12 +191,6 @@ class TraceMessageHandler { } } - private void addTags(Span result, String destinationName) { - if (StringUtils.hasText(destinationName)) { - result.tag("channel", SpanNameUtil.shorten(destinationName)); - } - } - /** * Called either when message got received and processed or message got sent. * @param span - span that corresponds to the given operation diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAspect.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAspect.java new file mode 100644 index 000000000..a2b262bc0 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAspect.java @@ -0,0 +1,100 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.messaging; + +import java.lang.reflect.Method; + +import org.apache.commons.logging.Log; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanNamer; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.internal.SpanNameUtil; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.util.ReflectionUtils; + +/** + * Aspect that wraps {@link MessageMapping} annotated methods in a tracing representation. + * + * TODO: Document that for client side responders declare them as beans + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +@SuppressWarnings("ArgNamesWarningsInspection") +@Aspect +public class TraceMessagingAspect { + + private static final Log log = org.apache.commons.logging.LogFactory.getLog(TraceMessagingAspect.class); + + static final String MESSAGING_CONTROLLER_CLASS_KEY = "messaging.controller.class"; + + static final String MESSAGING_CONTROLLER_METHOD_KEY = "messaging.controller.method"; + + private final Tracer tracer; + + private final SpanNamer spanNamer; + + public TraceMessagingAspect(Tracer tracer, SpanNamer spanNamer) { + this.tracer = tracer; + this.spanNamer = spanNamer; + } + + @Pointcut("@annotation(org.springframework.messaging.handler.annotation.MessageMapping)") + private void anyMessageMappingAnnotated() { + } // NOSONAR + + @Around("anyMessageMappingAnnotated()") + @SuppressWarnings("unchecked") + public Object addTags(ProceedingJoinPoint pjp) throws Throwable { + Object object = pjp.proceed(); + String methodName = pjp.getSignature().getName(); + String className = pjp.getTarget().getClass().getName(); + Span currentSpan = currentSpan(pjp); + currentSpan.tag(MESSAGING_CONTROLLER_CLASS_KEY, className); + currentSpan.tag(MESSAGING_CONTROLLER_METHOD_KEY, methodName); + return object; + } + + private Span currentSpan(ProceedingJoinPoint pjp) { + Span currentSpan = this.tracer.currentSpan(); + if (currentSpan == null) { + if (log.isDebugEnabled()) { + log.debug("No span found - will create a new one"); + } + currentSpan = this.tracer.nextSpan().name(name(pjp)).start(); + } + return currentSpan; + } + + private String name(ProceedingJoinPoint pjp) { + return this.spanNamer.name(getMethod(pjp, pjp.getTarget()), + SpanNameUtil.toLowerHyphen(pjp.getSignature().getName())); + } + + private Method getMethod(ProceedingJoinPoint pjp, Object object) { + MethodSignature signature = (MethodSignature) pjp.getSignature(); + Method method = signature.getMethod(); + return ReflectionUtils.findMethod(object.getClass(), method.getName(), method.getParameterTypes()); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptor.java index 880a67c38..9ee309081 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -18,8 +18,6 @@ package org.springframework.cloud.sleuth.instrument.messaging; import java.util.Iterator; import java.util.Map; -import java.util.NoSuchElementException; -import java.util.concurrent.LinkedBlockingDeque; import java.util.function.Function; import org.apache.commons.logging.Log; @@ -28,7 +26,9 @@ import org.apache.commons.logging.LogFactory; import org.springframework.aop.support.AopUtils; import org.springframework.beans.BeansException; import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.ThreadLocalSpan; import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.WithThreadLocalSpan; import org.springframework.cloud.sleuth.propagation.Propagator; import org.springframework.cloud.stream.binder.BinderType; import org.springframework.cloud.stream.binder.BinderTypeRegistry; @@ -58,7 +58,7 @@ import org.springframework.util.StringUtils; * @since 3.0.0 */ public final class TracingChannelInterceptor extends ChannelInterceptorAdapter - implements ExecutorChannelInterceptor, ApplicationContextAware { + implements ExecutorChannelInterceptor, ApplicationContextAware, WithThreadLocalSpan { /** * Name of the class in Spring Cloud Stream that is a direct channel. @@ -107,7 +107,7 @@ public final class TracingChannelInterceptor extends ChannelInterceptorAdapter private final Propagator propagator; - private final ThreadLocalSpan threadLocalSpan = new ThreadLocalSpan(); + private final ThreadLocalSpan threadLocalSpan; private final Function remoteServiceNameMapper; @@ -115,6 +115,7 @@ public final class TracingChannelInterceptor extends ChannelInterceptorAdapter Propagator.Setter setter, Propagator.Getter getter, Function remoteServiceNameMapper, MessageSpanCustomizer messageSpanCustomizer) { this.tracer = tracer; + this.threadLocalSpan = new ThreadLocalSpan(tracer); this.propagator = propagator; this.injector = setter; this.extractor = getter; @@ -162,14 +163,6 @@ public final class TracingChannelInterceptor extends ChannelInterceptorAdapter return outputMessage; } - private void setSpanInScope(Span span) { - Tracer.SpanInScope spanInScope = this.tracer.withSpan(span); - this.threadLocalSpan.set(new SpanAndScope(span, spanInScope)); - if (log.isDebugEnabled()) { - log.debug("Put span in scope " + span); - } - } - private String toRemoteServiceName(MessageHeaderAccessor headers) { for (String key : headers.getMessageHeaders().keySet()) { String remoteServiceName = this.remoteServiceNameMapper.apply(key); @@ -357,41 +350,9 @@ public final class TracingChannelInterceptor extends ChannelInterceptorAdapter finishSpan(ex); } - void finishSpan(Exception error) { - SpanAndScope spanAndScope = getSpanFromThreadLocal(); - if (spanAndScope == null) { - return; - } - Span span = spanAndScope.span; - Tracer.SpanInScope scope = spanAndScope.scope; - if (span.isNoop()) { - if (log.isDebugEnabled()) { - log.debug("Span " + span + " is noop - will stope the scope"); - } - scope.close(); - return; - } - if (error != null) { // an error occurred, adding error to span - String message = error.getMessage(); - if (message == null) { - message = error.getClass().getSimpleName(); - } - span.tag("error", message); - } - if (log.isDebugEnabled()) { - log.debug("Will finish the and its corresponding scope " + span); - } - span.end(); - scope.close(); - } - - private SpanAndScope getSpanFromThreadLocal() { - SpanAndScope span = this.threadLocalSpan.get(); - if (log.isDebugEnabled()) { - log.debug("Took span [" + span + "] from thread local"); - } - this.threadLocalSpan.remove(); - return span; + @Override + public ThreadLocalSpan getThreadLocalSpan() { + return this.threadLocalSpan; } private MessageHeaderAccessor mutableHeaderAccessor(Message message) { @@ -424,57 +385,3 @@ public final class TracingChannelInterceptor extends ChannelInterceptorAdapter } } - -class SpanAndScope { - - final Span span; - - final Tracer.SpanInScope scope; - - SpanAndScope(Span span, Tracer.SpanInScope scope) { - this.span = span; - this.scope = scope; - } - -} - -class ThreadLocalSpan { - - private static final Log log = LogFactory.getLog(ThreadLocalSpan.class); - - final ThreadLocal threadLocalSpan = new ThreadLocal<>(); - - final LinkedBlockingDeque spans = new LinkedBlockingDeque<>(); - - void set(SpanAndScope spanAndScope) { - SpanAndScope scope = this.threadLocalSpan.get(); - if (scope != null) { - this.spans.addFirst(scope); - } - this.threadLocalSpan.set(spanAndScope); - } - - SpanAndScope get() { - return this.threadLocalSpan.get(); - } - - void remove() { - this.threadLocalSpan.remove(); - if (this.spans.isEmpty()) { - return; - } - try { - SpanAndScope span = this.spans.removeFirst(); - if (log.isDebugEnabled()) { - log.debug("Took span [" + span + "] from thread local"); - } - this.threadLocalSpan.set(span); - } - catch (NoSuchElementException ex) { - if (log.isTraceEnabled()) { - log.trace("Failed to remove a span from the queue", ex); - } - } - } - -} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListener.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListener.java index dad33a648..81b020901 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListener.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorHooksHelper.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorHooksHelper.java index dd759fbbd..135a4be6d 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorHooksHelper.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorHooksHelper.java @@ -60,13 +60,13 @@ import org.springframework.util.Assert; * .scan((l, r) -> l + r) // (-) * .doOnNext(it -> { // (-) * //log - * }) + * }) * .doFirst(() -> { // (-) * //log - * }) + * }) * .doFinally(signalType -> { // (-) * //log - * }) + * }) * .subscribeOn(Schedulers.parallel()) //(+) * .subscribe();//(*) * (*) - captures tracing context if it differs from what was captured before at subscription and propagates it. @@ -84,7 +84,7 @@ import org.springframework.util.Assert; * .map(it -> ...) // (+) is SYNC but should add hook as previous Processor/operator does not use hooks * .doOnNext(it -> { // (-) is SYNC no need to wrap * //log - * }) + * }) * .subscribe(); *} */ @@ -93,6 +93,7 @@ final class ReactorHooksHelper { // need a way to determine SYNC sources to not add redundant scope passing decorator // most of reactor-core SYNC sources are marked with SourceProducer interface static final Class sourceProducerClass; + static { Class c; try { diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java index cf96f09a7..02d870027 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -17,8 +17,10 @@ package org.springframework.cloud.sleuth.instrument.reactor; import java.util.function.BiFunction; +import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; +import java.util.function.Supplier; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -28,16 +30,20 @@ import org.reactivestreams.Subscription; import reactor.core.CoreSubscriber; import reactor.core.Fuseable; import reactor.core.Scannable; +import reactor.core.publisher.Flux; import reactor.core.publisher.Hooks; +import reactor.core.publisher.Mono; import reactor.core.publisher.Operators; -import reactor.util.annotation.Nullable; import reactor.util.context.Context; import org.springframework.cloud.sleuth.CurrentTraceContext; +import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.TraceContext; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.internal.LazyBean; import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; /** * Reactive Span pointcuts factories. @@ -122,7 +128,7 @@ public abstract class ReactorSleuth { ConfigurableApplicationContext springContext, LazyBean lazyCurrentTraceContext, LazyBean lazyTracer) { return (p, sub) -> { - if (!springContext.isActive()) { + if (!springContext.isActive() || !springContext.isRunning()) { if (log.isTraceEnabled()) { String message = "Spring Context [" + springContext + "] is not yet refreshed. This is unexpected. Reactor Context is [" + context(sub) @@ -314,6 +320,187 @@ public abstract class ReactorSleuth { }; } + /** + * Wraps the given Mono in a trace representation. Retrieves the span from context, + * creates a child span with the given name. + * @param tracer - Tracer bean + * @param currentTraceContext - CurrentTraceContext bean + * @param childSpanName - name of the created child span + * @param supplier - supplier of a {@link Mono} to be wrapped in tracing + * @param - type returned by the Mono + * @param spanCustomizer - customizer for the child span + * @return traced Mono + */ + public static Mono tracedMono(@NonNull Tracer tracer, @NonNull CurrentTraceContext currentTraceContext, + @NonNull String childSpanName, @NonNull Supplier> supplier, + @NonNull Consumer spanCustomizer) { + return runMonoSupplierInScope(supplier, spanCustomizer).contextWrite( + context -> ReactorSleuth.enhanceContext(tracer, currentTraceContext, context, childSpanName)); + } + + private static Mono runMonoSupplierInScope(Supplier> supplier, Consumer spanCustomizer) { + return Mono.deferContextual(contextView -> { + Span span = contextView.get(Span.class); + spanCustomizer.accept(span); + Tracer.SpanInScope scope = contextView.get(Tracer.SpanInScope.class); + // @formatter:off + return supplier.get() + // TODO: Fix me when this is resolved in Reactor +// .doOnSubscribe(__ -> scope.close()) + .doOnError(span::error) + .doFinally(signalType -> { + span.end(); + scope.close(); + }); + // @formatter:on + }); + } + + /** + * Wraps the given Mono in a trace representation. Retrieves the span from context, + * creates a child span with the given name. + * @param tracer - Tracer bean + * @param currentTraceContext - CurrentTraceContext bean + * @param childSpanName - name of the created child span + * @param supplier - supplier of a {@link Mono} to be wrapped in tracing + * @param - type returned by the Mono + * @return traced Mono + */ + public static Mono tracedMono(@NonNull Tracer tracer, @NonNull CurrentTraceContext currentTraceContext, + @NonNull String childSpanName, @NonNull Supplier> supplier) { + return tracedMono(tracer, currentTraceContext, childSpanName, supplier, span -> { + }); + } + + /** + * Wraps the given Mono in a trace representation. Puts the provided span to context. + * @param tracer - Tracer bean + * @param span - span to put in context + * @param supplier - supplier of a {@link Mono} to be wrapped in tracing + * @param - type returned by the Mono + * @return traced Mono + */ + public static Mono tracedMono(@NonNull Tracer tracer, @NonNull Span span, + @NonNull Supplier> supplier) { + return runMonoSupplierInScope(supplier, span1 -> { + }).contextWrite(context -> ReactorSleuth.putSpanInScope(tracer, context, span)); + } + + /** + * Wraps the given Flux in a trace representation. Retrieves the span from context, + * creates a child span with the given name. + * @param tracer - Tracer bean + * @param currentTraceContext - CurrentTraceContext bean + * @param childSpanName - name of the created child span + * @param supplier - supplier of a {@link Flux} to be wrapped in tracing + * @param - type returned by the Flux + * @param spanCustomizer - customizer for the child span + * @return traced Flux + */ + public static Flux tracedFlux(@NonNull Tracer tracer, @NonNull CurrentTraceContext currentTraceContext, + @NonNull String childSpanName, @NonNull Supplier> supplier, + @NonNull Consumer spanCustomizer) { + return runFluxSupplierInScope(supplier, spanCustomizer).contextWrite( + context -> ReactorSleuth.enhanceContext(tracer, currentTraceContext, context, childSpanName)); + } + + /** + * Wraps the given Flux in a trace representation. Retrieves the span from context, + * creates a child span with the given name. + * @param tracer - Tracer bean + * @param span - span to put in context + * @param supplier - supplier of a {@link Flux} to be wrapped in tracing + * @param - type returned by the Flux + * @return traced Flux + */ + public static Flux tracedFlux(@NonNull Tracer tracer, @NonNull Span span, + @NonNull Supplier> supplier) { + return runFluxSupplierInScope(supplier, span1 -> { + }).contextWrite(context -> ReactorSleuth.putSpanInScope(tracer, context, span)); + } + + private static Flux runFluxSupplierInScope(Supplier> supplier, Consumer spanCustomizer) { + return Flux.deferContextual(contextView -> { + Span span = contextView.get(Span.class); + spanCustomizer.accept(span); + Tracer.SpanInScope scope = contextView.get(Tracer.SpanInScope.class); + // @formatter:off + return supplier.get() + // TODO: Fix me when this is resolved in Reactor +// .doOnSubscribe(__ -> scope.close()) + .doOnError(span::error) + .doFinally(signalType -> { + span.end(); + scope.close(); + }); + // @formatter:on + }); + } + + /** + * Wraps the given Flux in a trace representation. Retrieves the span from context, + * creates a child span with the given name. + * @param tracer - Tracer bean + * @param currentTraceContext - CurrentTraceContext bean + * @param childSpanName - name of the created child span + * @param supplier - supplier of a {@link Flux} to be wrapped in tracing + * @param - type returned by the Flux + * @return traced Flux + */ + public static Flux tracedFlux(@NonNull Tracer tracer, @NonNull CurrentTraceContext currentTraceContext, + @NonNull String childSpanName, @NonNull Supplier> supplier) { + return tracedFlux(tracer, currentTraceContext, childSpanName, supplier, span -> { + }); + } + + private static Span spanFromContext(Tracer tracer, CurrentTraceContext currentTraceContext, + reactor.util.context.Context context, String childSpanName) { + TraceContext traceContext = context.getOrDefault(TraceContext.class, null); + Span span = null; + if (traceContext == null) { + span = context.getOrDefault(Span.class, null); + } + if (traceContext == null && span == null) { + span = tracer.nextSpan(); + if (log.isDebugEnabled()) { + log.debug("There was no previous span in reactor context, created a new one [" + span + "]"); + } + } + else if (traceContext != null) { + // there was a previous span - we create a child one + try (CurrentTraceContext.Scope scope = currentTraceContext.maybeScope(traceContext)) { + if (log.isDebugEnabled()) { + log.debug("Found a trace context in reactor context [" + traceContext + "]"); + } + span = tracer.nextSpan(); + if (log.isDebugEnabled()) { + log.debug("Created a child span [" + span + "]"); + } + } + } + else { + if (log.isDebugEnabled()) { + log.debug("Found a span in reactor context [" + span + "]"); + } + span = tracer.nextSpan(span); + if (log.isDebugEnabled()) { + log.debug("Created a child span [" + span + "]"); + } + } + return span.name(childSpanName).start(); + } + + private static Context enhanceContext(Tracer tracer, CurrentTraceContext currentTraceContext, + reactor.util.context.Context context, String childSpanName) { + Span span = spanFromContext(tracer, currentTraceContext, context, childSpanName); + return putSpanInScope(tracer, context, span); + } + + private static Context putSpanInScope(Tracer tracer, Context context, Span span) { + return context.put(Span.class, span).put(TraceContext.class, span.context()).put(Tracer.SpanInScope.class, + tracer.withSpan(span)); + } + } class SleuthContextOperator implements Subscription, CoreSubscriber, Scannable { diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriber.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriber.java index 64a6e19f5..8c62ec0a7 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriber.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriber.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SpanSubscription.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SpanSubscription.java index a546e1ab5..9aef6b59a 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SpanSubscription.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SpanSubscription.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/TraceContextPropagator.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/TraceContextPropagator.java index 8afbd8b9e..029991e18 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/TraceContextPropagator.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/TraceContextPropagator.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/ByteBufGetter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/ByteBufGetter.java new file mode 100644 index 000000000..167af1865 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/ByteBufGetter.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.rsocket; + +import io.netty.buffer.ByteBuf; +import io.netty.util.CharsetUtil; +import io.rsocket.metadata.CompositeMetadata; + +import org.springframework.cloud.sleuth.propagation.Propagator; + +class ByteBufGetter implements Propagator.Getter { + + @Override + public String get(ByteBuf carrier, String key) { + final CompositeMetadata compositeMetadata = new CompositeMetadata(carrier, false); + for (CompositeMetadata.Entry entry : compositeMetadata) { + if (key.equals(entry.getMimeType())) { + return entry.getContent().toString(CharsetUtil.UTF_8); + } + } + return null; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/ByteBufSetter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/ByteBufSetter.java new file mode 100644 index 000000000..e44a77de7 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/ByteBufSetter.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.rsocket; + +import io.netty.buffer.ByteBufAllocator; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.CompositeByteBuf; +import io.rsocket.metadata.CompositeMetadataCodec; + +import org.springframework.cloud.sleuth.propagation.Propagator; + +class ByteBufSetter implements Propagator.Setter { + + @Override + public void set(CompositeByteBuf carrier, String key, String value) { + final ByteBufAllocator alloc = carrier.alloc(); + CompositeMetadataCodec.encodeAndAddMetadataWithCompression(carrier, alloc, key, + ByteBufUtil.writeUtf8(alloc, value)); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/CompositeMetadataUtils.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/CompositeMetadataUtils.java new file mode 100644 index 000000000..5bc960a3e --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/CompositeMetadataUtils.java @@ -0,0 +1,42 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.rsocket; + +import io.netty.buffer.ByteBuf; +import io.rsocket.metadata.CompositeMetadata; + +import org.springframework.lang.Nullable; + +final class CompositeMetadataUtils { + + private CompositeMetadataUtils() { + throw new IllegalStateException("Can't instantiate a utility class"); + } + + @Nullable + static ByteBuf extract(ByteBuf metadata, String key) { + final CompositeMetadata compositeMetadata = new CompositeMetadata(metadata, false); + for (CompositeMetadata.Entry entry : compositeMetadata) { + final String entryKey = entry.getMimeType(); + if (key.equals(entryKey)) { + return entry.getContent(); + } + } + return null; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/PayloadUtils.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/PayloadUtils.java new file mode 100644 index 000000000..17363acc4 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/PayloadUtils.java @@ -0,0 +1,68 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.rsocket; + +import java.util.HashSet; +import java.util.Set; + +import io.netty.buffer.ByteBufAllocator; +import io.netty.buffer.CompositeByteBuf; +import io.rsocket.Payload; +import io.rsocket.metadata.CompositeMetadata; +import io.rsocket.metadata.CompositeMetadata.Entry; +import io.rsocket.metadata.CompositeMetadataCodec; +import io.rsocket.metadata.WellKnownMimeType; +import io.rsocket.util.ByteBufPayload; +import io.rsocket.util.DefaultPayload; + +final class PayloadUtils { + + private PayloadUtils() { + throw new IllegalStateException("Can't instantiate a utility class"); + } + + static Payload cleanTracingMetadata(Payload payload, Set fields) { + Set fieldsWithDefaultZipkin = new HashSet<>(fields); + fieldsWithDefaultZipkin.add(WellKnownMimeType.MESSAGE_RSOCKET_TRACING_ZIPKIN.getString()); + final CompositeMetadata entries = new CompositeMetadata(payload.metadata(), true); + final CompositeByteBuf metadata = ByteBufAllocator.DEFAULT.compositeBuffer(); + for (Entry entry : entries) { + if (!fieldsWithDefaultZipkin.contains(entry.getMimeType())) { + CompositeMetadataCodec.encodeAndAddMetadataWithCompression(metadata, ByteBufAllocator.DEFAULT, + entry.getMimeType(), entry.getContent()); + } + } + return payload(payload, metadata); + } + + private static Payload payload(Payload payload, CompositeByteBuf metadata) { + final Payload newPayload; + try { + if (payload instanceof ByteBufPayload) { + newPayload = ByteBufPayload.create(payload.data().retain(), metadata.retain()); + } + else { + newPayload = DefaultPayload.create(payload.data().retain(), metadata.retain()); + } + } + finally { + payload.release(); + } + return newPayload; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRSocketConnectorConfigurer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRSocketConnectorConfigurer.java new file mode 100644 index 000000000..b172c0640 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRSocketConnectorConfigurer.java @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.rsocket; + +import io.rsocket.core.RSocketConnector; +import io.rsocket.plugins.RSocketInterceptor; + +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.propagation.Propagator; +import org.springframework.messaging.rsocket.RSocketConnectorConfigurer; + +public class TracingRSocketConnectorConfigurer implements RSocketConnectorConfigurer { + + private final Propagator propagator; + + private final Tracer tracer; + + private final boolean isZipkinPropagationEnabled; + + public TracingRSocketConnectorConfigurer(Propagator propagator, Tracer tracer, boolean isZipkinPropagationEnabled) { + this.propagator = propagator; + this.tracer = tracer; + this.isZipkinPropagationEnabled = isZipkinPropagationEnabled; + } + + @Override + public void configure(RSocketConnector rSocketConnector) { + rSocketConnector.interceptors(ir -> ir + .forResponder((RSocketInterceptor) rSocket -> new TracingResponderRSocketProxy(rSocket, this.propagator, + new ByteBufGetter(), this.tracer, this.isZipkinPropagationEnabled)) + .forRequester((RSocketInterceptor) rSocket -> new TracingRequesterRSocketProxy(rSocket, this.propagator, + new ByteBufSetter(), this.tracer, this.isZipkinPropagationEnabled))); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRSocketServerCustomizer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRSocketServerCustomizer.java new file mode 100644 index 000000000..809671eec --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRSocketServerCustomizer.java @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.rsocket; + +import io.rsocket.core.RSocketServer; +import io.rsocket.plugins.RSocketInterceptor; + +import org.springframework.boot.rsocket.server.RSocketServerCustomizer; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.propagation.Propagator; + +public class TracingRSocketServerCustomizer implements RSocketServerCustomizer { + + private final Propagator propagator; + + private final Tracer tracer; + + private final boolean isZipkinPropagationEnabled; + + public TracingRSocketServerCustomizer(Propagator propagator, Tracer tracer, boolean isZipkinPropagationEnabled) { + this.propagator = propagator; + this.tracer = tracer; + this.isZipkinPropagationEnabled = isZipkinPropagationEnabled; + } + + @Override + public void customize(RSocketServer rSocketServer) { + rSocketServer.interceptors(ir -> ir + .forResponder((RSocketInterceptor) rSocket -> new TracingResponderRSocketProxy(rSocket, propagator, + new ByteBufGetter(), this.tracer, this.isZipkinPropagationEnabled)) + .forRequester((RSocketInterceptor) rSocket -> new TracingRequesterRSocketProxy(rSocket, propagator, + new ByteBufSetter(), tracer, isZipkinPropagationEnabled))); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRequesterRSocketProxy.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRequesterRSocketProxy.java new file mode 100644 index 000000000..31d0b9a96 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRequesterRSocketProxy.java @@ -0,0 +1,168 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.rsocket; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.function.Function; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.CompositeByteBuf; +import io.rsocket.Payload; +import io.rsocket.RSocket; +import io.rsocket.frame.FrameType; +import io.rsocket.metadata.RoutingMetadata; +import io.rsocket.metadata.TracingMetadataCodec; +import io.rsocket.metadata.WellKnownMimeType; +import io.rsocket.util.RSocketProxy; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.util.context.ContextView; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.internal.EncodingUtils; +import org.springframework.cloud.sleuth.propagation.Propagator; + +/** + * Tracing representation of a {@link RSocketProxy} for the requester. + * + * @author Marcin Grzejszczak + * @author Oleh Dokuka + * @since 3.1.0 + */ +public class TracingRequesterRSocketProxy extends RSocketProxy { + + private static final Log log = LogFactory.getLog(TracingRequesterRSocketProxy.class); + + private final Propagator propagator; + + private final Propagator.Setter setter; + + private final Tracer tracer; + + private final boolean isZipkinPropagationEnabled; + + public TracingRequesterRSocketProxy(RSocket source, Propagator propagator, + Propagator.Setter setter, Tracer tracer, boolean isZipkinPropagationEnabled) { + super(source); + this.propagator = propagator; + this.setter = setter; + this.tracer = tracer; + this.isZipkinPropagationEnabled = isZipkinPropagationEnabled; + } + + @Override + public Mono fireAndForget(Payload payload) { + return setSpan(super::fireAndForget, payload, FrameType.REQUEST_FNF); + } + + @Override + public Mono requestResponse(Payload payload) { + return setSpan(super::requestResponse, payload, FrameType.REQUEST_RESPONSE); + } + + Mono setSpan(Function> input, Payload payload, FrameType frameType) { + return Mono.deferContextual(contextView -> { + Span.Builder spanBuilder = spanBuilder(contextView); + ByteBuf extracted = CompositeMetadataUtils.extract(payload.sliceMetadata(), + WellKnownMimeType.MESSAGE_RSOCKET_ROUTING.getString()); + // TODO: do sth about extracted == null, log that tracing can't be used or sth + final RoutingMetadata routingMetadata = new RoutingMetadata(extracted); + final Iterator iterator = routingMetadata.iterator(); + String route = iterator.next(); + Span span = spanBuilder.kind(Span.Kind.PRODUCER).name(frameType.name() + " " + route).start(); + span.tag("rsocket.route", route); + span.tag("rsocket.request-type", frameType.name()); + if (log.isDebugEnabled()) { + log.debug("Extracted result from context or thread local " + span); + } + final Payload newPayload = PayloadUtils.cleanTracingMetadata(payload, new HashSet<>(propagator.fields())); + TraceContext traceContext = span.context(); + if (this.isZipkinPropagationEnabled) { + injectDefaultZipkinRSocketHeaders(newPayload, traceContext); + } + this.propagator.inject(traceContext, (CompositeByteBuf) newPayload.metadata(), this.setter); + return input.apply(newPayload).doOnError(span::error).doFinally(signalType -> span.end()); + }); + } + + private void injectDefaultZipkinRSocketHeaders(Payload newPayload, TraceContext traceContext) { + TracingMetadataCodec.Flags flags = traceContext.sampled() == null ? TracingMetadataCodec.Flags.UNDECIDED + : traceContext.sampled() ? TracingMetadataCodec.Flags.SAMPLE : TracingMetadataCodec.Flags.NOT_SAMPLE; + String traceId = traceContext.traceId(); + long[] traceIds = EncodingUtils.fromString(traceId); + long[] spanId = EncodingUtils.fromString(traceContext.spanId()); + long[] parentSpanId = EncodingUtils.fromString(traceContext.parentId()); + boolean isTraceId128Bit = traceIds.length == 2; + if (isTraceId128Bit) { + TracingMetadataCodec.encode128(newPayload.metadata().alloc(), traceIds[0], traceIds[1], spanId[0], + EncodingUtils.fromString(traceContext.parentId())[0], flags); + } + else { + TracingMetadataCodec.encode64(newPayload.metadata().alloc(), traceIds[0], spanId[0], parentSpanId[0], + flags); + } + } + + private Span.Builder spanBuilder(ContextView contextView) { + Span.Builder spanBuilder = this.tracer.spanBuilder(); + if (contextView.hasKey(TraceContext.class)) { + spanBuilder = spanBuilder.setParent(contextView.get(TraceContext.class)); + } + else if (this.tracer.currentSpan() != null) { + spanBuilder = spanBuilder.setParent(this.tracer.currentSpan().context()); + } + return spanBuilder; + } + + @Override + public Flux requestStream(Payload payload) { + return Flux.deferContextual(contextView -> setSpan(super::requestStream, payload, contextView)); + } + + @Override + public Flux requestChannel(Publisher inbound) { + return Flux.from(inbound).switchOnFirst((firstSignal, flux) -> { + final Payload firstPayload = firstSignal.get(); + if (firstPayload != null) { + return setSpan(p -> super.requestChannel(flux.skip(1).startWith(p)), firstPayload, + firstSignal.getContextView()); + } + return flux; + }); + } + + Flux setSpan(Function> input, Payload payload, ContextView contextView) { + Span.Builder spanBuilder = spanBuilder(contextView); + final RoutingMetadata routingMetadata = new RoutingMetadata(CompositeMetadataUtils + .extract(payload.sliceMetadata(), WellKnownMimeType.MESSAGE_RSOCKET_ROUTING.getString())); + final Iterator iterator = routingMetadata.iterator(); + Span span = spanBuilder.kind(Span.Kind.PRODUCER).name(iterator.next()).start(); + if (log.isDebugEnabled()) { + log.debug("Extracted result from context or thread local " + span); + } + final Payload newPayload = PayloadUtils.cleanTracingMetadata(payload, new HashSet<>(propagator.fields())); + this.propagator.inject(span.context(), (CompositeByteBuf) newPayload.metadata(), this.setter); + return input.apply(newPayload).doOnError(span::error).doFinally(signalType -> span.end()); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingResponderRSocketProxy.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingResponderRSocketProxy.java new file mode 100644 index 000000000..b75a4aff9 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingResponderRSocketProxy.java @@ -0,0 +1,170 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.rsocket; + +import java.util.HashSet; +import java.util.Iterator; + +import io.netty.buffer.ByteBuf; +import io.rsocket.Payload; +import io.rsocket.RSocket; +import io.rsocket.frame.FrameType; +import io.rsocket.metadata.RoutingMetadata; +import io.rsocket.metadata.TracingMetadata; +import io.rsocket.metadata.TracingMetadataCodec; +import io.rsocket.metadata.WellKnownMimeType; +import io.rsocket.util.RSocketProxy; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.ThreadLocalSpan; +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.WithThreadLocalSpan; +import org.springframework.cloud.sleuth.instrument.reactor.ReactorSleuth; +import org.springframework.cloud.sleuth.internal.EncodingUtils; +import org.springframework.cloud.sleuth.propagation.Propagator; + +/** + * Tracing representation of a {@link RSocketProxy} for the responder. + * + * @author Marcin Grzejszczak + * @author Oleh Dokuka + * @since 3.1.0 + */ +public class TracingResponderRSocketProxy extends RSocketProxy implements WithThreadLocalSpan { + + private static final Log log = LogFactory.getLog(TracingResponderRSocketProxy.class); + + private final Propagator propagator; + + private final Propagator.Getter getter; + + private final Tracer tracer; + + private final ThreadLocalSpan threadLocalSpan; + + private final boolean isZipkinPropagationEnabled; + + public TracingResponderRSocketProxy(RSocket source, Propagator propagator, Propagator.Getter getter, + Tracer tracer, boolean isZipkinPropagationEnabled) { + super(source); + this.propagator = propagator; + this.getter = getter; + this.tracer = tracer; + this.threadLocalSpan = new ThreadLocalSpan(tracer); + this.isZipkinPropagationEnabled = isZipkinPropagationEnabled; + } + + @Override + public Mono fireAndForget(Payload payload) { + // called on Netty EventLoop + // there can't be trace context in thread local here + Span handle = consumerSpanBuilder(payload.sliceMetadata(), FrameType.REQUEST_FNF); + if (log.isDebugEnabled()) { + log.debug("Created consumer span " + handle); + } + final Payload newPayload = PayloadUtils.cleanTracingMetadata(payload, new HashSet<>(propagator.fields())); + return ReactorSleuth.tracedMono(this.tracer, handle, () -> super.fireAndForget(newPayload)); + } + + @Override + public Mono requestResponse(Payload payload) { + Span handle = consumerSpanBuilder(payload.sliceMetadata(), FrameType.REQUEST_RESPONSE); + if (log.isDebugEnabled()) { + log.debug("Created consumer span " + handle); + } + final Payload newPayload = PayloadUtils.cleanTracingMetadata(payload, new HashSet<>(propagator.fields())); + return ReactorSleuth.tracedMono(this.tracer, handle, () -> super.requestResponse(newPayload)); + } + + @Override + public Flux requestStream(Payload payload) { + Span handle = consumerSpanBuilder(payload.sliceMetadata(), FrameType.REQUEST_STREAM); + if (log.isDebugEnabled()) { + log.debug("Created consumer span " + handle); + } + final Payload newPayload = PayloadUtils.cleanTracingMetadata(payload, new HashSet<>(propagator.fields())); + return ReactorSleuth.tracedFlux(this.tracer, handle, () -> super.requestStream(newPayload)); + } + + @Override + public Flux requestChannel(Publisher payloads) { + return Flux.from(payloads).switchOnFirst((firstSignal, flux) -> { + final Payload firstPayload = firstSignal.get(); + if (firstPayload != null) { + Span handle = consumerSpanBuilder(firstPayload.sliceMetadata(), FrameType.REQUEST_CHANNEL); + if (handle == null) { + return super.requestChannel(flux); + } + if (log.isDebugEnabled()) { + log.debug("Created consumer span " + handle); + } + final Payload newPayload = PayloadUtils.cleanTracingMetadata(firstPayload, + new HashSet<>(propagator.fields())); + return ReactorSleuth.tracedFlux(this.tracer, handle, + () -> super.requestChannel(flux.skip(1).startWith(newPayload))); + } + return flux; + }); + } + + private Span consumerSpanBuilder(ByteBuf headers, FrameType requestType) { + Span.Builder consumerSpanBuilder = consumerSpanBuilder(headers); + if (log.isDebugEnabled()) { + log.debug("Extracted result from headers " + consumerSpanBuilder); + } + final ByteBuf extract = CompositeMetadataUtils.extract(headers, + WellKnownMimeType.MESSAGE_RSOCKET_ROUTING.getString()); + String name = "handle"; + if (extract != null) { + final RoutingMetadata routingMetadata = new RoutingMetadata(extract); + final Iterator iterator = routingMetadata.iterator(); + name = requestType.name() + " " + iterator.next(); + } + return consumerSpanBuilder.kind(Span.Kind.CONSUMER).name(name).start(); + } + + private Span.Builder consumerSpanBuilder(ByteBuf headers) { + if (this.isZipkinPropagationEnabled) { + ByteBuf extract = CompositeMetadataUtils.extract(headers, + WellKnownMimeType.MESSAGE_RSOCKET_TRACING_ZIPKIN.getString()); + if (extract != null) { + TracingMetadata tracingMetadata = TracingMetadataCodec.decode(extract); + Span.Builder builder = this.tracer.spanBuilder(); + TraceContext.Builder parentBuilder = this.tracer.traceContextBuilder() + .sampled(tracingMetadata.isSampled()).traceId(EncodingUtils.fromLong(tracingMetadata.traceId())) + .parentId(EncodingUtils.fromLong(tracingMetadata.parentId())); + return builder.setParent(parentBuilder.build()); + } + else { + return this.propagator.extract(headers, this.getter); + } + } + return this.propagator.extract(headers, this.getter); + } + + @Override + public ThreadLocalSpan getThreadLocalSpan() { + return this.threadLocalSpan; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersHook.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersHook.java index 4473ffce7..a2f226270 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersHook.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersHook.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAspect.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAspect.java index a73af359f..16dcaff11 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAspect.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAspect.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceApplicationRunner.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceApplicationRunner.java new file mode 100644 index 000000000..4e3f6c77d --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceApplicationRunner.java @@ -0,0 +1,65 @@ +/* + * Copyright 2018-2021 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 + * + * https://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.task; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; + +/** + * Trace representation of a {@link ApplicationRunner}. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class TraceApplicationRunner implements ApplicationRunner { + + private final BeanFactory beanFactory; + + private final ApplicationRunner delegate; + + private final String beanName; + + private Tracer tracer; + + public TraceApplicationRunner(BeanFactory beanFactory, ApplicationRunner delegate, String beanName) { + this.beanFactory = beanFactory; + this.delegate = delegate; + this.beanName = beanName; + } + + @Override + public void run(ApplicationArguments args) throws Exception { + Span span = tracer().nextSpan().name(this.beanName); + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + this.delegate.run(args); + } + finally { + span.end(); + } + } + + private Tracer tracer() { + if (this.tracer == null) { + this.tracer = this.beanFactory.getBean(Tracer.class); + } + return this.tracer; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceCommandLineRunner.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceCommandLineRunner.java new file mode 100644 index 000000000..70b9ee320 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceCommandLineRunner.java @@ -0,0 +1,64 @@ +/* + * Copyright 2018-2021 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 + * + * https://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.task; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.boot.CommandLineRunner; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; + +/** + * Trace representation of a {@link CommandLineRunner}. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class TraceCommandLineRunner implements CommandLineRunner { + + private final BeanFactory beanFactory; + + private final CommandLineRunner delegate; + + private final String beanName; + + private Tracer tracer; + + public TraceCommandLineRunner(BeanFactory beanFactory, CommandLineRunner delegate, String beanName) { + this.beanFactory = beanFactory; + this.delegate = delegate; + this.beanName = beanName; + } + + @Override + public void run(String... args) throws Exception { + Span span = tracer().nextSpan().name(this.beanName); + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + this.delegate.run(args); + } + finally { + span.end(); + } + } + + private Tracer tracer() { + if (this.tracer == null) { + this.tracer = this.beanFactory.getBean(Tracer.class); + } + return this.tracer; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceTaskExecutionListener.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceTaskExecutionListener.java new file mode 100644 index 000000000..d50d7ab00 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceTaskExecutionListener.java @@ -0,0 +1,89 @@ +/* + * Copyright 2018-2021 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 + * + * https://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.task; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanAndScope; +import org.springframework.cloud.sleuth.ThreadLocalSpan; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.task.listener.TaskExecutionListener; +import org.springframework.cloud.task.repository.TaskExecution; +import org.springframework.core.Ordered; + +/** + * Sets the span upon starting and closes it upon ending a task. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class TraceTaskExecutionListener implements TaskExecutionListener, Ordered { + + private static final Log log = LogFactory.getLog(TraceTaskExecutionListener.class); + + private final Tracer tracer; + + private final ThreadLocalSpan threadLocalSpan; + + private final String projectName; + + public TraceTaskExecutionListener(Tracer tracer, String projectName) { + this.tracer = tracer; + this.threadLocalSpan = new ThreadLocalSpan(tracer); + this.projectName = projectName; + } + + @Override + public void onTaskStartup(TaskExecution taskExecution) { + Span span = this.tracer.nextSpan().name(this.projectName).start(); + this.threadLocalSpan.set(span); + if (log.isDebugEnabled()) { + log.debug("Put the span [" + span + "] to thread local"); + } + } + + @Override + public void onTaskEnd(TaskExecution taskExecution) { + SpanAndScope spanAndScope = this.threadLocalSpan.get(); + Span span = spanAndScope.getSpan(); + span.end(); + spanAndScope.getScope().close(); + if (log.isDebugEnabled()) { + log.debug("Removed the [" + span + "] from thread local"); + } + } + + @Override + public void onTaskFailed(TaskExecution taskExecution, Throwable throwable) { + SpanAndScope spanAndScope = this.threadLocalSpan.get(); + Span span = spanAndScope.getSpan(); + span.error(throwable); + span.end(); + spanAndScope.getScope().close(); + if (log.isDebugEnabled()) { + log.debug("Removed the [" + span + "] from thread local and added error"); + } + } + + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientRequestParser.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientRequestParser.java index e5fb681f9..41ec85fa3 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientRequestParser.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientRequestParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientResponseParser.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientResponseParser.java index e727d0843..68cd2586f 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientResponseParser.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientResponseParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientSampler.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientSampler.java index b2d425872..44b062111 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientSampler.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerRequestParser.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerRequestParser.java index f7bb7a6a5..d42004b7d 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerRequestParser.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerRequestParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerResponseParser.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerResponseParser.java index d059aa917..81e87fcb5 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerResponseParser.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerResponseParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerSampler.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerSampler.java index 8248f5574..047ca54d1 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerSampler.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternProvider.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternProvider.java index 07efe0e94..478849381 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternProvider.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/SpanFromContextRetriever.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/SpanFromContextRetriever.java new file mode 100644 index 000000000..6a7d3f3ba --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/SpanFromContextRetriever.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013-2021 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 + * + * https://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; + +import java.util.regex.Pattern; + +import reactor.util.context.Context; + +import org.springframework.cloud.sleuth.Span; + +/** + * Provides a URL {@link Pattern} for spans that should be not sampled. + * + * @author Marcin Grzejszczak + * @since 3.0.2 + */ +public interface SpanFromContextRetriever { + + /** + * @param context - Reactor context + * @return span or {@code null} if no span present + */ + default Span findSpan(Context context) { + return null; + }; + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerAdapter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerAdapter.java new file mode 100644 index 000000000..fe86a56d1 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerAdapter.java @@ -0,0 +1,56 @@ +/* + * Copyright 2013-2021 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 + * + * https://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; + +import reactor.core.publisher.Mono; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.web.reactive.HandlerAdapter; +import org.springframework.web.reactive.HandlerResult; +import org.springframework.web.reactive.function.server.HandlerFunction; +import org.springframework.web.server.ServerWebExchange; + +/** + * Tracing representation of a {@link HandlerAdapter}. + * + * @author Marcin Grzejszczak + * @since 3.0.2 + */ +public class TraceHandlerAdapter implements HandlerAdapter { + + private final BeanFactory beanFactory; + + private final HandlerAdapter delegate; + + public TraceHandlerAdapter(HandlerAdapter delegate, BeanFactory beanFactory) { + this.delegate = delegate; + this.beanFactory = beanFactory; + } + + @Override + public boolean supports(Object handler) { + return this.delegate.supports(handler); + } + + @Override + public Mono handle(ServerWebExchange exchange, Object handler) { + HandlerFunction handlerFunction = (HandlerFunction) handler; + TraceHandlerFunction traceHandlerFunction = new TraceHandlerFunction(handlerFunction, this.beanFactory); + return this.delegate.handle(exchange, traceHandlerFunction); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerFunction.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerFunction.java new file mode 100644 index 000000000..8df043c86 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerFunction.java @@ -0,0 +1,69 @@ +/* + * Copyright 2013-2021 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 + * + * https://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; + +import java.util.concurrent.atomic.AtomicReference; + +import reactor.core.publisher.Mono; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.cloud.sleuth.CurrentTraceContext; +import org.springframework.cloud.sleuth.Span; +import org.springframework.web.reactive.function.server.HandlerFunction; +import org.springframework.web.reactive.function.server.ServerRequest; + +/** + * Tracing representation of a {@link HandlerFunction}. + * + * @author Marcin Grzejszczak + * @since 3.0.2 + */ +public class TraceHandlerFunction implements HandlerFunction { + + private final HandlerFunction delegate; + + private final BeanFactory beanFactory; + + private CurrentTraceContext currentTraceContext; + + public TraceHandlerFunction(HandlerFunction delegate, BeanFactory beanFactory) { + this.delegate = delegate; + this.beanFactory = beanFactory; + } + + @Override + public Mono handle(ServerRequest serverRequest) { + AtomicReference scope = new AtomicReference<>(); + return Mono.just(scope) + .doFirst(() -> serverRequest.attribute(TraceWebFilter.TRACE_REQUEST_ATTR) + .ifPresent(span -> scope.set(currentTraceContext().maybeScope(((Span) span).context())))) + .flatMap(r -> this.delegate.handle(serverRequest)).doFinally(signalType -> { + CurrentTraceContext.Scope spanInScope = scope.get(); + if (spanInScope != null) { + spanInScope.close(); + } + }); + } + + private CurrentTraceContext currentTraceContext() { + if (this.currentTraceContext == null) { + this.currentTraceContext = this.beanFactory.getBean(CurrentTraceContext.class); + } + return this.currentTraceContext; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAspect.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAspect.java index 46f7d5e6e..d0a01d6b8 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAspect.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAspect.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java index ba3ce18f0..c2ed27cc8 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -81,6 +81,8 @@ public class TraceWebFilter implements WebFilter, Ordered, ApplicationContextAwa private int order; + private SpanFromContextRetriever spanFromContextRetriever; + @Deprecated public TraceWebFilter(Tracer tracer, HttpServerHandler handler) { this.tracer = tracer; @@ -97,12 +99,12 @@ public class TraceWebFilter implements WebFilter, Ordered, ApplicationContextAwa @Override public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { String uri = exchange.getRequest().getPath().pathWithinApplication().value(); + Mono source = chain.filter(exchange); + boolean tracePresent = isTracePresent(); if (log.isDebugEnabled()) { log.debug("Received a request to uri [" + uri + "]"); } - Mono source = chain.filter(exchange); - boolean tracePresent = isTracePresent(); - return new MonoWebFilterTrace(source, exchange, tracePresent, this); + return new MonoWebFilterTrace(source, exchange, tracePresent, this, spanFromContextRetriever()); } private boolean isTracePresent() { @@ -135,6 +137,15 @@ public class TraceWebFilter implements WebFilter, Ordered, ApplicationContextAwa return this.currentTraceContext; } + private SpanFromContextRetriever spanFromContextRetriever() { + if (this.spanFromContextRetriever == null) { + this.spanFromContextRetriever = this.applicationContext.getBeanProvider(SpanFromContextRetriever.class) + .getIfAvailable(() -> new SpanFromContextRetriever() { + }); + } + return this.spanFromContextRetriever; + } + private static class MonoWebFilterTrace extends MonoOperator implements TraceContextPropagator { final ServerWebExchange exchange; @@ -151,8 +162,10 @@ public class TraceWebFilter implements WebFilter, Ordered, ApplicationContextAwa final CurrentTraceContext currentTraceContext; + final SpanFromContextRetriever spanFromContextRetriever; + MonoWebFilterTrace(Mono source, ServerWebExchange exchange, boolean initialTracePresent, - TraceWebFilter parent) { + TraceWebFilter parent, SpanFromContextRetriever spanFromContextRetriever) { super(source); this.tracer = parent.tracer; this.handler = parent.handler; @@ -160,6 +173,7 @@ public class TraceWebFilter implements WebFilter, Ordered, ApplicationContextAwa this.exchange = exchange; this.span = exchange.getAttribute(TRACE_REQUEST_ATTR); this.initialTracePresent = initialTracePresent; + this.spanFromContextRetriever = spanFromContextRetriever; } @Override @@ -207,12 +221,16 @@ public class TraceWebFilter implements WebFilter, Ordered, ApplicationContextAwa log.debug("Found span in attribute " + span); } } - else { + span = this.spanFromContextRetriever.findSpan(c); + if (this.span == null && span == null) { span = this.handler.handleReceive(new WrappedRequest(this.exchange.getRequest())); if (log.isDebugEnabled()) { log.debug("Handled receive of span " + span); } } + else if (log.isDebugEnabled()) { + log.debug("Found tracer specific span in reactor context [" + span + "]"); + } this.exchange.getAttributes().put(TRACE_REQUEST_ATTR, span); } return span; @@ -397,8 +415,11 @@ public class TraceWebFilter implements WebFilter, Ordered, ApplicationContextAwa @Override public int statusCode() { - if (this.throwable != null && this.throwable instanceof ResponseStatusException) { - return ((ResponseStatusException) this.throwable).getRawStatusCode(); + if (!this.delegate.isCommitted() && this.throwable != null) { + if (this.throwable instanceof ResponseStatusException) { + return ((ResponseStatusException) this.throwable).getRawStatusCode(); + } + return HttpStatus.INTERNAL_SERVER_ERROR.value(); } HttpStatus statusCode = this.delegate.getStatusCode(); return statusCode != null ? statusCode.value() : 0; diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/WebFluxSleuthOperators.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/WebFluxSleuthOperators.java index c6f7487c9..b18f58a86 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/WebFluxSleuthOperators.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/WebFluxSleuthOperators.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -24,6 +24,7 @@ import org.apache.commons.logging.LogFactory; import reactor.core.publisher.Signal; import reactor.core.publisher.SignalType; import reactor.util.context.Context; +import reactor.util.context.ContextView; import org.springframework.cloud.sleuth.CurrentTraceContext; import org.springframework.cloud.sleuth.Span; @@ -94,6 +95,15 @@ public final class WebFluxSleuthOperators { * @param runnable - lambda to execute within the tracing context */ public static void withSpanInScope(Context context, Runnable runnable) { + withSpanInScope((ContextView) context, runnable); + } + + /** + * Wraps a runnable with a span. + * @param context - Reactor context that contains the {@link TraceContext} + * @param runnable - lambda to execute within the tracing context + */ + public static void withSpanInScope(ContextView context, Runnable runnable) { CurrentTraceContext currentTraceContext = context.get(CurrentTraceContext.class); TraceContext traceContext = traceContextOrNew(context); try (CurrentTraceContext.Scope scope = currentTraceContext.maybeScope(traceContext)) { @@ -109,12 +119,23 @@ public final class WebFluxSleuthOperators { * @return value from the callable */ public static T withSpanInScope(Context context, Callable callable) { + return withSpanInScope((ContextView) context, callable); + } + + /** + * Wraps a callable with a span. + * @param context - Reactor context that contains the {@link TraceContext} + * @param callable - lambda to execute within the tracing context + * @param callable's return type + * @return value from the callable + */ + public static T withSpanInScope(ContextView context, Callable callable) { CurrentTraceContext currentTraceContext = context.get(CurrentTraceContext.class); TraceContext traceContext = traceContextOrNew(context); return withContext(callable, currentTraceContext, traceContext); } - private static TraceContext traceContextOrNew(Context context) { + private static TraceContext traceContextOrNew(ContextView context) { Tracer tracer = context.get(Tracer.class); if (!context.hasKey(TraceContext.class)) { if (log.isDebugEnabled()) { diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/AbstractHttpHeadersFilter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/AbstractHttpHeadersFilter.java index 6df38d2da..576a628c8 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/AbstractHttpHeadersFilter.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/AbstractHttpHeadersFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java index e669308f7..4f819f0ec 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -25,6 +25,8 @@ import java.util.function.BiConsumer; import java.util.function.Function; import java.util.function.Supplier; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import reactor.core.publisher.Mono; import reactor.netty.Connection; import reactor.netty.http.client.HttpClient; @@ -69,7 +71,7 @@ public class HttpClientBeanPostProcessor implements BeanPostProcessor { // preparation of a redirect follow-up. TracingDoOnResponse doOnResponse = new TracingDoOnResponse(springContext); return ((HttpClient) bean).doOnResponseError(new TracingDoOnErrorResponse(springContext)) - .doOnRedirect(doOnResponse).doOnResponse(doOnResponse) + .doOnRedirect(doOnResponse).doAfterResponseSuccess(doOnResponse) .doOnRequestError(new TracingDoOnErrorRequest(springContext)) .doOnRequest(new TracingDoOnRequest(springContext)).mapConnect(new TracingMapConnect(() -> { CurrentTraceContext ref = currentContext.get(); @@ -86,6 +88,8 @@ public class HttpClientBeanPostProcessor implements BeanPostProcessor { static class TracingMapConnect implements Function, Mono> { + private static final Log log = LogFactory.getLog(TracingMapConnect.class); + static final Exception CANCELLED_ERROR = new CancellationException("CANCELLED") { @Override public Throwable fillInStackTrace() { @@ -116,6 +120,9 @@ public class HttpClientBeanPostProcessor implements BeanPostProcessor { // like onComplete() completed the span (clearing the reference). Span span = pendingSpan.getAndSet(null); if (span != null) { + if (log.isDebugEnabled()) { + log.debug("Marking span [" + span + "] with cancelled error"); + } span.error(CANCELLED_ERROR); span.end(); } @@ -126,6 +133,8 @@ public class HttpClientBeanPostProcessor implements BeanPostProcessor { private static class TracingDoOnRequest implements BiConsumer { + private static final Log log = LogFactory.getLog(TracingDoOnRequest.class); + final ConfigurableApplicationContext context; HttpClientHandler handler; @@ -153,15 +162,16 @@ public class HttpClientBeanPostProcessor implements BeanPostProcessor { // update this code! Span span = pendingSpan.getAndSet(null); if (span != null) { - assert false : "span exists when it shouldn't!"; span.abandon(); // abandon instead of break } // Start a new client span with the appropriate parent TraceContext parent = req.currentContextView().getOrDefault(TraceContext.class, null); HttpClientRequestWrapper request = new HttpClientRequestWrapper(req, connection); - span = handler().handleSend(request, parent); + if (log.isDebugEnabled()) { + log.debug("Handled send of the netty client span [" + span + "] with parent [" + parent + "]"); + } pendingSpan.set(span); } @@ -211,6 +221,8 @@ public class HttpClientBeanPostProcessor implements BeanPostProcessor { private static abstract class AbstractTracingDoOnHandler { + private static final Log log = LogFactory.getLog(AbstractTracingDoOnHandler.class); + final ConfigurableApplicationContext context; HttpClientHandler handler; @@ -236,6 +248,9 @@ public class HttpClientBeanPostProcessor implements BeanPostProcessor { if (span == null) { return; // Unexpected. In the handle method, without a span to finish! } + if (log.isDebugEnabled()) { + log.debug("Handle receive of the netty client span [" + span + "]"); + } HttpClientResponseWrapper response = new HttpClientResponseWrapper(resp, error); handler().handleReceive(response, span); } diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/LazyTraceClientHttpRequestInterceptor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/LazyTraceClientHttpRequestInterceptor.java index df8093b98..07e89845a 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/LazyTraceClientHttpRequestInterceptor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/LazyTraceClientHttpRequestInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/RestTemplateInterceptorInjector.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/RestTemplateInterceptorInjector.java index fbdda43d8..f80b8e79d 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/RestTemplateInterceptorInjector.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/RestTemplateInterceptorInjector.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunction.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunction.java new file mode 100644 index 000000000..487148e1e --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunction.java @@ -0,0 +1,389 @@ +/* + * Copyright 2013-2021 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 + * + * https://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 java.util.Collection; +import java.util.List; +import java.util.concurrent.CancellationException; +import java.util.concurrent.atomic.AtomicReference; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.reactivestreams.Subscription; +import reactor.core.CoreSubscriber; +import reactor.core.Scannable; +import reactor.core.publisher.Mono; +import reactor.util.annotation.Nullable; +import reactor.util.context.Context; + +import org.springframework.cloud.sleuth.CurrentTraceContext; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.cloud.sleuth.http.HttpClientHandler; +import org.springframework.cloud.sleuth.http.HttpClientRequest; +import org.springframework.cloud.sleuth.http.HttpClientResponse; +import org.springframework.cloud.sleuth.instrument.reactor.TraceContextPropagator; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.web.reactive.function.client.ClientRequest; +import org.springframework.web.reactive.function.client.ClientResponse; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.ExchangeFunction; + +/** + * Trace representation of {@link ExchangeFilterFunction}. + * + * @author Marcin Grzejszczak + * @since 3.0.2 + */ +public final class TraceExchangeFilterFunction implements ExchangeFilterFunction { + + private static final Log log = LogFactory.getLog(TraceExchangeFilterFunction.class); + + final ConfigurableApplicationContext springContext; + + // Lazy initialized fields + HttpClientHandler handler; + + CurrentTraceContext currentTraceContext; + + TraceExchangeFilterFunction(ConfigurableApplicationContext springContext) { + this.springContext = springContext; + } + + public static ExchangeFilterFunction create(ConfigurableApplicationContext springContext) { + return new TraceExchangeFilterFunction(springContext); + } + + @Override + public Mono filter(ClientRequest request, ExchangeFunction next) { + return new MonoWebClientTrace(next, request, this); + } + + CurrentTraceContext currentTraceContext() { + if (this.currentTraceContext == null) { + this.currentTraceContext = this.springContext.getBean(CurrentTraceContext.class); + } + return this.currentTraceContext; + } + + HttpClientHandler handler() { + if (this.handler == null) { + this.handler = this.springContext.getBean(HttpClientHandler.class); + } + return this.handler; + } + + private static final class MonoWebClientTrace extends Mono + implements Scannable, TraceContextPropagator { + + final ExchangeFunction next; + + final ClientRequest request; + + final HttpClientHandler handler; + + final CurrentTraceContext currentTraceContext; + + MonoWebClientTrace(ExchangeFunction next, ClientRequest request, TraceExchangeFilterFunction filterFunction) { + this.next = next; + this.request = request; + this.handler = filterFunction.handler(); + this.currentTraceContext = filterFunction.currentTraceContext(); + } + + @Override + public void subscribe(CoreSubscriber subscriber) { + Context context = subscriber.currentContext(); + if (log.isTraceEnabled()) { + log.trace("Got the following context [" + context + "]"); + } + ClientRequestWrapper wrapper = new ClientRequestWrapper(this.request); + TraceContext parent = context.hasKey(TraceContext.class) ? context.get(TraceContext.class) : null; + if (parent == null) { + parent = this.currentTraceContext.context(); + } + Span span = handler.handleSend(wrapper, parent); + if (log.isTraceEnabled()) { + log.trace("HttpClientHandler::handleSend: " + span); + } + // NOTE: We are starting the client span for the request here, but it could be + // canceled prior to actually being invoked. TraceWebClientSubscription will + // abandon this span, if cancel() happens before request(). + this.next.exchange(wrapper.buildRequest()) + .subscribe(new TraceWebClientSubscriber(subscriber, context, span, parent, this)); + } + + @Nullable + @Override + public Object scanUnsafe(Attr key) { + if (key == Attr.RUN_STYLE) { + return Attr.RunStyle.SYNC; + } + return null; + } + + } + + /** + * Subscriber for WebClient. + */ + static final class TraceWebClientSubscriber extends AtomicReference + implements CoreSubscriber, Scannable { + + final CoreSubscriber actual; + + final Context context; + + @Nullable + final TraceContext parent; + + final HttpClientHandler handler; + + final CurrentTraceContext currentTraceContext; + + TraceWebClientSubscriber(CoreSubscriber actual, Context ctx, Span clientSpan, + TraceContext parent, MonoWebClientTrace mono) { + this.actual = actual; + this.parent = parent; + this.handler = mono.handler; + this.currentTraceContext = mono.currentTraceContext; + this.context = this.parent != null && !this.parent.equals(ctx.getOrDefault(TraceContext.class, null)) + ? ctx.put(TraceContext.class, this.parent) : ctx; + set(clientSpan); + } + + @Override + public void onSubscribe(Subscription subscription) { + this.actual.onSubscribe(new TraceWebClientSubscription(subscription, this)); + } + + @Override + public void onNext(ClientResponse response) { + try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(parent)) { + if (log.isTraceEnabled()) { + log.trace("OnNext"); + } + // decorate response body + this.actual.onNext(response); + } + finally { + Span span = getAndSet(null); + if (span != null) { + if (log.isTraceEnabled()) { + log.trace("OnNext finally"); + } + // TODO: is there a way to read the request at response time? + this.handler.handleReceive(new ClientResponseWrapper(response), span); + } + } + } + + @Override + public void onError(Throwable t) { + try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(parent)) { + if (log.isTraceEnabled()) { + log.trace("OnError"); + } + this.actual.onError(t); + } + finally { + Span span = getAndSet(null); + if (span != null) { + if (log.isTraceEnabled()) { + log.trace("OnError finally"); + } + span.error(t); + span.end(); + } + } + } + + @Override + public void onComplete() { + try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(parent)) { + if (log.isTraceEnabled()) { + log.trace("OnComplete"); + } + this.actual.onComplete(); + } + finally { + Span span = getAndSet(null); + if (span != null) { + // TODO: backfill empty test: + // https://github.com/spring-cloud/spring-cloud-sleuth/issues/1570 + if (log.isTraceEnabled()) { + log.trace("Reached OnComplete without finishing [" + span + "]"); + } + span.abandon(); + } + } + } + + @Override + public Context currentContext() { + return this.context; + } + + @Override + public Object scanUnsafe(Attr key) { + if (key == Attr.RUN_STYLE) { + return Attr.RunStyle.SYNC; + } + return null; + } + + } + + static class TraceWebClientSubscription implements Subscription { + + static final Exception CANCELLED_ERROR = new CancellationException("CANCELLED") { + @Override + public Throwable fillInStackTrace() { + return this; // stack trace doesn't add value here + } + }; + + final AtomicReference pendingSpan; + + final Subscription delegate; + + volatile boolean requested; + + TraceWebClientSubscription(Subscription delegate, AtomicReference pendingSpan) { + this.delegate = delegate; + this.pendingSpan = pendingSpan; + } + + @Override + public void request(long n) { + requested = true; + delegate.request(n); // Not scoping to save overhead + } + + @Override + public void cancel() { + delegate.cancel(); // Not scoping to save overhead + + // Check to see if Subscription.cancel() happened after request(), + // but before another signal (like onComplete) completed the span. + Span span = pendingSpan.getAndSet(null); + if (span != null) { + if (log.isTraceEnabled()) { + log.trace("Subscription was cancelled. TraceWebClientBeanPostProcessor Will close the span [" + span + + "]"); + } + + if (!requested) { // Abandon the span. + span.abandon(); + } + else { // Request was canceled in-flight + span.error(CANCELLED_ERROR); + span.end(); + } + } + } + + } + + private static final class ClientRequestWrapper implements HttpClientRequest { + + final ClientRequest delegate; + + final ClientRequest.Builder builder; + + ClientRequestWrapper(ClientRequest delegate) { + this.delegate = delegate; + this.builder = ClientRequest.from(delegate); + } + + @Override + public Collection headerNames() { + return this.delegate.headers().keySet(); + } + + @Override + public Object unwrap() { + return delegate; + } + + @Override + public String method() { + return delegate.method().name(); + } + + @Override + public String path() { + return delegate.url().getPath(); + } + + @Override + public String url() { + return delegate.url().toString(); + } + + @Override + public String header(String name) { + return delegate.headers().getFirst(name); + } + + @Override + public void header(String name, String value) { + builder.header(name, value); + } + + ClientRequest buildRequest() { + return builder.build(); + } + + } + + static final class ClientResponseWrapper implements HttpClientResponse { + + final ClientResponse delegate; + + ClientResponseWrapper(ClientResponse delegate) { + this.delegate = delegate; + } + + @Override + public Collection headerNames() { + return this.delegate.headers().asHttpHeaders().keySet(); + } + + @Override + public Object unwrap() { + return delegate; + } + + @Override + public int statusCode() { + // unlike statusCode(), this doesn't throw + return Math.max(delegate.rawStatusCode(), 0); + } + + @Override + public String header(String header) { + List headers = delegate.headers().header(header); + if (headers.isEmpty()) { + return null; + } + return headers.get(0); + } + + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java index c8c0c1c74..5be41ac2c 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -44,6 +44,8 @@ public class TraceRequestHttpHeadersFilter extends AbstractHttpHeadersFilter { static final String TRACE_REQUEST_ATTR = TraceContext.class.getName(); + static final String TRACE_REQUEST_ATTR_FROM_TRACE_WEB_FILTER = Span.class.getName(); + public TraceRequestHttpHeadersFilter(Tracer tracer, HttpClientHandler handler, Propagator propagator) { super(tracer, handler, propagator); } @@ -84,12 +86,20 @@ public class TraceRequestHttpHeadersFilter extends AbstractHttpHeadersFilter { private Span currentSpan(ServerWebExchange exchange) { Object attribute = exchange.getAttribute(TRACE_REQUEST_ATTR); + Object span = exchange.getAttribute(TRACE_REQUEST_ATTR_FROM_TRACE_WEB_FILTER); if (attribute instanceof Span) { if (log.isDebugEnabled()) { log.debug("Found trace request attribute in the server web exchange [" + attribute + "]"); } return (Span) attribute; } + else if (span instanceof Span) { + if (log.isDebugEnabled()) { + log.debug("Found trace request attribute in the server web exchange set by TraceWebFilter [" + span + + "]"); + } + return (Span) span; + } return this.tracer.currentSpan(); } @@ -97,10 +107,7 @@ public class TraceRequestHttpHeadersFilter extends AbstractHttpHeadersFilter { if (currentSpan == null) { return this.handler.handleSend(request); } - try (Tracer.SpanInScope ws = this.tracer.withSpan(currentSpan)) { - Span clientSpan = this.tracer.nextSpan(); - return this.handler.handleSend(request, clientSpan.context()); - } + return this.handler.handleSend(request, currentSpan.context()); } private void addHeadersWithInput(HttpHeaders filteredHeaders, HttpHeaders headersWithInput) { diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceResponseHttpHeadersFilter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceResponseHttpHeadersFilter.java index 4403b77cc..4822a274f 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceResponseHttpHeadersFilter.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceResponseHttpHeadersFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateBeanPostProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateBeanPostProcessor.java index 882287153..ccdbf53d9 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateBeanPostProcessor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateCustomizer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateCustomizer.java index 2c8bb8686..d2b9f763c 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateCustomizer.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceUserInfoRestTemplateCustomizer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceUserInfoRestTemplateCustomizer.java index e8fbdaa65..c96608e86 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceUserInfoRestTemplateCustomizer.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceUserInfoRestTemplateCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java index 8a858586f..1dd21b4df 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -16,34 +16,12 @@ package org.springframework.cloud.sleuth.instrument.web.client; -import java.util.Collection; import java.util.List; -import java.util.concurrent.CancellationException; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.reactivestreams.Subscription; -import reactor.core.CoreSubscriber; -import reactor.core.Scannable; -import reactor.core.publisher.Mono; -import reactor.util.annotation.Nullable; -import reactor.util.context.Context; - import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.cloud.sleuth.CurrentTraceContext; -import org.springframework.cloud.sleuth.Span; -import org.springframework.cloud.sleuth.TraceContext; -import org.springframework.cloud.sleuth.http.HttpClientHandler; -import org.springframework.cloud.sleuth.http.HttpClientRequest; -import org.springframework.cloud.sleuth.http.HttpClientResponse; -import org.springframework.cloud.sleuth.instrument.reactor.TraceContextPropagator; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.web.reactive.function.client.ClientRequest; -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; /** @@ -102,339 +80,3 @@ public class TraceWebClientBeanPostProcessor implements BeanPostProcessor { } } - -final class TraceExchangeFilterFunction implements ExchangeFilterFunction { - - private static final Log log = LogFactory.getLog(TraceExchangeFilterFunction.class); - - final ConfigurableApplicationContext springContext; - - // Lazy initialized fields - HttpClientHandler handler; - - CurrentTraceContext currentTraceContext; - - TraceExchangeFilterFunction(ConfigurableApplicationContext springContext) { - this.springContext = springContext; - } - - public static ExchangeFilterFunction create(ConfigurableApplicationContext springContext) { - return new TraceExchangeFilterFunction(springContext); - } - - @Override - public Mono filter(ClientRequest request, ExchangeFunction next) { - return new MonoWebClientTrace(next, request, this); - } - - CurrentTraceContext currentTraceContext() { - if (this.currentTraceContext == null) { - this.currentTraceContext = this.springContext.getBean(CurrentTraceContext.class); - } - return this.currentTraceContext; - } - - HttpClientHandler handler() { - if (this.handler == null) { - this.handler = this.springContext.getBean(HttpClientHandler.class); - } - return this.handler; - } - - private static final class MonoWebClientTrace extends Mono - implements Scannable, TraceContextPropagator { - - final ExchangeFunction next; - - final ClientRequest request; - - final HttpClientHandler handler; - - final CurrentTraceContext currentTraceContext; - - MonoWebClientTrace(ExchangeFunction next, ClientRequest request, TraceExchangeFilterFunction filterFunction) { - this.next = next; - this.request = request; - this.handler = filterFunction.handler(); - this.currentTraceContext = filterFunction.currentTraceContext(); - } - - @Override - public void subscribe(CoreSubscriber subscriber) { - Context context = subscriber.currentContext(); - if (log.isTraceEnabled()) { - log.trace("Got the following context [" + context + "]"); - } - ClientRequestWrapper wrapper = new ClientRequestWrapper(this.request); - TraceContext parent = context.hasKey(TraceContext.class) ? context.get(TraceContext.class) : null; - Span span = handler.handleSend(wrapper, parent); - if (log.isTraceEnabled()) { - log.trace("HttpClientHandler::handleSend: " + span); - } - // NOTE: We are starting the client span for the request here, but it could be - // canceled prior to actually being invoked. TraceWebClientSubscription will - // abandon this span, if cancel() happens before request(). - this.next.exchange(wrapper.buildRequest()) - .subscribe(new TraceWebClientSubscriber(subscriber, context, span, parent, this)); - } - - @Nullable - @Override - public Object scanUnsafe(Scannable.Attr key) { - if (key == Scannable.Attr.RUN_STYLE) { - return Scannable.Attr.RunStyle.SYNC; - } - return null; - } - - } - - /** - * Subscriber for WebClient. - */ - static final class TraceWebClientSubscriber extends AtomicReference - implements CoreSubscriber, Scannable { - - final CoreSubscriber actual; - - final Context context; - - @Nullable - final TraceContext parent; - - final HttpClientHandler handler; - - final CurrentTraceContext currentTraceContext; - - TraceWebClientSubscriber(CoreSubscriber actual, Context ctx, Span clientSpan, - TraceContext parent, MonoWebClientTrace mono) { - this.actual = actual; - this.parent = parent; - this.handler = mono.handler; - this.currentTraceContext = mono.currentTraceContext; - this.context = this.parent != null && !this.parent.equals(ctx.getOrDefault(TraceContext.class, null)) - ? ctx.put(TraceContext.class, this.parent) : ctx; - set(clientSpan); - } - - @Override - public void onSubscribe(Subscription subscription) { - this.actual.onSubscribe(new TraceWebClientSubscription(subscription, this)); - } - - @Override - public void onNext(ClientResponse response) { - try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(parent)) { - if (log.isTraceEnabled()) { - log.trace("OnNext"); - } - // decorate response body - this.actual.onNext(response); - } - finally { - Span span = getAndSet(null); - if (span != null) { - if (log.isTraceEnabled()) { - log.trace("OnNext finally"); - } - // TODO: is there a way to read the request at response time? - this.handler.handleReceive(new ClientResponseWrapper(response), span); - } - } - } - - @Override - public void onError(Throwable t) { - try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(parent)) { - if (log.isTraceEnabled()) { - log.trace("OnError"); - } - this.actual.onError(t); - } - finally { - Span span = getAndSet(null); - if (span != null) { - if (log.isTraceEnabled()) { - log.trace("OnError finally"); - } - span.error(t); - span.end(); - } - } - } - - @Override - public void onComplete() { - try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(parent)) { - if (log.isTraceEnabled()) { - log.trace("OnComplete"); - } - this.actual.onComplete(); - } - finally { - Span span = getAndSet(null); - if (span != null) { - // TODO: backfill empty test: - // https://github.com/spring-cloud/spring-cloud-sleuth/issues/1570 - if (log.isTraceEnabled()) { - log.trace("Reached OnComplete without finishing [" + span + "]"); - } - span.abandon(); - } - } - } - - @Override - public Context currentContext() { - return this.context; - } - - @Override - public Object scanUnsafe(Scannable.Attr key) { - if (key == Scannable.Attr.RUN_STYLE) { - return Scannable.Attr.RunStyle.SYNC; - } - return null; - } - - } - - static class TraceWebClientSubscription implements Subscription { - - static final Exception CANCELLED_ERROR = new CancellationException("CANCELLED") { - @Override - public Throwable fillInStackTrace() { - return this; // stack trace doesn't add value here - } - }; - - final AtomicReference pendingSpan; - - final Subscription delegate; - - volatile boolean requested; - - TraceWebClientSubscription(Subscription delegate, AtomicReference pendingSpan) { - this.delegate = delegate; - this.pendingSpan = pendingSpan; - } - - @Override - public void request(long n) { - requested = true; - delegate.request(n); // Not scoping to save overhead - } - - @Override - public void cancel() { - delegate.cancel(); // Not scoping to save overhead - - // Check to see if Subscription.cancel() happened after request(), - // but before another signal (like onComplete) completed the span. - Span span = pendingSpan.getAndSet(null); - if (span != null) { - if (log.isTraceEnabled()) { - log.trace("Subscription was cancelled. TraceWebClientBeanPostProcessor Will close the span [" + span - + "]"); - } - - if (!requested) { // Abandon the span. - span.abandon(); - } - else { // Request was canceled in-flight - span.error(CANCELLED_ERROR); - span.end(); - } - } - } - - } - - private static final class ClientRequestWrapper implements HttpClientRequest { - - final ClientRequest delegate; - - final ClientRequest.Builder builder; - - ClientRequestWrapper(ClientRequest delegate) { - this.delegate = delegate; - this.builder = ClientRequest.from(delegate); - } - - @Override - public Collection headerNames() { - return this.delegate.headers().keySet(); - } - - @Override - public Object unwrap() { - return delegate; - } - - @Override - public String method() { - return delegate.method().name(); - } - - @Override - public String path() { - return delegate.url().getPath(); - } - - @Override - public String url() { - return delegate.url().toString(); - } - - @Override - public String header(String name) { - return delegate.headers().getFirst(name); - } - - @Override - public void header(String name, String value) { - builder.header(name, value); - } - - ClientRequest buildRequest() { - return builder.build(); - } - - } - - static final class ClientResponseWrapper implements HttpClientResponse { - - final ClientResponse delegate; - - ClientResponseWrapper(ClientResponse delegate) { - this.delegate = delegate; - } - - @Override - public Collection headerNames() { - return this.delegate.headers().asHttpHeaders().keySet(); - } - - @Override - public Object unwrap() { - return delegate; - } - - @Override - public int statusCode() { - // unlike statusCode(), this doesn't throw - return Math.max(delegate.rawStatusCode(), 0); - } - - @Override - public String header(String header) { - List headers = delegate.headers().header(header); - if (headers.isEmpty()) { - return null; - } - return headers.get(0); - } - - } - -} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/UserInfoRestTemplateCustomizerBeanPostProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/UserInfoRestTemplateCustomizerBeanPostProcessor.java index c539a18b6..a967e3de1 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/UserInfoRestTemplateCustomizerBeanPostProcessor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/UserInfoRestTemplateCustomizerBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignContextBeanPostProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignContextBeanPostProcessor.java index adc049177..72da6a33b 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignContextBeanPostProcessor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignContextBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyClient.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyClient.java index 8b99f90fe..aa12c934f 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyClient.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyTracingFeignClient.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyTracingFeignClient.java index 6e563bb0c..874022887 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyTracingFeignClient.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyTracingFeignClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/OkHttpFeignClientBeanPostProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/OkHttpFeignClientBeanPostProcessor.java index e79cc6e23..4f798c4c7 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/OkHttpFeignClientBeanPostProcessor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/OkHttpFeignClientBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilder.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilder.java index 70d3f25ad..2a88e9cfc 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilder.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -20,7 +20,6 @@ import feign.Client; import feign.Feign; import feign.Retryer; -import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; /** @@ -36,15 +35,19 @@ public final class SleuthFeignBuilder { } public static Feign.Builder builder(BeanFactory beanFactory) { - return Feign.builder().retryer(Retryer.NEVER_RETRY).client(client(beanFactory)); + return builder(beanFactory, null); } - private static Client client(BeanFactory beanFactory) { - try { + public static Feign.Builder builder(BeanFactory beanFactory, Client delegate) { + return Feign.builder().retryer(Retryer.NEVER_RETRY).client(client(beanFactory, delegate)); + } + + private static Client client(BeanFactory beanFactory, Client delegate) { + if (delegate == null) { return new LazyClient(beanFactory); } - catch (BeansException ex) { - return new LazyClient(beanFactory, new Client.Default(null, null)); + else { + return new LazyClient(beanFactory, delegate); } } diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignAspect.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignAspect.java index d2cabe30e..df500bd35 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignAspect.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignAspect.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBlockingLoadBalancerClient.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBlockingLoadBalancerClient.java index 3ed3652d6..433c5e6cc 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBlockingLoadBalancerClient.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBlockingLoadBalancerClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBuilderBeanPostProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBuilderBeanPostProcessor.java new file mode 100644 index 000000000..c10596245 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBuilderBeanPostProcessor.java @@ -0,0 +1,60 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.feign; + +import java.lang.reflect.Field; + +import feign.Client; +import feign.Feign; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.util.ReflectionUtils; + +/** + * {@link BeanPostProcessor} that ensures that each {@link Feign.Builder} has a trace + * representation of a {@link Client}. + * + * @author Marcin Grzejszczak + * @since 3.0.2 + */ +public class TraceFeignBuilderBeanPostProcessor implements BeanPostProcessor { + + private final BeanFactory beanFactory; + + public TraceFeignBuilderBeanPostProcessor(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof Feign.Builder) { + Field client = ReflectionUtils.findField(Feign.Builder.class, "client"); + ReflectionUtils.makeAccessible(client); + Feign.Builder delegate = (Feign.Builder) bean; + Client clientInDelegate = (Client) ReflectionUtils.getField(client, delegate); + if (clientInDelegate instanceof LazyClient || clientInDelegate instanceof LazyTracingFeignClient) { + return bean; + } + delegate.client(new LazyClient(this.beanFactory, clientInDelegate)); + return bean; + } + return bean; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignContext.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignContext.java index 33eba5489..fb7dcc08c 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignContext.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignObjectWrapper.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignObjectWrapper.java index 6993315e2..afdbb25ad 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignObjectWrapper.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignObjectWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -70,8 +70,11 @@ final class TraceFeignObjectWrapper { private Object loadBalancerClientFactory; + private final TraceFeignBuilderBeanPostProcessor traceFeignBuilderBeanPostProcessor; + TraceFeignObjectWrapper(BeanFactory beanFactory) { this.beanFactory = beanFactory; + this.traceFeignBuilderBeanPostProcessor = new TraceFeignBuilderBeanPostProcessor(beanFactory); } Object wrap(Object bean) { @@ -87,7 +90,7 @@ final class TraceFeignObjectWrapper { } return new LazyTracingFeignClient(this.beanFactory, (Client) bean); } - return bean; + return this.traceFeignBuilderBeanPostProcessor.postProcessAfterInitialization(bean, null); } private Object instrumentedFeignLoadBalancerClient(Object bean) { diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceRetryableFeignBlockingLoadBalancerClient.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceRetryableFeignBlockingLoadBalancerClient.java index 7d51a071c..7158012e9 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceRetryableFeignBlockingLoadBalancerClient.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceRetryableFeignBlockingLoadBalancerClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignClient.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignClient.java index 6493dddcc..b8e1cad57 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignClient.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/HandlerParser.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/HandlerParser.java index 571fc1585..2ee9cb929 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/HandlerParser.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/HandlerParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/SpanCustomizingAsyncHandlerInterceptor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/SpanCustomizingAsyncHandlerInterceptor.java index 7d3fa7b1b..466cbc894 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/SpanCustomizingAsyncHandlerInterceptor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/SpanCustomizingAsyncHandlerInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/SpanCustomizingHandlerInterceptor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/SpanCustomizingHandlerInterceptor.java index 6063b1035..6174413ce 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/SpanCustomizingHandlerInterceptor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/SpanCustomizingHandlerInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/TraceContextListenableFuture.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/TraceContextListenableFuture.java index 88ac53a02..04d1cad64 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/TraceContextListenableFuture.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/TraceContextListenableFuture.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/TracingAsyncClientHttpRequestInterceptor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/TracingAsyncClientHttpRequestInterceptor.java index 24c314df2..b77f18665 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/TracingAsyncClientHttpRequestInterceptor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/TracingAsyncClientHttpRequestInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/TracingClientHttpRequestInterceptor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/TracingClientHttpRequestInterceptor.java index 1b9909ab0..9b5c3524e 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/TracingClientHttpRequestInterceptor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/TracingClientHttpRequestInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/WebMvcRuntime.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/WebMvcRuntime.java index f228016aa..842b981d2 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/WebMvcRuntime.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/WebMvcRuntime.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/package-info.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/package-info.java index 5a386ca08..5bac0866f 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/package-info.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/mvc/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/HttpServletRequestWrapper.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/HttpServletRequestWrapper.java index f3f028b66..133c195ba 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/HttpServletRequestWrapper.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/HttpServletRequestWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/HttpServletResponseWrapper.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/HttpServletResponseWrapper.java index 6e6f9d7d4..5971fc1ef 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/HttpServletResponseWrapper.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/HttpServletResponseWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/ServletRuntime.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/ServletRuntime.java index 8a5abd26a..3f1ba56df 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/ServletRuntime.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/ServletRuntime.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/TracingFilter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/TracingFilter.java index 3f589c893..57ba6251e 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/TracingFilter.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/TracingFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/package-info.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/package-info.java index 4d7afb534..d1f06e38d 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/package-info.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/servlet/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/ContextUtil.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/ContextUtil.java index 25c2f6779..861a9534f 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/ContextUtil.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/ContextUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/DefaultSpanNamer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/DefaultSpanNamer.java index 04a8588ce..8344471af 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/DefaultSpanNamer.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/DefaultSpanNamer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/EncodingUtils.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/EncodingUtils.java new file mode 100644 index 000000000..f1fcf6f82 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/EncodingUtils.java @@ -0,0 +1,322 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.internal; + +import java.util.Arrays; + +import org.springframework.util.Assert; + +/** + * Adopted from OpenTelemetry API. + * + * @since 3.1.0 + */ +public final class EncodingUtils { + + private static final ThreadLocal charBuffer = new ThreadLocal(); + + private EncodingUtils() { + } + + static final int LONG_BYTES = Long.SIZE / Byte.SIZE; + + static final int BYTE_BASE16 = 2; + + static final int LONG_BASE16 = BYTE_BASE16 * LONG_BYTES; + + private static final String ALPHABET = "0123456789abcdef"; + + private static final int ASCII_CHARACTERS = 128; + + private static final char[] ENCODING = buildEncodingArray(); + + private static final byte[] DECODING = buildDecodingArray(); + + private static char[] buildEncodingArray() { + char[] encoding = new char[512]; + for (int i = 0; i < 256; ++i) { + encoding[i] = ALPHABET.charAt(i >>> 4); + encoding[i | 0x100] = ALPHABET.charAt(i & 0xF); + } + return encoding; + } + + private static byte[] buildDecodingArray() { + byte[] decoding = new byte[ASCII_CHARACTERS]; + Arrays.fill(decoding, (byte) -1); + for (int i = 0; i < ALPHABET.length(); i++) { + char c = ALPHABET.charAt(i); + decoding[c] = (byte) i; + } + return decoding; + } + + /** + * Returns the {@code long} value. + * @param chars the base8 or base16 representation of the {@code long}. + * @return long array from string. Either contains high and low or just low trace id + */ + public static long[] fromString(CharSequence chars) { + if (chars == null || chars.length() == 0) { + return new long[] { 0 }; + } + if (chars.length() == 32) { + long high = HexCodec.lenientLowerHexToUnsignedLong(chars, 0, 16); + long low = HexCodec.lenientLowerHexToUnsignedLong(chars, 16, 32); + return new long[] { high, low }; + } + return new long[] { HexCodec.lenientLowerHexToUnsignedLong(chars, 0, 16) }; + } + + /** + * Returns the {@code long} value whose base16 representation is stored in the first + * 16 chars of {@code chars} starting from the {@code offset}. + * @param chars the base16 representation of the {@code long}. + * @return long value from string + */ + public static long longFromBase16String(CharSequence chars) { + return longFromBase16String(chars, 0); + } + + /** + * Returns the {@code long} value whose base16 representation is stored in the first + * 16 chars of {@code chars} starting from the {@code offset}. + * @param chars the base16 representation of the {@code long}. + */ + static long longFromBase16String(CharSequence chars, int offset) { + Assert.isTrue(chars.length() >= offset + LONG_BASE16, "chars too small"); + return (decodeByte(chars.charAt(offset), chars.charAt(offset + 1)) & 0xFFL) << 56 + | (decodeByte(chars.charAt(offset + 2), chars.charAt(offset + 3)) & 0xFFL) << 48 + | (decodeByte(chars.charAt(offset + 4), chars.charAt(offset + 5)) & 0xFFL) << 40 + | (decodeByte(chars.charAt(offset + 6), chars.charAt(offset + 7)) & 0xFFL) << 32 + | (decodeByte(chars.charAt(offset + 8), chars.charAt(offset + 9)) & 0xFFL) << 24 + | (decodeByte(chars.charAt(offset + 10), chars.charAt(offset + 11)) & 0xFFL) << 16 + | (decodeByte(chars.charAt(offset + 12), chars.charAt(offset + 13)) & 0xFFL) << 8 + | (decodeByte(chars.charAt(offset + 14), chars.charAt(offset + 15)) & 0xFFL); + } + + /** + * Decodes the specified two character sequence, and returns the resulting + * {@code byte}. + * @param chars the character sequence to be decoded. + * @param offset the starting offset in the {@code CharSequence}. + * @return the resulting {@code byte} + * @throws IllegalArgumentException if the input is not a valid encoded string + * according to this encoding. + */ + public static byte byteFromBase16String(CharSequence chars, int offset) { + Assert.isTrue(chars.length() >= offset + 2, "chars too small"); + return decodeByte(chars.charAt(offset), chars.charAt(offset + 1)); + } + + private static byte decodeByte(char hi, char lo) { + Assert.isTrue(lo < ASCII_CHARACTERS && DECODING[lo] != -1, "invalid character " + lo); + Assert.isTrue(hi < ASCII_CHARACTERS && DECODING[hi] != -1, "invalid character " + hi); + int decoded = DECODING[hi] << 4 | DECODING[lo]; + return (byte) decoded; + } + + /** + * Checks if string is valid base16. + * @param value to check + * @return {@code true} if valid base16 string + */ + public static boolean isValidBase16String(CharSequence value) { + for (int i = 0; i < value.length(); i++) { + char b = value.charAt(i); + // 48..57 && 97..102 are valid + if (!isDigit(b) && !isLowercaseHexCharacter(b)) { + return false; + } + } + return true; + } + + /** + * Converts long into string. + * @param id 64 bit + * @return string representation of the long + */ + public static String fromLong(long id) { + return fromLongs(0, id); + } + + /** + * Converts longs into string. + * @param idHigh - trace id high part + * @param idLow - trace id low part + * @return string representation of the long + */ + public static String fromLongs(long idHigh, long idLow) { + if (idHigh == 0L) { + return HexCodec.toLowerHex(idLow); + } + else { + char[] chars = getTemporaryBuffer(); + longToBase16String(idHigh, chars, 0); + longToBase16String(idLow, chars, 16); + return new String(chars); + } + } + + public static void longToBase16String(long value, char[] dest, int destOffset) { + byteToBase16((byte) ((int) (value >> 56 & 255L)), dest, destOffset); + byteToBase16((byte) ((int) (value >> 48 & 255L)), dest, destOffset + 2); + byteToBase16((byte) ((int) (value >> 40 & 255L)), dest, destOffset + 4); + byteToBase16((byte) ((int) (value >> 32 & 255L)), dest, destOffset + 6); + byteToBase16((byte) ((int) (value >> 24 & 255L)), dest, destOffset + 8); + byteToBase16((byte) ((int) (value >> 16 & 255L)), dest, destOffset + 10); + byteToBase16((byte) ((int) (value >> 8 & 255L)), dest, destOffset + 12); + byteToBase16((byte) ((int) (value & 255L)), dest, destOffset + 14); + } + + public static void byteToBase16(byte value, char[] dest, int destOffset) { + int b = value & 255; + dest[destOffset] = ENCODING[b]; + dest[destOffset + 1] = ENCODING[b | 256]; + } + + private static char[] getTemporaryBuffer() { + char[] chars = charBuffer.get(); + if (chars == null) { + chars = new char[32]; + charBuffer.set(chars); + } + return chars; + } + + private static boolean isLowercaseHexCharacter(char b) { + return 97 <= b && b <= 102; + } + + private static boolean isDigit(char b) { + return 48 <= b && b <= 57; + } + +} + +// taken from brave.internal.codec.HexCodec +final class HexCodec { + + private HexCodec() { + throw new IllegalStateException("Can't instantiate a utility class"); + } + + /** + * Parses a 16 character lower-hex string with no prefix into an unsigned long, + * starting at the specified index. + * + * This reads a trace context a sequence potentially larger than the format. The + * use-case is reducing garbage, by re-using the input {@code value} across multiple + * parse operations. + * @param value the sequence that contains a lower-hex encoded unsigned long. + * @param beginIndex the inclusive begin index: {@linkplain CharSequence#charAt(int) + * index} of the first lower-hex character representing the unsigned long. + */ + static long lowerHexToUnsignedLong(CharSequence value, int beginIndex) { + int endIndex = Math.min(beginIndex + 16, value.length()); + long result = lenientLowerHexToUnsignedLong(value, beginIndex, endIndex); + if (result == 0) { + throw isntLowerHexLong(value); + } + return result; + } + + /** + * Like {@link #lowerHexToUnsignedLong(CharSequence, int)}, but returns zero on + * invalid input. + * @param value the sequence that contains a lower-hex encoded unsigned long. + * @param beginIndex the inclusive begin index: {@linkplain CharSequence#charAt(int) + * index} of the first lower-hex character representing the unsigned long. + * @param endIndex the exclusive end index: {@linkplain CharSequence#charAt(int) + * index} after the last lower-hex character representing the unsigned long. + */ + static long lenientLowerHexToUnsignedLong(CharSequence value, int beginIndex, int endIndex) { + long result = 0; + int pos = beginIndex; + while (pos < endIndex) { + char c = value.charAt(pos++); + result <<= 4; + if (c >= '0' && c <= '9') { + result |= c - '0'; + } + else if (c >= 'a' && c <= 'f') { + result |= c - 'a' + 10; + } + else { + return 0; + } + } + return result; + } + + static NumberFormatException isntLowerHexLong(CharSequence lowerHex) { + throw new NumberFormatException(lowerHex + " should be a 1 to 32 character lower-hex string with no prefix"); + } + + /** Inspired by {@code okio.Buffer.writeLong}. */ + static String toLowerHex(long v) { + char[] data = RecyclableBuffers.parseBuffer(); + writeHexLong(data, 0, v); + return new String(data, 0, 16); + } + + /** Inspired by {@code okio.Buffer.writeLong}. */ + static void writeHexLong(char[] data, int pos, long v) { + writeHexByte(data, pos + 0, (byte) ((v >>> 56L) & 0xff)); + writeHexByte(data, pos + 2, (byte) ((v >>> 48L) & 0xff)); + writeHexByte(data, pos + 4, (byte) ((v >>> 40L) & 0xff)); + writeHexByte(data, pos + 6, (byte) ((v >>> 32L) & 0xff)); + writeHexByte(data, pos + 8, (byte) ((v >>> 24L) & 0xff)); + writeHexByte(data, pos + 10, (byte) ((v >>> 16L) & 0xff)); + writeHexByte(data, pos + 12, (byte) ((v >>> 8L) & 0xff)); + writeHexByte(data, pos + 14, (byte) (v & 0xff)); + } + + static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + + static void writeHexByte(char[] data, int pos, byte b) { + data[pos + 0] = HEX_DIGITS[(b >> 4) & 0xf]; + data[pos + 1] = HEX_DIGITS[b & 0xf]; + } + +} + +// taken from brave +final class RecyclableBuffers { + + private RecyclableBuffers() { + throw new IllegalStateException("Can't instantiate a utility class"); + } + + private static final ThreadLocal PARSE_BUFFER = new ThreadLocal<>(); + + /** + * Returns a {@link ThreadLocal} reused {@code char[]} for use when decoding bytes + * into an ID hex string. The buffer should be immediately copied into a + * {@link String} after decoding within the same method. + */ + static char[] parseBuffer() { + char[] idBuffer = PARSE_BUFFER.get(); + if (idBuffer == null) { + idBuffer = new char[32 + 1 + 16 + 3 + 16]; // traceid128-spanid-1-parentid + PARSE_BUFFER.set(idBuffer); + } + return idBuffer; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/LazyBean.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/LazyBean.java index 328ef61ed..688014885 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/LazyBean.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/LazyBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/SleuthContextListener.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/SleuthContextListener.java index a6ffeb027..ff0eb0a38 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/SleuthContextListener.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/SleuthContextListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/SpanNameUtil.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/SpanNameUtil.java index 0a567ad4e..94e5473eb 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/SpanNameUtil.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/SpanNameUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/ArchitectureTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/ArchitectureTests.java index 434c404af..53b9421e7 100644 --- a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/ArchitectureTests.java +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/ArchitectureTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolverTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolverTests.java index 75ce679cd..0fa85b175 100644 --- a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolverTests.java +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/annotation/SpelTagValueExpressionResolverTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/annotation/SpelTagValueExpressionResolverTests.java index f77bee18c..f00ade0ad 100644 --- a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/annotation/SpelTagValueExpressionResolverTests.java +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/annotation/SpelTagValueExpressionResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/ExecutorInstrumentorTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/ExecutorInstrumentorTests.java index c935a31be..dfed086bb 100644 --- a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/ExecutorInstrumentorTests.java +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/ExecutorInstrumentorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -36,6 +36,8 @@ import org.aopalliance.aop.Advice; import org.assertj.core.api.BDDAssertions; import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledForJreRange; +import org.junit.jupiter.api.condition.JRE; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.BDDMockito; import org.mockito.Mock; @@ -294,6 +296,7 @@ public class ExecutorInstrumentorTests { } @Test + @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_15) public void should_use_cglib_proxy_when_an_executor_has_a_final_package_protected_method() { ExecutorInstrumentor beanPostProcessor = new ExecutorInstrumentor(Collections::emptyList, beanFactory); ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10); @@ -307,6 +310,21 @@ public class ExecutorInstrumentorTests { Awaitility.await().untilAsserted(() -> BDDAssertions.then(wasCalled).isTrue()); } + @Test + @EnabledForJreRange(min = JRE.JAVA_16) + public void should_use_jdk_proxy_when_an_executor_has_a_final_package_protected_method() { + ExecutorInstrumentor beanPostProcessor = new ExecutorInstrumentor(Collections::emptyList, beanFactory); + ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10); + ScheduledThreadPoolExecutor wrappedExecutor = (ScheduledThreadPoolExecutor) beanPostProcessor + .instrument(executor, "executor"); + + BDDAssertions.then(AopUtils.isCglibProxy(wrappedExecutor)).isFalse(); + + AtomicBoolean wasCalled = new AtomicBoolean(false); + wrappedExecutor.execute(() -> wasCalled.set(true)); + Awaitility.await().untilAsserted(() -> BDDAssertions.then(wasCalled).isTrue()); + } + @Test public void should_use_jdk_proxy_when_executor_service_has_final_methods() throws Exception { ExecutorInstrumentor beanPostProcessor = new ExecutorInstrumentor(Collections::emptyList, beanFactory); diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncCustomizerTest.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncCustomizerTest.java index d99a56d56..0b5992738 100644 --- a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncCustomizerTest.java +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncCustomizerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutorTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutorTests.java index c5c7bd5f9..8dc98bc85 100644 --- a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutorTests.java +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -16,6 +16,7 @@ package org.springframework.cloud.sleuth.instrument.async; +import java.lang.reflect.Method; import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -34,8 +35,11 @@ import java.util.concurrent.atomic.AtomicBoolean; import org.assertj.core.api.BDDAssertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledForJreRange; +import org.junit.jupiter.api.condition.JRE; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; +import org.mockito.BDDMockito; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -92,6 +96,14 @@ public class LazyTraceScheduledThreadPoolExecutorTests { boolean isContextUnusable() { return false; } + + @Override + boolean isMethodOverridden(Method originalMethod) { + if (JRE.currentVersion().ordinal() >= JRE.JAVA_16.ordinal()) { + return false; + } + return true; + } }); } @@ -107,13 +119,22 @@ public class LazyTraceScheduledThreadPoolExecutorTests { }; BeanFactory beanFactory = mock(BeanFactory.class); - new LazyTraceScheduledThreadPoolExecutor(10, beanFactory, executor, null).finalize(); + new LazyTraceScheduledThreadPoolExecutor(10, beanFactory, executor, null) { + @Override + boolean isMethodOverridden(Method originalMethod) { + if (JRE.currentVersion().ordinal() >= JRE.JAVA_16.ordinal()) { + return false; + } + return true; + } + }.finalize(); BDDAssertions.then(wasCalled).isFalse(); BDDAssertions.then(executor.isShutdown()).isFalse(); } @Test + @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_15) public void should_delegate_decorateTask_with_runnable() { final Runnable runnable = mock(Runnable.class); final RunnableScheduledFuture value = mock(RunnableScheduledFuture.class); @@ -128,6 +149,7 @@ public class LazyTraceScheduledThreadPoolExecutorTests { } @Test + @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_15) public void should_delegate_decorateTask_with_callable() { final Callable callable = mock(Callable.class); final RunnableScheduledFuture value = mock(RunnableScheduledFuture.class); @@ -511,7 +533,7 @@ public class LazyTraceScheduledThreadPoolExecutorTests { executor.remove(expected); - verify(delegate).remove(expected); + verify(delegate).remove(BDDMockito.isA(TraceRunnable.class)); } @Test @@ -582,6 +604,7 @@ public class LazyTraceScheduledThreadPoolExecutorTests { } @Test + @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_15) public void should_delegate_beforeExecute() { final Thread thread = mock(Thread.class); final Runnable expected = mock(Runnable.class); @@ -593,6 +616,7 @@ public class LazyTraceScheduledThreadPoolExecutorTests { } @Test + @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_15) public void should_delegate_afterExecute() { final Throwable throwable = mock(Throwable.class); final Runnable expected = mock(Runnable.class); @@ -604,6 +628,7 @@ public class LazyTraceScheduledThreadPoolExecutorTests { } @Test + @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_15) public void should_delegate_terminated() { executor.terminated(); @@ -611,6 +636,7 @@ public class LazyTraceScheduledThreadPoolExecutorTests { } @Test + @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_15) public void should_delegate_newTaskForRunnable() { final Runnable runnable = mock(Runnable.class); final String expected = "testing"; @@ -625,6 +651,7 @@ public class LazyTraceScheduledThreadPoolExecutorTests { } @Test + @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_15) public void should_delegate_newTaskForCallable() { final Callable callable = mock(Callable.class); final RunnableFuture expected = mock(RunnableFuture.class); diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpCurrentTraceContext.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpCurrentTraceContext.java new file mode 100644 index 000000000..394c3eefb --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpCurrentTraceContext.java @@ -0,0 +1,71 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.deployer; + +import java.util.concurrent.Callable; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; + +import org.springframework.cloud.sleuth.CurrentTraceContext; +import org.springframework.cloud.sleuth.TraceContext; + +/** + * A noop implementation. Does nothing. + * + * @author Marcin Grzejszczak + * @since 3.0.0 + */ +class NoOpCurrentTraceContext implements CurrentTraceContext { + + @Override + public TraceContext context() { + return null; + } + + @Override + public Scope newScope(TraceContext context) { + return () -> { + }; + } + + @Override + public Scope maybeScope(TraceContext context) { + return () -> { + }; + } + + @Override + public Callable wrap(Callable task) { + return task; + } + + @Override + public Runnable wrap(Runnable task) { + return task; + } + + @Override + public Executor wrap(Executor delegate) { + return delegate; + } + + @Override + public ExecutorService wrap(ExecutorService delegate) { + return delegate; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpSpanInScope.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpSpanInScope.java new file mode 100644 index 000000000..d2339918a --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpSpanInScope.java @@ -0,0 +1,34 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.deployer; + +import org.springframework.cloud.sleuth.Tracer; + +/** + * A noop implementation. Does nothing. + * + * @author Marcin Grzejszczak + * @since 3.0.0 + */ +class NoOpSpanInScope implements Tracer.SpanInScope { + + @Override + public void close() { + + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpTraceContext.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpTraceContext.java new file mode 100644 index 000000000..057b4b41f --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpTraceContext.java @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.deployer; + +import org.springframework.cloud.sleuth.TraceContext; + +/** + * A noop implementation. Does nothing. + * + * @author Marcin Grzejszczak + * @since 3.0.0 + */ +class NoOpTraceContext implements TraceContext { + + @Override + public String traceId() { + return ""; + } + + @Override + public String parentId() { + return ""; + } + + @Override + public String spanId() { + return ""; + } + + @Override + public Boolean sampled() { + return false; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleSpan.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleSpan.java new file mode 100644 index 000000000..86cdfd169 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleSpan.java @@ -0,0 +1,91 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.deployer; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.TraceContext; + +/** + * A noop implementation. Does nothing. + * + * @author Marcin Grzejszczak + * @since 3.0.0 + */ +class SimpleSpan implements Span { + + Map tags = new HashMap<>(); + + boolean started; + + boolean ended; + + @Override + public boolean isNoop() { + return true; + } + + @Override + public TraceContext context() { + return new NoOpTraceContext(); + } + + @Override + public Span start() { + this.started = true; + return this; + } + + @Override + public Span name(String name) { + return this; + } + + @Override + public Span event(String value) { + return this; + } + + @Override + public Span tag(String key, String value) { + this.tags.put(key, value); + return this; + } + + @Override + public Span error(Throwable throwable) { + return this; + } + + @Override + public void end() { + this.ended = true; + } + + @Override + public void abandon() { + + } + + @Override + public Span remoteServiceName(String remoteServiceName) { + return this; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleTracer.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleTracer.java new file mode 100644 index 000000000..0b56fc984 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleTracer.java @@ -0,0 +1,118 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.deployer; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.assertj.core.api.BDDAssertions; + +import org.springframework.cloud.sleuth.BaggageInScope; +import org.springframework.cloud.sleuth.ScopedSpan; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanCustomizer; +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.cloud.sleuth.Tracer; + +/** + * A noop implementation. Does nothing. + * + * @author Marcin Grzejszczak + * @since 3.0.0 + */ +class SimpleTracer implements Tracer { + + List spans = new ArrayList<>(); + + @Override + public Span nextSpan(Span parent) { + return new SimpleSpan(); + } + + SimpleSpan getOnlySpan() { + BDDAssertions.then(this.spans).hasSize(1); + SimpleSpan span = this.spans.get(0); + BDDAssertions.then(span.started).as("Span must be started").isTrue(); + BDDAssertions.then(span.ended).as("Span must be finished").isTrue(); + return span; + } + + @Override + public SpanInScope withSpan(Span span) { + return new NoOpSpanInScope(); + } + + @Override + public SpanCustomizer currentSpanCustomizer() { + return null; + } + + @Override + public Span currentSpan() { + return new SimpleSpan(); + } + + @Override + public Span nextSpan() { + final SimpleSpan span = new SimpleSpan(); + this.spans.add(span); + return span; + } + + @Override + public ScopedSpan startScopedSpan(String name) { + return null; + } + + @Override + public Span.Builder spanBuilder() { + return null; + } + + @Override + public TraceContext.Builder traceContextBuilder() { + return null; + } + + @Override + public Map getAllBaggage() { + return new HashMap<>(); + } + + @Override + public BaggageInScope getBaggage(String name) { + return null; + } + + @Override + public BaggageInScope getBaggage(TraceContext traceContext, String name) { + return null; + } + + @Override + public BaggageInScope createBaggage(String name) { + return null; + } + + @Override + public BaggageInScope createBaggage(String name, String value) { + return null; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployerTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployerTests.java new file mode 100644 index 000000000..c6b50b62e --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployerTests.java @@ -0,0 +1,144 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.deployer; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.Test; +import org.mockito.BDDMockito; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.support.StaticListableBeanFactory; +import org.springframework.cloud.deployer.spi.app.AppDeployer; +import org.springframework.cloud.deployer.spi.app.AppScaleRequest; +import org.springframework.cloud.deployer.spi.app.AppStatus; +import org.springframework.cloud.deployer.spi.core.AppDefinition; +import org.springframework.cloud.deployer.spi.core.AppDeploymentRequest; +import org.springframework.core.env.Environment; +import org.springframework.core.io.PathResource; +import org.springframework.mock.env.MockEnvironment; + +class TraceAppDeployerTests { + + SimpleTracer simpleTracer = new SimpleTracer(); + + AppDeployer delegate = BDDMockito.mock(AppDeployer.class); + + TraceAppDeployer traceAppDeployer = new TraceAppDeployer(this.delegate, beanFactory(), environment()); + + @Test + void should_trace_deploy() { + BDDMockito.given(this.delegate.statusReactive(BDDMockito.any())) + .willReturn(Mono.just(AppStatus.of("asd").build())); + + this.traceAppDeployer.deploy(deploymentRequest()); + + BDDAssertions.then(this.simpleTracer.getOnlySpan().tags).isNotEmpty(); + BDDMockito.then(this.delegate).should().deploy(BDDMockito.any()); + } + + @Test + void should_trace_undeploy() { + BDDMockito.given(this.delegate.statusReactive(BDDMockito.any())) + .willReturn(Mono.just(AppStatus.of("asd").build())); + + this.traceAppDeployer.undeploy("asd"); + + BDDAssertions.then(this.simpleTracer.getOnlySpan().tags).isNotEmpty(); + BDDMockito.then(this.delegate).should().undeploy(BDDMockito.any()); + } + + @Test + void should_trace_status() { + this.traceAppDeployer.status("asd"); + + BDDAssertions.then(this.simpleTracer.getOnlySpan().tags).isNotEmpty(); + BDDMockito.then(this.delegate).should().status(BDDMockito.any()); + } + + @Test + void should_trace_status_reactive() { + BDDMockito.given(this.delegate.statusReactive(BDDMockito.any())) + .willReturn(Mono.just(AppStatus.of("asd").build())); + + this.traceAppDeployer.statusReactive("asd").block(); + + BDDAssertions.then(this.simpleTracer.getOnlySpan().tags).isNotEmpty(); + BDDMockito.then(this.delegate).should().statusReactive(BDDMockito.any()); + } + + @Test + void should_trace_statuses_reactive() { + BDDMockito.given(this.delegate.statusesReactive(BDDMockito.any())) + .willReturn(Flux.just(AppStatus.of("asd").build())); + + this.traceAppDeployer.statusesReactive("asd").blockFirst(); + + BDDAssertions.then(this.simpleTracer.getOnlySpan().tags).isNotEmpty(); + BDDMockito.then(this.delegate).should().statusesReactive(BDDMockito.any()); + } + + @Test + void should_trace_log() { + this.traceAppDeployer.getLog("id"); + + BDDAssertions.then(this.simpleTracer.getOnlySpan().tags).isNotEmpty(); + BDDMockito.then(this.delegate).should().getLog(BDDMockito.any()); + } + + @Test + void should_trace_scale() { + this.traceAppDeployer.scale(new AppScaleRequest("asd", 2)); + + BDDAssertions.then(this.simpleTracer.getOnlySpan().tags).isNotEmpty(); + BDDMockito.then(this.delegate).should().scale(BDDMockito.any()); + } + + private AppDeploymentRequest deploymentRequest() { + return new AppDeploymentRequest(new AppDefinition("foo", new HashMap<>()), new PathResource("/"), + deploymentProps(), commandLineArgs()); + } + + private List commandLineArgs() { + return Arrays.asList("foo=bar1", "baz=bar2"); + } + + private Map deploymentProps() { + Map map = new HashMap<>(); + map.put("deployment1", "prop1"); + map.put("deployment2", "prop2"); + return map; + } + + private BeanFactory beanFactory() { + StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); + beanFactory.addBean("tracer", this.simpleTracer); + beanFactory.addBean("currentTraceContext", new NoOpCurrentTraceContext()); + return beanFactory; + } + + private Environment environment() { + return new MockEnvironment(); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingCallbackTest.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingCallbackTest.java new file mode 100644 index 000000000..44fc895c9 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingCallbackTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.kafka; + +import org.apache.kafka.clients.producer.Callback; +import org.apache.kafka.clients.producer.RecordMetadata; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; + +@ExtendWith(MockitoExtension.class) +public class KafkaTracingCallbackTest { + + @Mock + Tracer tracer; + + @Mock + Span span; + + @Mock + Callback callback; + + @Test + void should_call_on_completion_on_user_callback_success() { + KafkaTracingCallback tracingCallback = new KafkaTracingCallback(callback, tracer, span); + RecordMetadata recordMetadata = new RecordMetadata(null, 0, 0, 0, 0L, 0, 0); + + tracingCallback.onCompletion(recordMetadata, null); + + Mockito.verify(callback).onCompletion(eq(recordMetadata), isNull()); + } + + @Test + void should_call_on_completion_on_user_callback_error() { + KafkaTracingCallback tracingCallback = new KafkaTracingCallback(callback, tracer, span); + + tracingCallback.onCompletion(null, new RuntimeException()); + + Mockito.verify(callback).onCompletion(isNull(), any(RuntimeException.class)); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaConsumerTest.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaConsumerTest.java new file mode 100644 index 000000000..c04c22d72 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaConsumerTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.kafka; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.common.TopicPartition; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Answers; +import org.mockito.BDDMockito; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.cloud.sleuth.propagation.Propagator; + +import static org.mockito.ArgumentMatchers.eq; + +@ExtendWith(MockitoExtension.class) +public class TracingKafkaConsumerTest { + + @Mock + KafkaConsumer kafkaConsumer; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + Propagator propagator; + + @Test + void should_delegate_poll_calls() { + Duration pollTimeout = Duration.of(5, ChronoUnit.SECONDS); + ConsumerRecord record = new ConsumerRecord<>("topic", 0, 1, "test-key", "test-value"); + Map>> map = new HashMap<>(); + map.put(new TopicPartition("topic", 0), Collections.singletonList(record)); + ConsumerRecords records = new ConsumerRecords<>(map); + BDDMockito.given(kafkaConsumer.poll(pollTimeout)).willReturn(records); + TracingKafkaConsumer tracingKafkaConsumer = new TracingKafkaConsumer<>(kafkaConsumer, + propagator, new TracingKafkaPropagatorGetter()); + + tracingKafkaConsumer.poll(pollTimeout); + + Mockito.verify(kafkaConsumer).poll(eq(pollTimeout)); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducerTest.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducerTest.java new file mode 100644 index 000000000..dcb3bab8b --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducerTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.kafka; + +import org.apache.kafka.clients.producer.Callback; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Answers; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.propagation.Propagator; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; + +@ExtendWith(MockitoExtension.class) +public class TracingKafkaProducerTest { + + @Mock + KafkaProducer kafkaProducer; + + @Mock + Propagator propagator; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + Tracer tracer; + + @Test + void should_delegate_send_calls() { + ProducerRecord testRecord = new ProducerRecord<>("test", "test"); + Callback callback = (record, ex) -> { + }; + TracingKafkaProducer tracingKafkaProducer = new TracingKafkaProducer<>(kafkaProducer, tracer, + propagator, new TracingKafkaPropagatorSetter()); + + tracingKafkaProducer.send(testRecord, callback); + + Mockito.verify(kafkaProducer).send(eq(testRecord), any()); + } + + @Test + void should_wrap_user_callback_on_send() { + ProducerRecord testRecord = new ProducerRecord<>("test", "test"); + Callback callback = (record, ex) -> { + }; + TracingKafkaProducer tracingKafkaProducer = new TracingKafkaProducer<>(kafkaProducer, tracer, + propagator, new TracingKafkaPropagatorSetter()); + + tracingKafkaProducer.send(testRecord, callback); + + ArgumentCaptor callbackArgument = ArgumentCaptor.forClass(KafkaTracingCallback.class); + Mockito.verify(kafkaProducer).send(any(), callbackArgument.capture()); + BDDAssertions.then(callbackArgument.getValue()).isNotNull(); + BDDAssertions.then(ReflectionTestUtils.getField(callbackArgument.getValue(), "callback")).isEqualTo(callback); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaReceiverTest.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaReceiverTest.java new file mode 100644 index 000000000..6707aeee6 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaReceiverTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.kafka; + +import java.util.function.Predicate; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Answers; +import org.mockito.BDDMockito; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import reactor.core.publisher.Flux; +import reactor.kafka.receiver.KafkaReceiver; +import reactor.kafka.receiver.ReceiverOffset; +import reactor.kafka.receiver.ReceiverRecord; +import reactor.test.StepVerifier; + +import org.springframework.cloud.sleuth.propagation.Propagator; + +@ExtendWith(MockitoExtension.class) +public class TracingKafkaReceiverTest { + + @Mock + KafkaReceiver kafkaReceiver; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + Propagator propagator; + + @Test + void should_delegate_receive_calls() { + ReceiverOffset receiverOffset = BDDMockito.mock(ReceiverOffset.class); + ConsumerRecord record = new ConsumerRecord<>("topic", 0, 1, "test-key", "test-value"); + ReceiverRecord receiverRecord = new ReceiverRecord<>(record, receiverOffset); + BDDMockito.given(kafkaReceiver.receive()).willReturn(Flux.just(receiverRecord)); + TracingKafkaReceiver tracingKafkaReceiver = new TracingKafkaReceiver<>(kafkaReceiver, + propagator, new TracingKafkaPropagatorGetter()); + + StepVerifier.create(tracingKafkaReceiver.receive()).expectNextMatches(Predicate.isEqual(receiverRecord)) + .verifyComplete(); + + Mockito.verify(kafkaReceiver).receive(); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapperTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapperTests.java index d42fa50e3..45973688c 100644 --- a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapperTests.java +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapperTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -18,6 +18,9 @@ package org.springframework.cloud.sleuth.instrument.messaging; import org.junit.jupiter.api.Test; +import org.springframework.mock.env.MockEnvironment; + +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.BDDAssertions.then; class TraceFunctionAroundWrapperTests { @@ -33,4 +36,34 @@ class TraceFunctionAroundWrapperTests { then(wrapper.functionToDestinationCache).isEmpty(); } + @Test + void should_point_to_proper_destination_when_working_with_function_definition() { + MockEnvironment mockEnvironment = new MockEnvironment(); + mockEnvironment.setProperty("spring.cloud.stream.bindings.marcin-in-0.destination", "oleg"); + mockEnvironment.setProperty("spring.cloud.stream.bindings.marcin-out-0.destination", "bob"); + TraceFunctionAroundWrapper wrapper = new TraceFunctionAroundWrapper(mockEnvironment, null, null, null, null); + + assertThat(wrapper.inputDestination("marcin")).isEqualTo("oleg"); + + wrapper.functionToDestinationCache.clear(); + + assertThat(wrapper.outputDestination("marcin")).isEqualTo("bob"); + } + + @Test + void should_point_to_proper_destination_when_working_with_remapped_functions() { + MockEnvironment mockEnvironment = new MockEnvironment(); + mockEnvironment.setProperty("spring.cloud.stream.function.bindings.marcin-in-0", "input"); + mockEnvironment.setProperty("spring.cloud.stream.bindings.input.destination", "oleg"); + mockEnvironment.setProperty("spring.cloud.stream.function.bindings.marcin-out-0", "output"); + mockEnvironment.setProperty("spring.cloud.stream.bindings.output.destination", "bob"); + TraceFunctionAroundWrapper wrapper = new TraceFunctionAroundWrapper(mockEnvironment, null, null, null, null); + + assertThat(wrapper.inputDestination("marcin")).isEqualTo("oleg"); + + wrapper.functionToDestinationCache.clear(); + + assertThat(wrapper.outputDestination("marcin")).isEqualTo("bob"); + } + } diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunctionHttpClientResponseTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunctionHttpClientResponseTests.java index a3108c5bd..be159e3a4 100644 --- a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunctionHttpClientResponseTests.java +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunctionHttpClientResponseTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessorTest.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessorTest.java index e7e2ef04d..d2f58bb7e 100644 --- a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessorTest.java +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilderTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilderTests.java new file mode 100644 index 000000000..92ccf81d7 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilderTests.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.feign; + +import feign.Client; +import feign.Feign; +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.beans.factory.BeanFactory; + +import static org.mockito.Mockito.mock; + +/** + * @author Julien Baillagou + */ +@ExtendWith(MockitoExtension.class) +public class SleuthFeignBuilderTests { + + @Mock + BeanFactory beanFactory; + + @Test + public void should_generate_feign_builder() { + BDDAssertions.then(SleuthFeignBuilder.builder(beanFactory)).isExactlyInstanceOf(Feign.Builder.class); + } + + @Test + public void should_generate_feign_builder_with_given_delegate() { + BDDAssertions.then(SleuthFeignBuilder.builder(beanFactory, mock(Client.class))) + .isExactlyInstanceOf(Feign.Builder.class); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignObjectWrapperTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignObjectWrapperTests.java index 6d51f0ac7..8dd2f1ccc 100644 --- a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignObjectWrapperTests.java +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignObjectWrapperTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/internal/EncodingUtilsTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/internal/EncodingUtilsTests.java new file mode 100644 index 000000000..3472e237f --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/internal/EncodingUtilsTests.java @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.internal; + +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.Test; + +class EncodingUtilsTests { + + @Test + void should_convert_back_and_forth_with_64bits() { + long[] fromString = EncodingUtils.fromString("7c6239a5ad0a4287"); + BDDAssertions.then(fromString).hasSize(1); + + String fromLong = EncodingUtils.fromLong(fromString[0]); + + BDDAssertions.then(fromLong).isEqualTo("7c6239a5ad0a4287"); + } + + @Test + void should_convert_back_and_forth_with_128bits() { + long[] fromString = EncodingUtils.fromString("596e1787feb110407c6239a5ad0a4287"); + BDDAssertions.then(fromString).hasSize(2); + String fromLong = EncodingUtils.fromLongs(fromString[0], fromString[1]); + + BDDAssertions.then(fromLong).isEqualTo("596e1787feb110407c6239a5ad0a4287"); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/internal/SleuthContextListenerTest.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/internal/SleuthContextListenerTest.java index 3237a30d9..10f283fa7 100644 --- a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/internal/SleuthContextListenerTest.java +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/internal/SleuthContextListenerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/pom.xml b/spring-cloud-sleuth-samples/pom.xml index 2289a3b7a..db7df8acb 100644 --- a/spring-cloud-sleuth-samples/pom.xml +++ b/spring-cloud-sleuth-samples/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml index 895d61229..14012ee1d 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleController.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleController.java index 368066e85..38c0e905e 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleController.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleController.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleFeignApplication.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleFeignApplication.java index c35052421..1b1e7ae11 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleFeignApplication.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleFeignApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/test/java/sample/SampleFeignApplicationTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/test/java/sample/SampleFeignApplicationTests.java index 12a162cb3..7bd844a5f 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/test/java/sample/SampleFeignApplicationTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/test/java/sample/SampleFeignApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml index 0a5c13aa4..75b4574a8 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.1.0-SNAPSHOT .. @@ -114,6 +114,7 @@ org.springframework.cloud spring-cloud-sleuth-sample-test-core + ${project.version} test diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleBackground.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleBackground.java index b1b50b9bd..d5ec87ac8 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleBackground.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleBackground.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleMessagingApplication.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleMessagingApplication.java index 34ea94c2d..e0b2021f9 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleMessagingApplication.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleMessagingApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleRequestResponse.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleRequestResponse.java index 86e1be23a..f7cad4401 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleRequestResponse.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleRequestResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleService.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleService.java index 0e30f4a9e..8672c58b1 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleService.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleService.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleSink.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleSink.java index 75c9b8c4b..e1d4c9545 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleSink.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleSink.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleTransformer.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleTransformer.java index d62f9740f..b24f0928b 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleTransformer.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/IntegrationTestZipkinSpanHandler.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/IntegrationTestZipkinSpanHandler.java index b5eb3cb35..5bce55167 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/IntegrationTestZipkinSpanHandler.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/IntegrationTestZipkinSpanHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java index 83bd7000f..15b06e31a 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -16,6 +16,7 @@ package integration; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -107,16 +108,19 @@ public class MessagingApplicationTests extends AbstractIntegrationTest { } private void thenThereIsAtLeastOneTagWithKey(String key) { - then(this.testSpanHandler.spans.stream().map(MutableSpan::tags).flatMap(m -> m.keySet().stream()) - .anyMatch(b -> b.equals(key))).isTrue(); + then(spans().stream().map(MutableSpan::tags).flatMap(m -> m.keySet().stream()).anyMatch(b -> b.equals(key))) + .isTrue(); + } + + private List spans() { + return new ArrayList<>(this.testSpanHandler.spans); } private void thenAllSpansHaveTraceIdEqualTo(long traceId) { String traceIdHex = Long.toHexString(traceId); - log.info("Stored spans: [\n" - + this.testSpanHandler.spans.stream().map(MutableSpan::toString).collect(Collectors.joining("\n")) + log.info("Stored spans: [\n" + spans().stream().map(MutableSpan::toString).collect(Collectors.joining("\n")) + "\n]"); - then(this.testSpanHandler.spans.stream().filter(span -> !span.traceId().equals(SpanUtil.idToHex(traceId))) + then(spans().stream().filter(span -> !span.traceId().equals(SpanUtil.idToHex(traceId))) .collect(Collectors.toList())).describedAs("All spans have same trace id [" + traceIdHex + "]") .isEmpty(); } @@ -130,8 +134,8 @@ public class MessagingApplicationTests extends AbstractIntegrationTest { // "http:/parent/" -> "message:messages" -> "http:/foo" (CS + CR) -> "http:/foo" // (SS) thenAllSpansArePresent(firstHttpSpan, eventSpans, lastHttpSpansParent, eventSentSpan, producerSpan); - List spans = this.testSpanHandler.spans; - then(spans).as("There were 7 spans").hasSize(7); + List spans = spans(); + then(spans).as("There were 6 spans").hasSize(6); log.info("Checking the parent child structure"); List> parentChild = spans.stream().filter(span -> span.parentId() != null).map(span -> { Optional any = spans.stream().filter(span1 -> span1.id().equals(span.parentId())).findAny(); @@ -146,21 +150,20 @@ public class MessagingApplicationTests extends AbstractIntegrationTest { } private Optional findLastHttpSpansParent() { - return this.testSpanHandler.spans.stream().filter(span -> "GET /".equals(span.name()) && span.kind() != null) - .findFirst(); + return spans().stream().filter(span -> "GET /".equals(span.name()) && span.kind() != null).findFirst(); } private Optional findSpanWithKind(Span.Kind kind) { - return this.testSpanHandler.spans.stream().filter(span -> kind.equals(span.kind())).findFirst(); + return spans().stream().filter(span -> kind.equals(span.kind())).findFirst(); } private List findAllEventRelatedSpans() { - return this.testSpanHandler.spans.stream().filter(span -> "send".equals(span.name()) && span.parentId() != null) + return spans().stream().filter(span -> "send".equals(span.name()) && span.parentId() != null) .collect(Collectors.toList()); } private Optional findFirstHttpRequestSpan() { - return this.testSpanHandler.spans.stream() + return spans().stream() // home is the name of the method .filter(span -> span.tags().values().stream().anyMatch("home"::equals)).findFirst(); } @@ -174,8 +177,7 @@ public class MessagingApplicationTests extends AbstractIntegrationTest { log.info("Event sent span " + eventSentSpan); log.info("Event received span " + eventReceivedSpan); log.info("Last http span " + lastHttpSpan); - log.info("All found spans \n" - + this.testSpanHandler.spans.stream().map(MutableSpan::toString).collect(Collectors.joining("\n"))); + log.info("All found spans \n" + spans().stream().map(MutableSpan::toString).collect(Collectors.joining("\n"))); then(firstHttpSpan.isPresent()).isTrue(); then(eventSpans).isNotEmpty(); then(eventSentSpan.isPresent()).isTrue(); diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/sample/SampleMessagingApplicationTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/sample/SampleMessagingApplicationTests.java index e5c9dfc24..a3d57d5ac 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/sample/SampleMessagingApplicationTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/sample/SampleMessagingApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml index 0fee3fcd6..438700c2d 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.1.0-SNAPSHOT .. @@ -38,36 +38,6 @@ true - - - - - - maven-deploy-plugin - - true - - - - - - - - org.codehaus.mojo - animal-sniffer-maven-plugin - 1.19 - - true - - org.codehaus.mojo.signature - java17 - 1.0 - - - - - - org.springframework.boot diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AbstractIntegrationTest.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AbstractIntegrationTest.java index 6eee50f8a..56e9f3139 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AbstractIntegrationTest.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AbstractIntegrationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AssertingRestTemplate.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AssertingRestTemplate.java index 3523fb2e2..b9e6a8434 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AssertingRestTemplate.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AssertingRestTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/RequestSendingRunnable.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/RequestSendingRunnable.java index 9ea56f52f..ebc380025 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/RequestSendingRunnable.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/RequestSendingRunnable.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/SpanUtil.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/SpanUtil.java index a7aae9e70..b85ac1ca0 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/SpanUtil.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/SpanUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml index e6c243c69..2114093a3 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.1.0-SNAPSHOT .. @@ -105,6 +105,7 @@ org.springframework.cloud spring-cloud-sleuth-sample-test-core + ${project.version} test diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/main/java/sample/GreetingController.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/main/java/sample/GreetingController.java index d7e8ce1ad..846177aef 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/main/java/sample/GreetingController.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/main/java/sample/GreetingController.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/main/java/sample/SampleWebsocketApplication.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/main/java/sample/SampleWebsocketApplication.java index 385fd67db..f6b7d2d76 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/main/java/sample/SampleWebsocketApplication.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/main/java/sample/SampleWebsocketApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/test/java/sample/SampleWebsocketApplicationTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/test/java/sample/SampleWebsocketApplicationTests.java index 1b158cecd..96694b822 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/test/java/sample/SampleWebsocketApplicationTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/test/java/sample/SampleWebsocketApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml index 900bcc2d8..85e6b2855 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.1.0-SNAPSHOT .. @@ -101,6 +101,7 @@ org.springframework.cloud spring-cloud-sleuth-sample-test-core + ${project.version} test diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleBackground.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleBackground.java index b1b50b9bd..d5ec87ac8 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleBackground.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleBackground.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleController.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleController.java index da57c5d9c..ff63be4a2 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleController.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleController.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleZipkinApplication.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleZipkinApplication.java index 2501b7ca7..6c53f564b 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleZipkinApplication.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleZipkinApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/ZipkinTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/ZipkinTests.java index 4496ff4e1..0c36b93c5 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/ZipkinTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/ZipkinTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/sample/SampleSleuthApplicationTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/sample/SampleSleuthApplicationTests.java index 573330903..46c04be69 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/sample/SampleSleuthApplicationTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/sample/SampleSleuthApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml index 26571c0ec..e4bb17d81 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleBackground.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleBackground.java index 94e408cbe..246af95b0 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleBackground.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleBackground.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleController.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleController.java index 95656d8db..d63f7f36b 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleController.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleController.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleSleuthApplication.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleSleuthApplication.java index 080c50c06..999bb1176 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleSleuthApplication.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleSleuthApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/test/java/sample/SampleSleuthApplicationTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/test/java/sample/SampleSleuthApplicationTests.java index 6ca65a795..3e9d32a27 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/test/java/sample/SampleSleuthApplicationTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/test/java/sample/SampleSleuthApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/pom.xml b/spring-cloud-sleuth-zipkin/pom.xml index f11729614..69642bfdb 100644 --- a/spring-cloud-sleuth-zipkin/pom.xml +++ b/spring-cloud-sleuth-zipkin/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/CachingZipkinUrlExtractor.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/CachingZipkinUrlExtractor.java index 14c027d4a..506301a41 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/CachingZipkinUrlExtractor.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/CachingZipkinUrlExtractor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/DefaultEndpointLocator.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/DefaultEndpointLocator.java index 9ed33285c..7f4b59b1b 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/DefaultEndpointLocator.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/DefaultEndpointLocator.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/DefaultZipkinRestTemplateCustomizer.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/DefaultZipkinRestTemplateCustomizer.java index 7cae4b7f7..a803cb8df 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/DefaultZipkinRestTemplateCustomizer.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/DefaultZipkinRestTemplateCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/EndpointLocator.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/EndpointLocator.java index 3ecadb6d2..98be515d7 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/EndpointLocator.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/EndpointLocator.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/LoadBalancerClientZipkinLoadBalancer.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/LoadBalancerClientZipkinLoadBalancer.java index 342dbf4b2..1d2dee886 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/LoadBalancerClientZipkinLoadBalancer.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/LoadBalancerClientZipkinLoadBalancer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/RestTemplateSender.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/RestTemplateSender.java index 07cc9dee5..72db2db33 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/RestTemplateSender.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/RestTemplateSender.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -19,6 +19,7 @@ package org.springframework.cloud.sleuth.zipkin2; import java.io.IOException; import java.net.URI; import java.util.List; +import java.util.Objects; import zipkin2.Call; import zipkin2.Callback; @@ -59,20 +60,28 @@ public class RestTemplateSender extends Sender { */ transient boolean closeCalled; + @Deprecated public RestTemplateSender(RestTemplate restTemplate, String baseUrl, BytesEncoder encoder) { + this(restTemplate, baseUrl, "", encoder); + } + + public RestTemplateSender(RestTemplate restTemplate, String baseUrl, String apiPath, BytesEncoder encoder) { this.restTemplate = restTemplate; this.encoding = encoder.encoding(); if (encoder.equals(JSON_V2)) { this.mediaType = MediaType.APPLICATION_JSON; - this.url = baseUrl + (baseUrl.endsWith("/") ? "" : "/") + "api/v2/spans"; + this.url = buildUrlWithCustomPathIfNecessary(baseUrl, apiPath, + baseUrl + (baseUrl.endsWith("/") ? "" : "/") + "api/v2/spans"); } else if (this.encoding == Encoding.PROTO3) { this.mediaType = MediaType.parseMediaType("application/x-protobuf"); - this.url = baseUrl + (baseUrl.endsWith("/") ? "" : "/") + "api/v2/spans"; + this.url = buildUrlWithCustomPathIfNecessary(baseUrl, apiPath, + baseUrl + (baseUrl.endsWith("/") ? "" : "/") + "api/v2/spans"); } else if (this.encoding == Encoding.JSON) { this.mediaType = MediaType.APPLICATION_JSON; - this.url = baseUrl + (baseUrl.endsWith("/") ? "" : "/") + "api/v1/spans"; + this.url = buildUrlWithCustomPathIfNecessary(baseUrl, apiPath, + baseUrl + (baseUrl.endsWith("/") ? "" : "/") + "api/v1/spans"); } else { throw new UnsupportedOperationException("Unsupported encoding: " + this.encoding.name()); @@ -80,6 +89,16 @@ public class RestTemplateSender extends Sender { this.messageEncoder = BytesMessageEncoder.forEncoding(this.encoding); } + private String buildUrlWithCustomPathIfNecessary(final String baseUrl, final String customApiPath, + final String defaultUrl) { + if (Objects.nonNull(customApiPath)) { + return baseUrl + + (baseUrl.endsWith("/") || customApiPath.startsWith("/") || customApiPath.isEmpty() ? "" : "/") + + customApiPath; + } + return defaultUrl; + } + @Override public Encoding encoding() { return this.encoding; diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/StaticInstanceZipkinLoadBalancer.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/StaticInstanceZipkinLoadBalancer.java index e7d271065..4daf356ba 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/StaticInstanceZipkinLoadBalancer.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/StaticInstanceZipkinLoadBalancer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinLoadBalancer.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinLoadBalancer.java index fd9d9a003..70d28f03e 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinLoadBalancer.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinLoadBalancer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinProperties.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinProperties.java index 21233f7c5..14d150819 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinProperties.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -37,6 +37,13 @@ public class ZipkinProperties { */ private String baseUrl = "http://localhost:9411/"; + /** + * The API path to append to baseUrl (above) as suffix. This applies if you use other + * monitoring tools, such as New Relic. The trace API doesn't need the API path, so + * you can set it to blank ("") in the configuration. + */ + private String apiPath = null; + /** * If set to {@code false}, will treat the {@link ZipkinProperties#baseUrl} as a URL * always. @@ -84,6 +91,14 @@ public class ZipkinProperties { this.baseUrl = baseUrl; } + public String getApiPath() { + return this.apiPath; + } + + public void setApiPath(String apiPath) { + this.apiPath = apiPath; + } + public boolean isEnabled() { return this.enabled; } diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinRestTemplateCustomizer.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinRestTemplateCustomizer.java index 7bec010b2..e886fd736 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinRestTemplateCustomizer.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinRestTemplateCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinRestTemplateWrapper.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinRestTemplateWrapper.java index e1b5e2f33..d7879149a 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinRestTemplateWrapper.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinRestTemplateWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinUrlExtractor.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinUrlExtractor.java index 373ce4734..e6f0b2271 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinUrlExtractor.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinUrlExtractor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/RestTemplateSenderTest.java b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/RestTemplateSenderTest.java index 4cf08a4e1..bc201c16a 100644 --- a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/RestTemplateSenderTest.java +++ b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/RestTemplateSenderTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -50,7 +50,7 @@ public class RestTemplateSenderTest { String endpoint = this.server.url("/api/v2/spans").toString(); - RestTemplateSender sender = new RestTemplateSender(new RestTemplate(), this.endpoint, JSON_V2); + RestTemplateSender sender = new RestTemplateSender(new RestTemplate(), this.endpoint, null, JSON_V2); @AfterEach void clean() throws IOException { @@ -74,7 +74,7 @@ public class RestTemplateSenderTest { @Test public void proto3() throws Exception { this.server.enqueue(new MockResponse()); - this.sender = new RestTemplateSender(new RestTemplate(), this.endpoint, PROTO3); + this.sender = new RestTemplateSender(new RestTemplate(), this.endpoint, "", PROTO3); send(SPAN).execute(); @@ -85,6 +85,37 @@ public class RestTemplateSenderTest { assertThat(request.getBody().readByteArray()).containsExactly(SpanBytesEncoder.PROTO3.encode(SPAN)); } + @Test + public void testWhereApiIsSetNonEmpty() { + final String mockedApiPath = "/test/v2"; + final RestTemplateSender senderWithMockedApiPath = new RestTemplateSender(new RestTemplate(), this.endpoint, + mockedApiPath, JSON_V2); + + assertThat(senderWithMockedApiPath.toString()) + .isEqualTo("RestTemplateSender{" + this.endpoint + mockedApiPath + "}"); + } + + @Test + public void testWhereApiIsSetToEmpty() { + final String mockedApiPath = ""; + final RestTemplateSender senderWithMockedApiPath = new RestTemplateSender(new RestTemplate(), this.endpoint, + mockedApiPath, JSON_V2); + + assertThat(senderWithMockedApiPath.toString()).isEqualTo("RestTemplateSender{" + this.endpoint + "}"); + } + + /** + * The output of toString() on {@link Sender} implementations appears in thread names + * created by {@link AsyncZipkinSpanHandler}. Since thread names are likely to be + * exposed in logs and other monitoring tools, care should be taken to ensure the + * toString() output is a reasonable length and does not contain sensitive + * information. + */ + @Test + public void toStringContainsOnlySenderTypeAndEndpoint() { + assertThat(sender.toString()).isEqualTo("RestTemplateSender{" + this.endpoint + "/api/v2/spans}"); + } + Call send(Span... spans) { SpanBytesEncoder bytesEncoder = this.sender.encoding() == Encoding.JSON ? SpanBytesEncoder.JSON_V2 : SpanBytesEncoder.PROTO3; diff --git a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinRestTemplateSenderConfigurationTest.java b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinRestTemplateSenderConfigurationTest.java index 944372c95..be391247e 100644 --- a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinRestTemplateSenderConfigurationTest.java +++ b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinRestTemplateSenderConfigurationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-starter-sleuth/pom.xml b/spring-cloud-starter-sleuth/pom.xml index 13f2e124f..7cf9452ec 100644 --- a/spring-cloud-starter-sleuth/pom.xml +++ b/spring-cloud-starter-sleuth/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.1.0-SNAPSHOT .. spring-cloud-starter-sleuth diff --git a/tests/brave/pom.xml b/tests/brave/pom.xml index 87e09eb69..b5ea5e1c9 100644 --- a/tests/brave/pom.xml +++ b/tests/brave/pom.xml @@ -1,70 +1,75 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-tests-brave - pom - Spring Cloud Sleuth Brave Tests - Spring Cloud Sleuth Brave Tests - - - org.springframework.cloud - spring-cloud-sleuth-tests - 3.0.2-SNAPSHOT - .. - - - - spring-cloud-sleuth-instrumentation-annotation-tests - spring-cloud-sleuth-instrumentation-async-tests - spring-cloud-sleuth-instrumentation-baggage-tests - spring-cloud-sleuth-instrumentation-circuitbreaker-tests - spring-cloud-sleuth-instrumentation-feign-tests - spring-cloud-sleuth-instrumentation-gateway-tests - spring-cloud-sleuth-instrumentation-grpc-tests - spring-cloud-sleuth-instrumentation-lettuce-tests - spring-cloud-sleuth-instrumentation-messaging-tests - spring-cloud-sleuth-instrumentation-mvc-tests - spring-cloud-sleuth-instrumentation-quartz-tests - spring-cloud-sleuth-instrumentation-reactor-tests - spring-cloud-sleuth-instrumentation-rxjava-tests - spring-cloud-sleuth-instrumentation-scheduling-tests - spring-cloud-sleuth-instrumentation-webflux-tests - spring-cloud-sleuth-zipkin-tests - - - - - - - - maven-deploy-plugin - - true - - - - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-tests-brave + pom + Spring Cloud Sleuth Brave Tests + Spring Cloud Sleuth Brave Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests + 3.1.0-SNAPSHOT + .. + + + + spring-cloud-sleuth-instrumentation-annotation-tests + spring-cloud-sleuth-instrumentation-async-tests + spring-cloud-sleuth-instrumentation-baggage-tests + spring-cloud-sleuth-instrumentation-config-server-tests + spring-cloud-sleuth-instrumentation-circuitbreaker-tests + spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests + spring-cloud-sleuth-instrumentation-feign-tests + spring-cloud-sleuth-instrumentation-gateway-tests + spring-cloud-sleuth-instrumentation-grpc-tests + spring-cloud-sleuth-instrumentation-kafka-tests + spring-cloud-sleuth-instrumentation-lettuce-tests + spring-cloud-sleuth-instrumentation-messaging-tests + spring-cloud-sleuth-instrumentation-mvc-tests + spring-cloud-sleuth-instrumentation-quartz-tests + spring-cloud-sleuth-instrumentation-reactor-tests + spring-cloud-sleuth-instrumentation-rxjava-tests + spring-cloud-sleuth-instrumentation-scheduling-tests + spring-cloud-sleuth-instrumentation-task-tests + spring-cloud-sleuth-instrumentation-webflux-tests + spring-cloud-sleuth-instrumentation-rsocket-tests + spring-cloud-sleuth-zipkin-tests + + + + + + + + maven-deploy-plugin + + true + + + + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml index 67d7fd14e..2fb76b9da 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml @@ -1,85 +1,84 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-instrumentation-annotation-tests - jar - Spring Cloud Sleuth Brave Annotation Instrumentation Tests - Spring Cloud Sleuth Brave Annotation Instrumentation Tests - - - org.springframework.cloud - spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT - .. - - - - true - - - - - - - maven-deploy-plugin - - true - - - - - - - - org.springframework.cloud - spring-cloud-sleuth-tests-common - ${project.version} - - - org.springframework.boot - spring-boot-starter-aop - - - org.springframework.boot - spring-boot-starter-webflux - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.boot - spring-boot-starter-test - - - io.zipkin.brave - brave-tests - - - org.awaitility - awaitility - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-annotation-tests + jar + Spring Cloud Sleuth Brave Annotation Instrumentation Tests + Spring Cloud Sleuth Brave Annotation Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.cloud + spring-cloud-sleuth-tests-common + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/NullSpanTagAnnotationHandlerTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/NullSpanTagAnnotationHandlerTests.java index 824d45e15..644963551 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/NullSpanTagAnnotationHandlerTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/NullSpanTagAnnotationHandlerTests.java @@ -1,53 +1,53 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.annotation; - -import brave.sampler.Sampler; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; -import org.springframework.cloud.sleuth.test.TestSpanHandler; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.ContextConfiguration; - -@SpringBootTest -@ContextConfiguration(classes = NullSpanTagAnnotationHandlerTests.Config.class) -public class NullSpanTagAnnotationHandlerTests - extends org.springframework.cloud.sleuth.instrument.annotation.NullSpanTagAnnotationHandlerTests { - - @Configuration(proxyBeanMethods = false) - static class Config { - - @Bean - TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { - return new BraveTestSpanHandler(testSpanHandler); - } - - @Bean - Sampler alwaysSampler() { - return Sampler.ALWAYS_SAMPLE; - } - - @Bean - brave.test.TestSpanHandler braveTestSpanHandler() { - return new brave.test.TestSpanHandler(); - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.annotation; + +import brave.sampler.Sampler; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +@SpringBootTest +@ContextConfiguration(classes = NullSpanTagAnnotationHandlerTests.Config.class) +public class NullSpanTagAnnotationHandlerTests + extends org.springframework.cloud.sleuth.instrument.annotation.NullSpanTagAnnotationHandlerTests { + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorAspectFluxTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorAspectFluxTests.java index f1c745655..8000e99db 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorAspectFluxTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorAspectFluxTests.java @@ -1,61 +1,61 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.annotation; - -import brave.sampler.Sampler; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.TraceContext; -import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; -import org.springframework.cloud.sleuth.brave.bridge.BraveAccessor; -import org.springframework.cloud.sleuth.test.TestSpanHandler; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.ContextConfiguration; - -@SpringBootTest -@ContextConfiguration(classes = SleuthSpanCreatorAspectFluxTests.Config.class) -public class SleuthSpanCreatorAspectFluxTests - extends org.springframework.cloud.sleuth.instrument.annotation.SleuthSpanCreatorAspectFluxTests { - - @Override - public TraceContext traceContext() { - return BraveAccessor - .traceContext(brave.propagation.TraceContext.newBuilder().traceId(1).spanId(2).sampled(true).build()); - } - - @Configuration(proxyBeanMethods = false) - static class Config { - - @Bean - TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { - return new BraveTestSpanHandler(testSpanHandler); - } - - @Bean - Sampler alwaysSampler() { - return Sampler.ALWAYS_SAMPLE; - } - - @Bean - brave.test.TestSpanHandler braveTestSpanHandler() { - return new brave.test.TestSpanHandler(); - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.annotation; + +import brave.sampler.Sampler; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.cloud.sleuth.brave.bridge.BraveAccessor; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +@SpringBootTest +@ContextConfiguration(classes = SleuthSpanCreatorAspectFluxTests.Config.class) +public class SleuthSpanCreatorAspectFluxTests + extends org.springframework.cloud.sleuth.instrument.annotation.SleuthSpanCreatorAspectFluxTests { + + @Override + public TraceContext traceContext() { + return BraveAccessor + .traceContext(brave.propagation.TraceContext.newBuilder().traceId(1).spanId(2).sampled(true).build()); + } + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorAspectMonoTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorAspectMonoTests.java index 82a2862c1..736182114 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorAspectMonoTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorAspectMonoTests.java @@ -1,53 +1,53 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.annotation; - -import brave.sampler.Sampler; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; -import org.springframework.cloud.sleuth.test.TestSpanHandler; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.ContextConfiguration; - -@SpringBootTest -@ContextConfiguration(classes = SleuthSpanCreatorAspectMonoTests.Config.class) -public class SleuthSpanCreatorAspectMonoTests - extends org.springframework.cloud.sleuth.instrument.annotation.SleuthSpanCreatorAspectMonoTests { - - @Configuration(proxyBeanMethods = false) - static class Config { - - @Bean - TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { - return new BraveTestSpanHandler(testSpanHandler); - } - - @Bean - Sampler alwaysSampler() { - return Sampler.ALWAYS_SAMPLE; - } - - @Bean - brave.test.TestSpanHandler braveTestSpanHandler() { - return new brave.test.TestSpanHandler(); - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.annotation; + +import brave.sampler.Sampler; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +@SpringBootTest +@ContextConfiguration(classes = SleuthSpanCreatorAspectMonoTests.Config.class) +public class SleuthSpanCreatorAspectMonoTests + extends org.springframework.cloud.sleuth.instrument.annotation.SleuthSpanCreatorAspectMonoTests { + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorAspectNegativeTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorAspectNegativeTests.java index 13756ad38..c4154df84 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorAspectNegativeTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorAspectNegativeTests.java @@ -1,53 +1,53 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.annotation; - -import brave.sampler.Sampler; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; -import org.springframework.cloud.sleuth.test.TestSpanHandler; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.ContextConfiguration; - -@SpringBootTest -@ContextConfiguration(classes = SleuthSpanCreatorAspectNegativeTests.Config.class) -public class SleuthSpanCreatorAspectNegativeTests - extends org.springframework.cloud.sleuth.instrument.annotation.SleuthSpanCreatorAspectNegativeTests { - - @Configuration(proxyBeanMethods = false) - static class Config { - - @Bean - TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { - return new BraveTestSpanHandler(testSpanHandler); - } - - @Bean - Sampler alwaysSampler() { - return Sampler.ALWAYS_SAMPLE; - } - - @Bean - brave.test.TestSpanHandler braveTestSpanHandler() { - return new brave.test.TestSpanHandler(); - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.annotation; + +import brave.sampler.Sampler; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +@SpringBootTest +@ContextConfiguration(classes = SleuthSpanCreatorAspectNegativeTests.Config.class) +public class SleuthSpanCreatorAspectNegativeTests + extends org.springframework.cloud.sleuth.instrument.annotation.SleuthSpanCreatorAspectNegativeTests { + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorAspectTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorAspectTests.java index 1b457deea..031b3990c 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorAspectTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorAspectTests.java @@ -1,53 +1,53 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.annotation; - -import brave.sampler.Sampler; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; -import org.springframework.cloud.sleuth.test.TestSpanHandler; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.ContextConfiguration; - -@SpringBootTest -@ContextConfiguration(classes = SleuthSpanCreatorAspectTests.Config.class) -public class SleuthSpanCreatorAspectTests - extends org.springframework.cloud.sleuth.instrument.annotation.SleuthSpanCreatorAspectTests { - - @Configuration(proxyBeanMethods = false) - static class Config { - - @Bean - TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { - return new BraveTestSpanHandler(testSpanHandler); - } - - @Bean - Sampler alwaysSampler() { - return Sampler.ALWAYS_SAMPLE; - } - - @Bean - brave.test.TestSpanHandler braveTestSpanHandler() { - return new brave.test.TestSpanHandler(); - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.annotation; + +import brave.sampler.Sampler; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +@SpringBootTest +@ContextConfiguration(classes = SleuthSpanCreatorAspectTests.Config.class) +public class SleuthSpanCreatorAspectTests + extends org.springframework.cloud.sleuth.instrument.annotation.SleuthSpanCreatorAspectTests { + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorCircularDependencyTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorCircularDependencyTests.java index 29b03356c..a9e9c13cd 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorCircularDependencyTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SleuthSpanCreatorCircularDependencyTests.java @@ -1,53 +1,53 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.annotation; - -import brave.sampler.Sampler; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; -import org.springframework.cloud.sleuth.test.TestSpanHandler; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.ContextConfiguration; - -@SpringBootTest -@ContextConfiguration(classes = SleuthSpanCreatorCircularDependencyTests.Config.class) -public class SleuthSpanCreatorCircularDependencyTests - extends org.springframework.cloud.sleuth.instrument.annotation.SleuthSpanCreatorCircularDependencyTests { - - @Configuration(proxyBeanMethods = false) - static class Config { - - @Bean - TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { - return new BraveTestSpanHandler(testSpanHandler); - } - - @Bean - Sampler alwaysSampler() { - return Sampler.ALWAYS_SAMPLE; - } - - @Bean - brave.test.TestSpanHandler braveTestSpanHandler() { - return new brave.test.TestSpanHandler(); - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.annotation; + +import brave.sampler.Sampler; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +@SpringBootTest +@ContextConfiguration(classes = SleuthSpanCreatorCircularDependencyTests.Config.class) +public class SleuthSpanCreatorCircularDependencyTests + extends org.springframework.cloud.sleuth.instrument.annotation.SleuthSpanCreatorCircularDependencyTests { + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SpanTagAnnotationHandlerTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SpanTagAnnotationHandlerTests.java index 0147f2538..9596b320e 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SpanTagAnnotationHandlerTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/src/test/java/org/springframework/cloud/sleuth/brave/annotation/SpanTagAnnotationHandlerTests.java @@ -1,53 +1,53 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.annotation; - -import brave.sampler.Sampler; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; -import org.springframework.cloud.sleuth.test.TestSpanHandler; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.ContextConfiguration; - -@SpringBootTest -@ContextConfiguration(classes = SpanTagAnnotationHandlerTests.Config.class) -public class SpanTagAnnotationHandlerTests - extends org.springframework.cloud.sleuth.instrument.annotation.SpanTagAnnotationHandlerTests { - - @Configuration(proxyBeanMethods = false) - static class Config { - - @Bean - TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { - return new BraveTestSpanHandler(testSpanHandler); - } - - @Bean - Sampler alwaysSampler() { - return Sampler.ALWAYS_SAMPLE; - } - - @Bean - brave.test.TestSpanHandler braveTestSpanHandler() { - return new brave.test.TestSpanHandler(); - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.annotation; + +import brave.sampler.Sampler; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +@SpringBootTest +@ContextConfiguration(classes = SpanTagAnnotationHandlerTests.Config.class) +public class SpanTagAnnotationHandlerTests + extends org.springframework.cloud.sleuth.instrument.annotation.SpanTagAnnotationHandlerTests { + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml index c8a5adf90..79ad224a3 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml @@ -1,81 +1,81 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-instrumentation-async-tests - jar - Spring Cloud Sleuth Brave Async Instrumentation Tests - Spring Cloud Sleuth Brave Async Instrumentation Tests - - - org.springframework.cloud - spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT - .. - - - - true - - - - - - - maven-deploy-plugin - - true - - - - - - - - ${project.groupId} - spring-cloud-sleuth-tests-common - ${project.version} - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.boot - spring-boot-starter-test - - - io.zipkin.brave - brave-tests - - - org.awaitility - awaitility - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-async-tests + jar + Spring Cloud Sleuth Brave Async Instrumentation Tests + Spring Cloud Sleuth Brave Async Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + ${project.groupId} + spring-cloud-sleuth-tests-common + ${project.version} + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/AsyncDisabledTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/AsyncDisabledTests.java index 0b3519a54..f92f4e442 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/AsyncDisabledTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/AsyncDisabledTests.java @@ -1,24 +1,24 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.instrument.async; - -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) -public class AsyncDisabledTests extends org.springframework.cloud.sleuth.instrument.async.AsyncDisabledTests { - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async; + +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) +public class AsyncDisabledTests extends org.springframework.cloud.sleuth.instrument.async.AsyncDisabledTests { + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/LazyTraceThreadPoolTaskSchedulerTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/LazyTraceThreadPoolTaskSchedulerTests.java index 2cd3c17e3..64808cd2f 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/LazyTraceThreadPoolTaskSchedulerTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/LazyTraceThreadPoolTaskSchedulerTests.java @@ -1,35 +1,35 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.instrument.async; - -import org.springframework.cloud.sleuth.brave.BraveTestTracing; -import org.springframework.cloud.sleuth.test.TestTracingAware; - -public class LazyTraceThreadPoolTaskSchedulerTests - extends org.springframework.cloud.sleuth.instrument.async.LazyTraceThreadPoolTaskSchedulerTests { - - BraveTestTracing testTracing; - - @Override - public TestTracingAware tracerTest() { - if (this.testTracing == null) { - this.testTracing = new BraveTestTracing(); - } - return this.testTracing; - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +public class LazyTraceThreadPoolTaskSchedulerTests + extends org.springframework.cloud.sleuth.instrument.async.LazyTraceThreadPoolTaskSchedulerTests { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceAsyncAspectTest.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceAsyncAspectTest.java index 262b597c7..21b68cd06 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceAsyncAspectTest.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceAsyncAspectTest.java @@ -1,37 +1,37 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.instrument.async; - -import org.springframework.cloud.sleuth.brave.BraveTestTracing; -import org.springframework.cloud.sleuth.test.TestTracingAware; - -/** - * @author Marcin Grzejszczak - */ -public class TraceAsyncAspectTest extends org.springframework.cloud.sleuth.instrument.async.TraceAsyncAspectTest { - - BraveTestTracing testTracing; - - @Override - public TestTracingAware tracerTest() { - if (this.testTracing == null) { - this.testTracing = new BraveTestTracing(); - } - return this.testTracing; - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +/** + * @author Marcin Grzejszczak + */ +public class TraceAsyncAspectTest extends org.springframework.cloud.sleuth.instrument.async.TraceAsyncAspectTest { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceAsyncIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceAsyncIntegrationTests.java index 9fe4da341..550b0b510 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceAsyncIntegrationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceAsyncIntegrationTests.java @@ -1,161 +1,158 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.instrument.async; - -import brave.Span; -import brave.SpanCustomizer; -import brave.Tracer; -import brave.handler.MutableSpan; -import brave.handler.SpanHandler; -import brave.propagation.CurrentTraceContext; -import brave.propagation.TraceContext; -import brave.test.IntegrationTestSpanHandler; -import org.junit.ClassRule; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.SpanName; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.annotation.Async; -import org.springframework.scheduling.annotation.EnableAsync; -import org.springframework.test.annotation.DirtiesContext; - -import static org.assertj.core.api.Assertions.assertThat; - -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, - classes = { TraceAsyncIntegrationTests.TraceAsyncITestConfiguration.class }) -@DirtiesContext // flakey otherwise -public class TraceAsyncIntegrationTests { - - private static final Logger log = LoggerFactory.getLogger(TraceAsyncIntegrationTests.class); - - @ClassRule - public static IntegrationTestSpanHandler spans = new IntegrationTestSpanHandler(); - - TraceContext context = TraceContext.newBuilder().traceId(1).spanId(2).sampled(true).build(); - - @Autowired - AsyncLogic asyncLogic; - - @Autowired - CurrentTraceContext currentTraceContext; - - @Autowired - Tracer tracer; - - @Test - public void should_set_span_on_an_async_annotated_method() { - Span parent = tracer.joinSpan(context); - try (Tracer.SpanInScope ws = tracer.withSpanInScope(parent.start())) { - log.info("HELLO"); - asyncLogic.invokeAsync(); - - MutableSpan span = takeDesirableSpan("invoke-async"); - assertThat(span.name()).isEqualTo("invoke-async"); - assertThat(span.containsAnnotation("@Async")).isTrue(); - assertThat(span.tags()).containsEntry("class", "AsyncLogic").containsEntry("method", "invokeAsync"); - - // continues the trace - assertThat(span.traceId()).isEqualTo(context.traceIdString()); - } - finally { - parent.finish(); - } - - } - - @Test - public void should_set_span_with_custom_method_on_an_async_annotated_method() { - Span parent = tracer.joinSpan(context); - try (Tracer.SpanInScope ws = tracer.withSpanInScope(parent.start())) { - log.info("HELLO"); - asyncLogic.invokeAsync_customName(); - - MutableSpan span = takeDesirableSpan("foo"); - assertThat(span.name()).isEqualTo("foo"); - assertThat(span.containsAnnotation("@Async")).isTrue(); - assertThat(span.tags()).containsEntry("class", "AsyncLogic").containsEntry("method", - "invokeAsync_customName"); - - // continues the trace - assertThat(span.traceId()).isEqualTo(context.traceIdString()); - } - finally { - parent.finish(); - } - } - - // Sleuth adds spans named "async" with no tags when an executor is used. - // We don't want that one. - MutableSpan takeDesirableSpan(String name) { - MutableSpan span1 = spans.takeLocalSpan(); - MutableSpan span2 = spans.takeLocalSpan(); - log.info("Two last spans [" + span2 + "] and [" + span1 + "]"); - MutableSpan span = span1 != null && name.equals(span1.name()) ? span1 - : span2 != null && name.equals(span2.name()) ? span2 : null; - assertThat(span).as("No span with name <> was found", name).isNotNull(); - return span; - } - - @EnableAutoConfiguration - @EnableAsync - @Configuration(proxyBeanMethods = false) - static class TraceAsyncITestConfiguration { - - @Bean - AsyncLogic asyncLogic(SpanCustomizer customizer) { - return new AsyncLogic(customizer); - } - - @Bean - SpanHandler testSpanHandler() { - return spans; - } - - } - - static class AsyncLogic { - - private static final Logger log = LoggerFactory.getLogger(AsyncLogic.class); - - final SpanCustomizer customizer; - - AsyncLogic(SpanCustomizer customizer) { - this.customizer = customizer; - } - - @Async - public void invokeAsync() { - customizer.annotate("@Async"); // proves the handler is in scope - log.info("HELLO ASYNC"); - } - - @Async - @SpanName("foo") - public void invokeAsync_customName() { - customizer.annotate("@Async"); // proves the handler is in scope - log.info("HELLO ASYNC CUSTOM NAME"); - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async; + +import brave.Span; +import brave.SpanCustomizer; +import brave.Tracer; +import brave.handler.MutableSpan; +import brave.handler.SpanHandler; +import brave.propagation.CurrentTraceContext; +import brave.propagation.TraceContext; +import brave.test.IntegrationTestSpanHandler; +import org.junit.ClassRule; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.SpanName; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.test.annotation.DirtiesContext; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, + classes = { TraceAsyncIntegrationTests.TraceAsyncITestConfiguration.class }) +@DirtiesContext // flakey otherwise +public class TraceAsyncIntegrationTests { + + private static final Logger log = LoggerFactory.getLogger(TraceAsyncIntegrationTests.class); + + @ClassRule + public static IntegrationTestSpanHandler spans = new IntegrationTestSpanHandler(); + + TraceContext context = TraceContext.newBuilder().traceId(1).spanId(2).sampled(true).build(); + + @Autowired + AsyncLogic asyncLogic; + + @Autowired + CurrentTraceContext currentTraceContext; + + @Autowired + Tracer tracer; + + @Test + public void should_set_span_on_an_async_annotated_method() { + Span parent = tracer.joinSpan(context); + try (Tracer.SpanInScope ws = tracer.withSpanInScope(parent.start())) { + log.info("HELLO"); + asyncLogic.invokeAsync(); + + MutableSpan span = takeDesirableSpan("invoke-async"); + assertThat(span.name()).isEqualTo("invoke-async"); + assertThat(span.containsAnnotation("@Async")).isTrue(); + assertThat(span.tags()).containsEntry("class", "AsyncLogic").containsEntry("method", "invokeAsync"); + + // continues the trace + assertThat(span.traceId()).isEqualTo(context.traceIdString()); + } + finally { + parent.abandon(); + } + } + + @Test + public void should_set_span_with_custom_method_on_an_async_annotated_method() { + Span parent = tracer.joinSpan(context); + try (Tracer.SpanInScope ws = tracer.withSpanInScope(parent.start())) { + log.info("HELLO"); + asyncLogic.invokeAsync_customName(); + + MutableSpan span = takeDesirableSpan("foo"); + assertThat(span.name()).isEqualTo("foo"); + assertThat(span.containsAnnotation("@Async")).isTrue(); + assertThat(span.tags()).containsEntry("class", "AsyncLogic").containsEntry("method", + "invokeAsync_customName"); + + // continues the trace + assertThat(span.traceId()).isEqualTo(context.traceIdString()); + } + finally { + parent.abandon(); + } + } + + // Sleuth adds spans named "async" with no tags when an executor is used. + // We don't want that one. + MutableSpan takeDesirableSpan(String name) { + MutableSpan span1 = spans.takeLocalSpan(); + log.info("Span [" + span1 + "] found"); + MutableSpan span = span1 != null && name.equals(span1.name()) ? span1 : null; + assertThat(span).as("No span with name <> was found", name).isNotNull(); + return span; + } + + @EnableAutoConfiguration + @EnableAsync + @Configuration(proxyBeanMethods = false) + static class TraceAsyncITestConfiguration { + + @Bean + AsyncLogic asyncLogic(SpanCustomizer customizer) { + return new AsyncLogic(customizer); + } + + @Bean + SpanHandler testSpanHandler() { + return spans; + } + + } + + static class AsyncLogic { + + private static final Logger log = LoggerFactory.getLogger(AsyncLogic.class); + + final SpanCustomizer customizer; + + AsyncLogic(SpanCustomizer customizer) { + this.customizer = customizer; + } + + @Async + public void invokeAsync() { + customizer.annotate("@Async"); // proves the handler is in scope + log.info("HELLO ASYNC"); + } + + @Async + @SpanName("foo") + public void invokeAsync_customName() { + customizer.annotate("@Async"); // proves the handler is in scope + log.info("HELLO ASYNC CUSTOM NAME"); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceAsyncListenableTaskExecutorTest.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceAsyncListenableTaskExecutorTest.java index e3a7d1763..db2d883ee 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceAsyncListenableTaskExecutorTest.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceAsyncListenableTaskExecutorTest.java @@ -1,38 +1,38 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.instrument.async; - -import org.springframework.cloud.sleuth.brave.BraveTestTracing; -import org.springframework.cloud.sleuth.test.TestTracingAware; - -/** - * @author Marcin Grzejszczak - */ -public class TraceAsyncListenableTaskExecutorTest - extends org.springframework.cloud.sleuth.instrument.async.TraceAsyncListenableTaskExecutorTest { - - BraveTestTracing testTracing; - - @Override - public TestTracingAware tracerTest() { - if (this.testTracing == null) { - this.testTracing = new BraveTestTracing(); - } - return this.testTracing; - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +/** + * @author Marcin Grzejszczak + */ +public class TraceAsyncListenableTaskExecutorTest + extends org.springframework.cloud.sleuth.instrument.async.TraceAsyncListenableTaskExecutorTest { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceCallableTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceCallableTests.java index 940a92289..4bbbdd884 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceCallableTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceCallableTests.java @@ -1,34 +1,34 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.instrument.async; - -import org.springframework.cloud.sleuth.brave.BraveTestTracing; -import org.springframework.cloud.sleuth.test.TestTracingAware; - -public class TraceCallableTests extends org.springframework.cloud.sleuth.instrument.async.TraceCallableTests { - - BraveTestTracing testTracing; - - @Override - public TestTracingAware tracerTest() { - if (this.testTracing == null) { - this.testTracing = new BraveTestTracing(); - } - return this.testTracing; - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +public class TraceCallableTests extends org.springframework.cloud.sleuth.instrument.async.TraceCallableTests { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceRunnableTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceRunnableTests.java index 24804e7b2..f518b47c9 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceRunnableTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceRunnableTests.java @@ -1,42 +1,42 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.instrument.async; - -import org.assertj.core.api.BDDAssertions; - -import org.springframework.cloud.sleuth.Span; -import org.springframework.cloud.sleuth.brave.BraveTestTracing; -import org.springframework.cloud.sleuth.test.TestTracingAware; - -public class TraceRunnableTests extends org.springframework.cloud.sleuth.instrument.async.TraceRunnableTests { - - BraveTestTracing testTracing; - - @Override - public TestTracingAware tracerTest() { - if (this.testTracing == null) { - this.testTracing = new BraveTestTracing(); - } - return this.testTracing; - } - - @Override - protected void assertThatThereIsNoParentId(Span secondSpan) { - BDDAssertions.then(secondSpan.context().parentId()).as("saved span as remnant of first span").isNull(); - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async; + +import org.assertj.core.api.BDDAssertions; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +public class TraceRunnableTests extends org.springframework.cloud.sleuth.instrument.async.TraceRunnableTests { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + + @Override + protected void assertThatThereIsNoParentId(Span secondSpan) { + BDDAssertions.then(secondSpan.context().parentId()).as("saved span as remnant of first span").isNull(); + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceScheduledThreadPoolExecutorAnotherConstructorTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceScheduledThreadPoolExecutorAnotherConstructorTests.java new file mode 100644 index 000000000..5e953992f --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceScheduledThreadPoolExecutorAnotherConstructorTests.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +public class TraceScheduledThreadPoolExecutorAnotherConstructorTests extends + org.springframework.cloud.sleuth.instrument.async.TraceScheduledThreadPoolExecutorAnotherConstructorTests { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceScheduledThreadPoolExecutorTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceScheduledThreadPoolExecutorTests.java new file mode 100644 index 000000000..28c61570a --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceScheduledThreadPoolExecutorTests.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +public class TraceScheduledThreadPoolExecutorTests + extends org.springframework.cloud.sleuth.instrument.async.TraceScheduledThreadPoolExecutorTests { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceThreadPoolTaskExecutorTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceThreadPoolTaskExecutorTests.java new file mode 100644 index 000000000..cb7d40593 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceThreadPoolTaskExecutorTests.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +public class TraceThreadPoolTaskExecutorTests + extends org.springframework.cloud.sleuth.instrument.async.TraceThreadPoolTaskExecutorTests { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceThreadPoolTaskSchedulerTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceThreadPoolTaskSchedulerTests.java new file mode 100644 index 000000000..bb67d325d --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceThreadPoolTaskSchedulerTests.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +public class TraceThreadPoolTaskSchedulerTests + extends org.springframework.cloud.sleuth.instrument.async.TraceThreadPoolTaskSchedulerTests { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceableExecutorServiceTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceableExecutorServiceTests.java index f8c1b19ed..a3f139a4f 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceableExecutorServiceTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceableExecutorServiceTests.java @@ -1,35 +1,35 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.instrument.async; - -import org.springframework.cloud.sleuth.brave.BraveTestTracing; -import org.springframework.cloud.sleuth.test.TestTracingAware; - -public class TraceableExecutorServiceTests - extends org.springframework.cloud.sleuth.instrument.async.TraceableExecutorServiceTests { - - BraveTestTracing testTracing; - - @Override - public TestTracingAware tracerTest() { - if (this.testTracing == null) { - this.testTracing = new BraveTestTracing(); - } - return this.testTracing; - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +public class TraceableExecutorServiceTests + extends org.springframework.cloud.sleuth.instrument.async.TraceableExecutorServiceTests { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceableScheduledExecutorServiceTest.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceableScheduledExecutorServiceTest.java index 43449a92b..3395b10c5 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceableScheduledExecutorServiceTest.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceableScheduledExecutorServiceTest.java @@ -1,38 +1,38 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.instrument.async; - -import org.springframework.cloud.sleuth.brave.BraveTestTracing; -import org.springframework.cloud.sleuth.test.TestTracingAware; - -/** - * @author Marcin Grzejszczak - */ -public class TraceableScheduledExecutorServiceTest - extends org.springframework.cloud.sleuth.instrument.async.TraceableScheduledExecutorServiceTest { - - BraveTestTracing testTracing; - - @Override - public TestTracingAware tracerTest() { - if (this.testTracing == null) { - this.testTracing = new BraveTestTracing(); - } - return this.testTracing; - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +/** + * @author Marcin Grzejszczak + */ +public class TraceableScheduledExecutorServiceTest + extends org.springframework.cloud.sleuth.instrument.async.TraceableScheduledExecutorServiceTest { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/issues/issue1212/GH1212Tests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/issues/issue1212/GH1212Tests.java index c6bad280e..e2025b096 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/issues/issue1212/GH1212Tests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/issues/issue1212/GH1212Tests.java @@ -1,182 +1,182 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.instrument.async.issues.issue1212; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; - -import org.junit.jupiter.api.Test; -import org.slf4j.LoggerFactory; - -import org.springframework.aop.interceptor.AsyncExecutionAspectSupport; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.core.task.SimpleAsyncTaskExecutor; -import org.springframework.core.task.TaskExecutor; -import org.springframework.scheduling.annotation.Async; -import org.springframework.scheduling.annotation.AsyncConfigurer; -import org.springframework.scheduling.annotation.AsyncConfigurerSupport; -import org.springframework.scheduling.annotation.EnableAsync; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Bertrand Renuart - */ -public class GH1212Tests { - - @Test - public void defaultTaskExecutor() throws Exception { - try (ConfigurableApplicationContext ctx = new SpringApplicationBuilder(App.class, - DefaultTaskExecutorConfig.class).web(WebApplicationType.NONE).run()) { - String asyncThreadName = getAsyncThreadName(ctx); - assertThat(asyncThreadName).startsWith("defaultTaskExecutor"); - } - } - - @Test - public void singleTaskExecutor() throws Exception { - try (ConfigurableApplicationContext ctx = new SpringApplicationBuilder(App.class, - SingleTaskExecutorConfig.class).web(WebApplicationType.NONE).run()) { - String asyncThreadName = getAsyncThreadName(ctx); - assertThat(asyncThreadName).startsWith("singleTaskExecutor"); - } - } - - @Test - public void multipleTaskExecutors() throws Exception { - try (ConfigurableApplicationContext ctx = new SpringApplicationBuilder(App.class, - MultipleTaskExecutorConfig.class).web(WebApplicationType.NONE).run()) { - String asyncThreadName = getAsyncThreadName(ctx); - assertThat(asyncThreadName).doesNotStartWith("multipleTaskExecutor"); - assertThat(asyncThreadName).startsWith("SimpleAsyncTaskExecutor"); // <-- - // comes - // from - // Sleuth's - // own - // AsyncConfigurer - } - } - - @Test - public void customAsyncConfigurer() throws Exception { - try (ConfigurableApplicationContext ctx = new SpringApplicationBuilder(App.class, - CustomAsyncConfigurerConfig.class).web(WebApplicationType.NONE).run()) { - String asyncThreadName = getAsyncThreadName(ctx); - assertThat(asyncThreadName).startsWith("customAsyncConfigurer"); - } - } - - private String getAsyncThreadName(ApplicationContext ctx) throws Exception { - return ctx.getBean(AsyncComponent.class).asyncMethod().get(); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @EnableAsync - public static class App { - - @Bean - AsyncComponent asyncComponent() { - return new AsyncComponent(); - } - - } - - public static class AsyncComponent { - - @Async - public CompletableFuture asyncMethod() { - LoggerFactory.getLogger("test").info("asyncMethod invoked"); - return CompletableFuture.completedFuture(Thread.currentThread().getName()); - } - - } - - /* - * Configuration with a single Executor named `taskExecutor` - */ - @Configuration(proxyBeanMethods = false) - public static class DefaultTaskExecutorConfig { - - @Bean(name = AsyncExecutionAspectSupport.DEFAULT_TASK_EXECUTOR_BEAN_NAME) - public Executor taskExecutor() { - return new SimpleAsyncTaskExecutor("defaultTaskExecutor"); - } - - } - - /* - * Configuration with a single TaskExecutor - */ - @Configuration(proxyBeanMethods = false) - public static class SingleTaskExecutorConfig { - - @Bean - // there's the task - @Primary - public TaskExecutor singleTaskExecutor() { - return new SimpleAsyncTaskExecutor("singleTaskExecutor"); - } - - } - - /* - * Configuration with a multiple TaskExecutors --> Spring won't pick any unless one - * is @Primary - */ - @Configuration(proxyBeanMethods = false) - public static class MultipleTaskExecutorConfig { - - @Bean - public TaskExecutor multipleTaskExecutor1() { - return new SimpleAsyncTaskExecutor("multipleTaskExecutor1"); - } - - @Bean - public TaskExecutor multipleTaskExecutor2() { - return new SimpleAsyncTaskExecutor("multipleTaskExecutor2"); - } - - } - - /* - * Configuration where a custom AsyncConfigurer is provided - */ - @Configuration(proxyBeanMethods = false) - public static class CustomAsyncConfigurerConfig { - - @Bean - public AsyncConfigurer customAsyncConfigurer() { - return new AsyncConfigurerSupport() { - @Override - public Executor getAsyncExecutor() { - return new SimpleAsyncTaskExecutor("customAsyncConfigurer"); - } - }; - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async.issues.issue1212; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; + +import org.junit.jupiter.api.Test; +import org.slf4j.LoggerFactory; + +import org.springframework.aop.interceptor.AsyncExecutionAspectSupport; +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.task.SimpleAsyncTaskExecutor; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.AsyncConfigurerSupport; +import org.springframework.scheduling.annotation.EnableAsync; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Bertrand Renuart + */ +public class GH1212Tests { + + @Test + public void defaultTaskExecutor() throws Exception { + try (ConfigurableApplicationContext ctx = new SpringApplicationBuilder(App.class, + DefaultTaskExecutorConfig.class).web(WebApplicationType.NONE).run()) { + String asyncThreadName = getAsyncThreadName(ctx); + assertThat(asyncThreadName).startsWith("defaultTaskExecutor"); + } + } + + @Test + public void singleTaskExecutor() throws Exception { + try (ConfigurableApplicationContext ctx = new SpringApplicationBuilder(App.class, + SingleTaskExecutorConfig.class).web(WebApplicationType.NONE).run()) { + String asyncThreadName = getAsyncThreadName(ctx); + assertThat(asyncThreadName).startsWith("singleTaskExecutor"); + } + } + + @Test + public void multipleTaskExecutors() throws Exception { + try (ConfigurableApplicationContext ctx = new SpringApplicationBuilder(App.class, + MultipleTaskExecutorConfig.class).web(WebApplicationType.NONE).run()) { + String asyncThreadName = getAsyncThreadName(ctx); + assertThat(asyncThreadName).doesNotStartWith("multipleTaskExecutor"); + assertThat(asyncThreadName).startsWith("SimpleAsyncTaskExecutor"); // <-- + // comes + // from + // Sleuth's + // own + // AsyncConfigurer + } + } + + @Test + public void customAsyncConfigurer() throws Exception { + try (ConfigurableApplicationContext ctx = new SpringApplicationBuilder(App.class, + CustomAsyncConfigurerConfig.class).web(WebApplicationType.NONE).run()) { + String asyncThreadName = getAsyncThreadName(ctx); + assertThat(asyncThreadName).startsWith("customAsyncConfigurer"); + } + } + + private String getAsyncThreadName(ApplicationContext ctx) throws Exception { + return ctx.getBean(AsyncComponent.class).asyncMethod().get(); + } + + @SpringBootConfiguration + @EnableAutoConfiguration + @EnableAsync + public static class App { + + @Bean + AsyncComponent asyncComponent() { + return new AsyncComponent(); + } + + } + + public static class AsyncComponent { + + @Async + public CompletableFuture asyncMethod() { + LoggerFactory.getLogger("test").info("asyncMethod invoked"); + return CompletableFuture.completedFuture(Thread.currentThread().getName()); + } + + } + + /* + * Configuration with a single Executor named `taskExecutor` + */ + @Configuration(proxyBeanMethods = false) + public static class DefaultTaskExecutorConfig { + + @Bean(name = AsyncExecutionAspectSupport.DEFAULT_TASK_EXECUTOR_BEAN_NAME) + public Executor taskExecutor() { + return new SimpleAsyncTaskExecutor("defaultTaskExecutor"); + } + + } + + /* + * Configuration with a single TaskExecutor + */ + @Configuration(proxyBeanMethods = false) + public static class SingleTaskExecutorConfig { + + @Bean + // there's the task + @Primary + public TaskExecutor singleTaskExecutor() { + return new SimpleAsyncTaskExecutor("singleTaskExecutor"); + } + + } + + /* + * Configuration with a multiple TaskExecutors --> Spring won't pick any unless one + * is @Primary + */ + @Configuration(proxyBeanMethods = false) + public static class MultipleTaskExecutorConfig { + + @Bean + public TaskExecutor multipleTaskExecutor1() { + return new SimpleAsyncTaskExecutor("multipleTaskExecutor1"); + } + + @Bean + public TaskExecutor multipleTaskExecutor2() { + return new SimpleAsyncTaskExecutor("multipleTaskExecutor2"); + } + + } + + /* + * Configuration where a custom AsyncConfigurer is provided + */ + @Configuration(proxyBeanMethods = false) + public static class CustomAsyncConfigurerConfig { + + @Bean + public AsyncConfigurer customAsyncConfigurer() { + return new AsyncConfigurerSupport() { + @Override + public Executor getAsyncExecutor() { + return new SimpleAsyncTaskExecutor("customAsyncConfigurer"); + } + }; + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/issues/issue410/Issue410Tests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/issues/issue410/Issue410Tests.java index 00ece718e..93c57e128 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/issues/issue410/Issue410Tests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/issues/issue410/Issue410Tests.java @@ -1,480 +1,480 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.instrument.async.issues.issue410; - -import java.util.Date; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.atomic.AtomicReference; - -import brave.Span; -import brave.Tracer; -import brave.sampler.Sampler; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.awaitility.Awaitility; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.cloud.sleuth.instrument.async.LazyTraceExecutor; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.scheduling.annotation.Async; -import org.springframework.scheduling.annotation.EnableAsync; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; -import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; -import org.springframework.stereotype.Component; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Marcin Grzejszczak - */ -@SpringBootTest(classes = { AppConfig.class, Application.class }, webEnvironment = WebEnvironment.RANDOM_PORT) -public class Issue410Tests { - - private static final Log log = LogFactory.getLog(Issue410Tests.class); - - @Autowired - Environment environment; - - @Autowired - Tracer tracer; - - @Autowired - AsyncTask asyncTask; - - @Autowired - RestTemplate restTemplate; - - /** - * Related to issue #445. - */ - @Autowired - Application.MyService executorService; - - @Test - public void should_pass_tracing_info_for_tasks_running_without_a_pool() { - Span span = this.tracer.nextSpan().name("foo"); - log.info("Starting test"); - try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span)) { - String response = this.restTemplate.getForObject("http://localhost:" + port() + "/without_pool", - String.class); - - then(response).isEqualTo(span.context().traceIdString()); - Awaitility.await().untilAsserted(() -> { - then(this.asyncTask.getSpan().get()).isNotNull(); - then(this.asyncTask.getSpan().get().context().traceId()).isEqualTo(span.context().traceId()); - }); - } - finally { - span.finish(); - } - - then(this.tracer.currentSpan()).isNull(); - } - - @Test - public void should_pass_tracing_info_for_tasks_running_with_a_pool() { - Span span = this.tracer.nextSpan().name("foo"); - log.info("Starting test"); - try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span)) { - String response = this.restTemplate.getForObject("http://localhost:" + port() + "/with_pool", String.class); - - then(response).isEqualTo(span.context().traceIdString()); - Awaitility.await().untilAsserted(() -> { - then(this.asyncTask.getSpan().get()).isNotNull(); - then(this.asyncTask.getSpan().get().context().traceId()).isEqualTo(span.context().traceId()); - }); - } - finally { - span.finish(); - } - - then(this.tracer.currentSpan()).isNull(); - } - - /** - * Related to issue #423. - */ - @Test - public void should_pass_tracing_info_for_completable_futures_with_executor() { - Span span = this.tracer.nextSpan().name("foo"); - log.info("Starting test"); - try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span)) { - String response = this.restTemplate.getForObject("http://localhost:" + port() + "/completable", - String.class); - - then(response).isEqualTo(span.context().traceIdString()); - Awaitility.await().untilAsserted(() -> { - then(this.asyncTask.getSpan().get()).isNotNull(); - then(this.asyncTask.getSpan().get().context().traceId()).isEqualTo(span.context().traceId()); - }); - } - finally { - span.finish(); - } - - then(this.tracer.currentSpan()).isNull(); - } - - /** - * Related to issue #423. - */ - @Test - public void should_pass_tracing_info_for_completable_futures_with_task_scheduler() { - Span span = this.tracer.nextSpan().name("foo"); - try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span)) { - log.info("Starting test"); - String response = this.restTemplate.getForObject("http://localhost:" + port() + "/taskScheduler", - String.class); - - then(response).isEqualTo(span.context().traceIdString()); - Awaitility.await().untilAsserted(() -> { - then(this.asyncTask.getSpan().get()).isNotNull(); - then(this.asyncTask.getSpan().get().context().traceId()).isEqualTo(span.context().traceId()); - }); - } - finally { - span.finish(); - } - - then(this.tracer.currentSpan()).isNull(); - } - - /** - * Related to issue #1232 - */ - @Test - public void should_pass_tracing_info_for_submitted_tasks_with_threadPoolTaskScheduler() { - Span span = this.tracer.nextSpan().name("foo"); - try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span)) { - log.info("Starting test"); - String response = this.restTemplate - .getForObject("http://localhost:" + port() + "/threadPoolTaskScheduler_submit", String.class); - - then(response).isEqualTo(span.context().traceIdString()); - Awaitility.await().untilAsserted(() -> { - then(this.asyncTask.getSpan().get()).isNotNull(); - then(this.asyncTask.getSpan().get().context().traceId()).isEqualTo(span.context().traceId()); - }); - } - finally { - span.finish(); - } - - then(this.tracer.currentSpan()).isNull(); - } - - @Test - public void should_pass_tracing_info_for_scheduled_tasks_with_threadPoolTaskScheduler() { - Span span = this.tracer.nextSpan().name("foo"); - try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span)) { - log.info("Starting test"); - String response = this.restTemplate - .getForObject("http://localhost:" + port() + "/threadPoolTaskScheduler_schedule", String.class); - - then(response).isEqualTo(span.context().traceIdString()); - Awaitility.await().untilAsserted(() -> { - then(this.asyncTask.getSpan().get()).isNotNull(); - then(this.asyncTask.getSpan().get().context().traceId()).isEqualTo(span.context().traceId()); - }); - } - finally { - span.finish(); - } - - then(this.tracer.currentSpan()).isNull(); - } - - /** - * Related to issue #1232 - */ - @Test - public void should_pass_tracing_info_for_completable_futures_with_scheduledThreadPoolExecutor() { - Span span = this.tracer.nextSpan().name("foo"); - try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span)) { - log.info("Starting test"); - String response = this.restTemplate - .getForObject("http://localhost:" + port() + "/scheduledThreadPoolExecutor", String.class); - - then(response).isEqualTo(span.context().traceIdString()); - Awaitility.await().untilAsserted(() -> { - then(this.asyncTask.getSpan().get()).isNotNull(); - then(this.asyncTask.getSpan().get().context().traceId()).isEqualTo(span.context().traceId()); - }); - } - finally { - span.finish(); - } - - then(this.tracer.currentSpan()).isNull(); - } - - private int port() { - return this.environment.getProperty("local.server.port", Integer.class); - } - -} - -@Configuration(proxyBeanMethods = false) -@EnableAsync -class AppConfig { - - @Bean - public Sampler testSampler() { - return Sampler.ALWAYS_SAMPLE; - } - - @Bean - public RestTemplate restTemplate() { - return new RestTemplate(); - } - - @Bean("taskScheduler") - public Executor myScheduler() { - return Executors.newSingleThreadExecutor(); - } - - @Bean - public Executor poolTaskExecutor() { - ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); - executor.initialize(); - return executor; - } - - @Bean - public ThreadPoolTaskScheduler threadPoolTaskScheduler() { - ThreadPoolTaskScheduler executor = new ThreadPoolTaskScheduler(); - executor.initialize(); - return executor; - } - - @Bean - public ScheduledThreadPoolExecutor scheduledThreadPoolExecutor() { - return new ScheduledThreadPoolExecutor(10); - } - -} - -@Component -class AsyncTask { - - private static final Log log = LogFactory.getLog(AsyncTask.class); - - @Autowired - Tracer tracer; - - @Autowired - @Qualifier("poolTaskExecutor") - Executor executor; - - @Autowired - @Qualifier("taskScheduler") - Executor taskScheduler; - - @Autowired - BeanFactory beanFactory; - - @Autowired - ThreadPoolTaskScheduler threadPoolTaskScheduler; - - @Autowired - ScheduledThreadPoolExecutor scheduledThreadPoolExecutor; - - private AtomicReference span = new AtomicReference<>(); - - @Async("poolTaskExecutor") - public void runWithPool() { - log.info("This task is running with a pool."); - this.span.set(this.tracer.currentSpan()); - } - - @Async - public void runWithoutPool() { - log.info("This task is running without a pool."); - this.span.set(this.tracer.currentSpan()); - } - - public Span completableFutures() throws ExecutionException, InterruptedException { - log.info("This task is running with completable future"); - CompletableFuture span1 = CompletableFuture.supplyAsync(() -> { - AsyncTask.log.info("First completable future"); - return AsyncTask.this.tracer.currentSpan(); - }, AsyncTask.this.executor); - CompletableFuture span2 = CompletableFuture.supplyAsync(() -> { - AsyncTask.log.info("Second completable future"); - return AsyncTask.this.tracer.currentSpan(); - }, AsyncTask.this.executor); - CompletableFuture response = CompletableFuture.allOf(span1, span2).thenApply(ignoredVoid -> { - AsyncTask.log.info("Third completable future"); - Span joinedSpan1 = span1.join(); - Span joinedSpan2 = span2.join(); - then(joinedSpan2).isNotNull(); - then(joinedSpan1.context().traceId()).isEqualTo(joinedSpan2.context().traceId()); - AsyncTask.log.info("TraceIds are correct"); - return joinedSpan2; - }); - this.span.set(response.get()); - return this.span.get(); - } - - public Span taskScheduler() throws ExecutionException, InterruptedException { - log.info("This task is running with completable future"); - CompletableFuture span1 = CompletableFuture.supplyAsync(() -> { - AsyncTask.log.info("First completable future"); - return AsyncTask.this.tracer.currentSpan(); - }, new LazyTraceExecutor(AsyncTask.this.beanFactory, AsyncTask.this.taskScheduler)); - CompletableFuture span2 = CompletableFuture.supplyAsync(() -> { - AsyncTask.log.info("Second completable future"); - return AsyncTask.this.tracer.currentSpan(); - }, new LazyTraceExecutor(AsyncTask.this.beanFactory, AsyncTask.this.taskScheduler)); - CompletableFuture response = CompletableFuture.allOf(span1, span2).thenApply(ignoredVoid -> { - AsyncTask.log.info("Third completable future"); - Span joinedSpan1 = span1.join(); - Span joinedSpan2 = span2.join(); - then(joinedSpan2).isNotNull(); - then(joinedSpan1.context().traceId()).isEqualTo(joinedSpan2.context().traceId()); - AsyncTask.log.info("TraceIds are correct"); - return joinedSpan2; - }); - this.span.set(response.get()); - return this.span.get(); - } - - public Span scheduledThreadPoolExecutor() throws ExecutionException, InterruptedException { - log.info("This task is running with ScheduledThreadPoolExecutor"); - this.scheduledThreadPoolExecutor.submit(() -> { - log.info("Hello from runnable"); - AsyncTask.this.span.set(AsyncTask.this.tracer.currentSpan()); - }).get(); - return this.span.get(); - } - - public Span threadPoolTaskSchedulerSubmit() throws ExecutionException, InterruptedException { - log.info("This task is running with ThreadPoolTaskScheduler"); - this.threadPoolTaskScheduler.submit(() -> { - log.info("Hello from runnable"); - AsyncTask.this.span.set(AsyncTask.this.tracer.currentSpan()); - }).get(); - return this.span.get(); - } - - public Span threadPoolTaskSchedulerSchedule() throws ExecutionException, InterruptedException { - log.info("This task is running with ThreadPoolTaskScheduler"); - this.threadPoolTaskScheduler.schedule(() -> { - log.info("Hello from runnable"); - AsyncTask.this.span.set(AsyncTask.this.tracer.currentSpan()); - }, new Date()).get(); - return this.span.get(); - } - - public AtomicReference getSpan() { - return this.span; - } - -} - -@SpringBootApplication(exclude = SpringDataWebAutoConfiguration.class) -@RestController -class Application { - - private static final Log log = LogFactory.getLog(Application.class); - - @Autowired - AsyncTask asyncTask; - - @Autowired - Tracer tracer; - - @RequestMapping("/with_pool") - public String withPool() { - log.info("Executing with pool."); - this.asyncTask.runWithPool(); - return this.tracer.currentSpan().context().traceIdString(); - - } - - @RequestMapping("/without_pool") - public String withoutPool() { - log.info("Executing without pool."); - this.asyncTask.runWithoutPool(); - return this.tracer.currentSpan().context().traceIdString(); - } - - @RequestMapping("/completable") - public String completable() throws ExecutionException, InterruptedException { - log.info("Executing completable"); - return this.asyncTask.completableFutures().context().traceIdString(); - } - - @RequestMapping("/taskScheduler") - public String taskScheduler() throws ExecutionException, InterruptedException { - log.info("Executing completable via task scheduler"); - return this.asyncTask.taskScheduler().context().traceIdString(); - } - - @RequestMapping("/threadPoolTaskScheduler_submit") - public String threadPoolTaskSchedulerSubmit() throws ExecutionException, InterruptedException { - log.info("Executing completable via ThreadPoolTaskScheduler"); - return this.asyncTask.threadPoolTaskSchedulerSubmit().context().traceIdString(); - } - - @RequestMapping("/threadPoolTaskScheduler_schedule") - public String threadPoolTaskSchedulerSchedule() throws ExecutionException, InterruptedException { - log.info("Executing completable via ThreadPoolTaskScheduler"); - return this.asyncTask.threadPoolTaskSchedulerSchedule().context().traceIdString(); - } - - @RequestMapping("/scheduledThreadPoolExecutor") - public String scheduledThreadPoolExecutor() throws ExecutionException, InterruptedException { - log.info("Executing completable via ScheduledThreadPoolExecutor"); - return this.asyncTask.scheduledThreadPoolExecutor().context().traceIdString(); - } - - /** - * Related to issue #445. - * @return service bean - */ - @Bean - public MyService executorService() { - return new MyService() { - @Override - public void execute(Runnable command) { - - } - }; - } - - interface MyService extends Executor { - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async.issues.issue410; + +import java.util.Date; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.atomic.AtomicReference; + +import brave.Span; +import brave.Tracer; +import brave.sampler.Sampler; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.awaitility.Awaitility; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.cloud.sleuth.instrument.async.LazyTraceExecutor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +import static org.assertj.core.api.BDDAssertions.then; + +/** + * @author Marcin Grzejszczak + */ +@SpringBootTest(classes = { AppConfig.class, Application.class }, webEnvironment = WebEnvironment.RANDOM_PORT) +public class Issue410Tests { + + private static final Log log = LogFactory.getLog(Issue410Tests.class); + + @Autowired + Environment environment; + + @Autowired + Tracer tracer; + + @Autowired + AsyncTask asyncTask; + + @Autowired + RestTemplate restTemplate; + + /** + * Related to issue #445. + */ + @Autowired + Application.MyService executorService; + + @Test + public void should_pass_tracing_info_for_tasks_running_without_a_pool() { + Span span = this.tracer.nextSpan().name("foo"); + log.info("Starting test"); + try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span)) { + String response = this.restTemplate.getForObject("http://localhost:" + port() + "/without_pool", + String.class); + + then(response).isEqualTo(span.context().traceIdString()); + Awaitility.await().untilAsserted(() -> { + then(this.asyncTask.getSpan().get()).isNotNull(); + then(this.asyncTask.getSpan().get().context().traceId()).isEqualTo(span.context().traceId()); + }); + } + finally { + span.finish(); + } + + then(this.tracer.currentSpan()).isNull(); + } + + @Test + public void should_pass_tracing_info_for_tasks_running_with_a_pool() { + Span span = this.tracer.nextSpan().name("foo"); + log.info("Starting test"); + try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span)) { + String response = this.restTemplate.getForObject("http://localhost:" + port() + "/with_pool", String.class); + + then(response).isEqualTo(span.context().traceIdString()); + Awaitility.await().untilAsserted(() -> { + then(this.asyncTask.getSpan().get()).isNotNull(); + then(this.asyncTask.getSpan().get().context().traceId()).isEqualTo(span.context().traceId()); + }); + } + finally { + span.finish(); + } + + then(this.tracer.currentSpan()).isNull(); + } + + /** + * Related to issue #423. + */ + @Test + public void should_pass_tracing_info_for_completable_futures_with_executor() { + Span span = this.tracer.nextSpan().name("foo"); + log.info("Starting test"); + try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span)) { + String response = this.restTemplate.getForObject("http://localhost:" + port() + "/completable", + String.class); + + then(response).isEqualTo(span.context().traceIdString()); + Awaitility.await().untilAsserted(() -> { + then(this.asyncTask.getSpan().get()).isNotNull(); + then(this.asyncTask.getSpan().get().context().traceId()).isEqualTo(span.context().traceId()); + }); + } + finally { + span.finish(); + } + + then(this.tracer.currentSpan()).isNull(); + } + + /** + * Related to issue #423. + */ + @Test + public void should_pass_tracing_info_for_completable_futures_with_task_scheduler() { + Span span = this.tracer.nextSpan().name("foo"); + try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span)) { + log.info("Starting test"); + String response = this.restTemplate.getForObject("http://localhost:" + port() + "/taskScheduler", + String.class); + + then(response).isEqualTo(span.context().traceIdString()); + Awaitility.await().untilAsserted(() -> { + then(this.asyncTask.getSpan().get()).isNotNull(); + then(this.asyncTask.getSpan().get().context().traceId()).isEqualTo(span.context().traceId()); + }); + } + finally { + span.finish(); + } + + then(this.tracer.currentSpan()).isNull(); + } + + /** + * Related to issue #1232 + */ + @Test + public void should_pass_tracing_info_for_submitted_tasks_with_threadPoolTaskScheduler() { + Span span = this.tracer.nextSpan().name("foo"); + try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span)) { + log.info("Starting test"); + String response = this.restTemplate + .getForObject("http://localhost:" + port() + "/threadPoolTaskScheduler_submit", String.class); + + then(response).isEqualTo(span.context().traceIdString()); + Awaitility.await().untilAsserted(() -> { + then(this.asyncTask.getSpan().get()).isNotNull(); + then(this.asyncTask.getSpan().get().context().traceId()).isEqualTo(span.context().traceId()); + }); + } + finally { + span.finish(); + } + + then(this.tracer.currentSpan()).isNull(); + } + + @Test + public void should_pass_tracing_info_for_scheduled_tasks_with_threadPoolTaskScheduler() { + Span span = this.tracer.nextSpan().name("foo"); + try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span)) { + log.info("Starting test"); + String response = this.restTemplate + .getForObject("http://localhost:" + port() + "/threadPoolTaskScheduler_schedule", String.class); + + then(response).isEqualTo(span.context().traceIdString()); + Awaitility.await().untilAsserted(() -> { + then(this.asyncTask.getSpan().get()).isNotNull(); + then(this.asyncTask.getSpan().get().context().traceId()).isEqualTo(span.context().traceId()); + }); + } + finally { + span.finish(); + } + + then(this.tracer.currentSpan()).isNull(); + } + + /** + * Related to issue #1232 + */ + @Test + public void should_pass_tracing_info_for_completable_futures_with_scheduledThreadPoolExecutor() { + Span span = this.tracer.nextSpan().name("foo"); + try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span)) { + log.info("Starting test"); + String response = this.restTemplate + .getForObject("http://localhost:" + port() + "/scheduledThreadPoolExecutor", String.class); + + then(response).isEqualTo(span.context().traceIdString()); + Awaitility.await().untilAsserted(() -> { + then(this.asyncTask.getSpan().get()).isNotNull(); + then(this.asyncTask.getSpan().get().context().traceId()).isEqualTo(span.context().traceId()); + }); + } + finally { + span.finish(); + } + + then(this.tracer.currentSpan()).isNull(); + } + + private int port() { + return this.environment.getProperty("local.server.port", Integer.class); + } + +} + +@Configuration(proxyBeanMethods = false) +@EnableAsync +class AppConfig { + + @Bean + public Sampler testSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } + + @Bean("taskScheduler") + public Executor myScheduler() { + return Executors.newSingleThreadExecutor(); + } + + @Bean + public Executor poolTaskExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.initialize(); + return executor; + } + + @Bean + public ThreadPoolTaskScheduler threadPoolTaskScheduler() { + ThreadPoolTaskScheduler executor = new ThreadPoolTaskScheduler(); + executor.initialize(); + return executor; + } + + @Bean + public ScheduledThreadPoolExecutor scheduledThreadPoolExecutor() { + return new ScheduledThreadPoolExecutor(10); + } + +} + +@Component +class AsyncTask { + + private static final Log log = LogFactory.getLog(AsyncTask.class); + + @Autowired + Tracer tracer; + + @Autowired + @Qualifier("poolTaskExecutor") + Executor executor; + + @Autowired + @Qualifier("taskScheduler") + Executor taskScheduler; + + @Autowired + BeanFactory beanFactory; + + @Autowired + ThreadPoolTaskScheduler threadPoolTaskScheduler; + + @Autowired + ScheduledThreadPoolExecutor scheduledThreadPoolExecutor; + + private AtomicReference span = new AtomicReference<>(); + + @Async("poolTaskExecutor") + public void runWithPool() { + log.info("This task is running with a pool."); + this.span.set(this.tracer.currentSpan()); + } + + @Async + public void runWithoutPool() { + log.info("This task is running without a pool."); + this.span.set(this.tracer.currentSpan()); + } + + public Span completableFutures() throws ExecutionException, InterruptedException { + log.info("This task is running with completable future"); + CompletableFuture span1 = CompletableFuture.supplyAsync(() -> { + AsyncTask.log.info("First completable future"); + return AsyncTask.this.tracer.currentSpan(); + }, AsyncTask.this.executor); + CompletableFuture span2 = CompletableFuture.supplyAsync(() -> { + AsyncTask.log.info("Second completable future"); + return AsyncTask.this.tracer.currentSpan(); + }, AsyncTask.this.executor); + CompletableFuture response = CompletableFuture.allOf(span1, span2).thenApply(ignoredVoid -> { + AsyncTask.log.info("Third completable future"); + Span joinedSpan1 = span1.join(); + Span joinedSpan2 = span2.join(); + then(joinedSpan2).isNotNull(); + then(joinedSpan1.context().traceId()).isEqualTo(joinedSpan2.context().traceId()); + AsyncTask.log.info("TraceIds are correct"); + return joinedSpan2; + }); + this.span.set(response.get()); + return this.span.get(); + } + + public Span taskScheduler() throws ExecutionException, InterruptedException { + log.info("This task is running with completable future"); + CompletableFuture span1 = CompletableFuture.supplyAsync(() -> { + AsyncTask.log.info("First completable future"); + return AsyncTask.this.tracer.currentSpan(); + }, new LazyTraceExecutor(AsyncTask.this.beanFactory, AsyncTask.this.taskScheduler)); + CompletableFuture span2 = CompletableFuture.supplyAsync(() -> { + AsyncTask.log.info("Second completable future"); + return AsyncTask.this.tracer.currentSpan(); + }, new LazyTraceExecutor(AsyncTask.this.beanFactory, AsyncTask.this.taskScheduler)); + CompletableFuture response = CompletableFuture.allOf(span1, span2).thenApply(ignoredVoid -> { + AsyncTask.log.info("Third completable future"); + Span joinedSpan1 = span1.join(); + Span joinedSpan2 = span2.join(); + then(joinedSpan2).isNotNull(); + then(joinedSpan1.context().traceId()).isEqualTo(joinedSpan2.context().traceId()); + AsyncTask.log.info("TraceIds are correct"); + return joinedSpan2; + }); + this.span.set(response.get()); + return this.span.get(); + } + + public Span scheduledThreadPoolExecutor() throws ExecutionException, InterruptedException { + log.info("This task is running with ScheduledThreadPoolExecutor"); + this.scheduledThreadPoolExecutor.submit(() -> { + log.info("Hello from runnable"); + AsyncTask.this.span.set(AsyncTask.this.tracer.currentSpan()); + }).get(); + return this.span.get(); + } + + public Span threadPoolTaskSchedulerSubmit() throws ExecutionException, InterruptedException { + log.info("This task is running with ThreadPoolTaskScheduler"); + this.threadPoolTaskScheduler.submit(() -> { + log.info("Hello from runnable"); + AsyncTask.this.span.set(AsyncTask.this.tracer.currentSpan()); + }).get(); + return this.span.get(); + } + + public Span threadPoolTaskSchedulerSchedule() throws ExecutionException, InterruptedException { + log.info("This task is running with ThreadPoolTaskScheduler"); + this.threadPoolTaskScheduler.schedule(() -> { + log.info("Hello from runnable"); + AsyncTask.this.span.set(AsyncTask.this.tracer.currentSpan()); + }, new Date()).get(); + return this.span.get(); + } + + public AtomicReference getSpan() { + return this.span; + } + +} + +@SpringBootApplication(exclude = SpringDataWebAutoConfiguration.class) +@RestController +class Application { + + private static final Log log = LogFactory.getLog(Application.class); + + @Autowired + AsyncTask asyncTask; + + @Autowired + Tracer tracer; + + @RequestMapping("/with_pool") + public String withPool() { + log.info("Executing with pool."); + this.asyncTask.runWithPool(); + return this.tracer.currentSpan().context().traceIdString(); + + } + + @RequestMapping("/without_pool") + public String withoutPool() { + log.info("Executing without pool."); + this.asyncTask.runWithoutPool(); + return this.tracer.currentSpan().context().traceIdString(); + } + + @RequestMapping("/completable") + public String completable() throws ExecutionException, InterruptedException { + log.info("Executing completable"); + return this.asyncTask.completableFutures().context().traceIdString(); + } + + @RequestMapping("/taskScheduler") + public String taskScheduler() throws ExecutionException, InterruptedException { + log.info("Executing completable via task scheduler"); + return this.asyncTask.taskScheduler().context().traceIdString(); + } + + @RequestMapping("/threadPoolTaskScheduler_submit") + public String threadPoolTaskSchedulerSubmit() throws ExecutionException, InterruptedException { + log.info("Executing completable via ThreadPoolTaskScheduler"); + return this.asyncTask.threadPoolTaskSchedulerSubmit().context().traceIdString(); + } + + @RequestMapping("/threadPoolTaskScheduler_schedule") + public String threadPoolTaskSchedulerSchedule() throws ExecutionException, InterruptedException { + log.info("Executing completable via ThreadPoolTaskScheduler"); + return this.asyncTask.threadPoolTaskSchedulerSchedule().context().traceIdString(); + } + + @RequestMapping("/scheduledThreadPoolExecutor") + public String scheduledThreadPoolExecutor() throws ExecutionException, InterruptedException { + log.info("Executing completable via ScheduledThreadPoolExecutor"); + return this.asyncTask.scheduledThreadPoolExecutor().context().traceIdString(); + } + + /** + * Related to issue #445. + * @return service bean + */ + @Bean + public MyService executorService() { + return new MyService() { + @Override + public void execute(Runnable command) { + + } + }; + } + + interface MyService extends Executor { + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/issues/issue546/Issue546Tests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/issues/issue546/Issue546Tests.java index d3afe82ee..3d7829c8a 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/issues/issue546/Issue546Tests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/issues/issue546/Issue546Tests.java @@ -1,143 +1,143 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.instrument.async.issues.issue546; - -import brave.Tracing; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Bean; -import org.springframework.core.env.Environment; -import org.springframework.http.ResponseEntity; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.AsyncRestTemplate; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Marcin Grzejszczak - */ -@SpringBootTest(classes = Issue546TestsApp.class, properties = { "server.port=0" }, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -public class Issue546Tests { - - @Autowired - Environment environment; - - @Test - public void should_pass_tracing_info_when_using_callbacks() { - new RestTemplate().getForObject("http://localhost:" + port() + "/trace-async-rest-template", String.class); - } - - private int port() { - return this.environment.getProperty("local.server.port", Integer.class); - } - -} - -@SpringBootApplication -class Issue546TestsApp { - - @Bean - AsyncRestTemplate asyncRestTemplate() { - return new AsyncRestTemplate(); - } - -} - -@RestController -class Controller { - - private static final Log log = LogFactory.getLog(Controller.class); - - private final AsyncRestTemplate traceAsyncRestTemplate; - - private final Tracing tracer; - - @Value("${server.port}") - private String port; - - Controller(AsyncRestTemplate traceAsyncRestTemplate, Tracing tracer) { - this.traceAsyncRestTemplate = traceAsyncRestTemplate; - this.tracer = tracer; - } - - @RequestMapping("/bean") - public HogeBean bean() { - log.info("(/bean) I got a request!"); - return new HogeBean("test", 18); - } - - @RequestMapping("/trace-async-rest-template") - public void asyncTest(@RequestParam(required = false) boolean isSleep) throws InterruptedException { - log.info("(/trace-async-rest-template) I got a request!"); - final long traceId = this.tracer.tracer().currentSpan().context().traceId(); - ListenableFuture> res = this.traceAsyncRestTemplate - .getForEntity("http://localhost:" + this.port + "/bean", HogeBean.class); - if (isSleep) { - Thread.sleep(1000); - } - res.addCallback(success -> { - then(Controller.this.tracer.tracer().currentSpan().context().traceId()).isEqualTo(traceId); - log.info("(/trace-async-rest-template) success"); - then(Controller.this.tracer.tracer().currentSpan().context().traceId()).isEqualTo(traceId); - }, failure -> { - then(Controller.this.tracer.tracer().currentSpan().context().traceId()).isEqualTo(traceId); - log.error("(/trace-async-rest-template) failure", failure); - then(Controller.this.tracer.tracer().currentSpan().context().traceId()).isEqualTo(traceId); - }); - } - -} - -class HogeBean { - - private String name; - - private int age; - - HogeBean(String name, int age) { - this.name = name; - this.age = age; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public int getAge() { - return this.age; - } - - public void setAge(int age) { - this.age = age; - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async.issues.issue546; + +import brave.Tracing; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.core.env.Environment; +import org.springframework.http.ResponseEntity; +import org.springframework.util.concurrent.ListenableFuture; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.AsyncRestTemplate; +import org.springframework.web.client.RestTemplate; + +import static org.assertj.core.api.BDDAssertions.then; + +/** + * @author Marcin Grzejszczak + */ +@SpringBootTest(classes = Issue546TestsApp.class, properties = { "server.port=0" }, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class Issue546Tests { + + @Autowired + Environment environment; + + @Test + public void should_pass_tracing_info_when_using_callbacks() { + new RestTemplate().getForObject("http://localhost:" + port() + "/trace-async-rest-template", String.class); + } + + private int port() { + return this.environment.getProperty("local.server.port", Integer.class); + } + +} + +@SpringBootApplication +class Issue546TestsApp { + + @Bean + AsyncRestTemplate asyncRestTemplate() { + return new AsyncRestTemplate(); + } + +} + +@RestController +class Controller { + + private static final Log log = LogFactory.getLog(Controller.class); + + private final AsyncRestTemplate traceAsyncRestTemplate; + + private final Tracing tracer; + + @Value("${server.port}") + private String port; + + Controller(AsyncRestTemplate traceAsyncRestTemplate, Tracing tracer) { + this.traceAsyncRestTemplate = traceAsyncRestTemplate; + this.tracer = tracer; + } + + @RequestMapping("/bean") + public HogeBean bean() { + log.info("(/bean) I got a request!"); + return new HogeBean("test", 18); + } + + @RequestMapping("/trace-async-rest-template") + public void asyncTest(@RequestParam(required = false) boolean isSleep) throws InterruptedException { + log.info("(/trace-async-rest-template) I got a request!"); + final long traceId = this.tracer.tracer().currentSpan().context().traceId(); + ListenableFuture> res = this.traceAsyncRestTemplate + .getForEntity("http://localhost:" + this.port + "/bean", HogeBean.class); + if (isSleep) { + Thread.sleep(1000); + } + res.addCallback(success -> { + then(Controller.this.tracer.tracer().currentSpan().context().traceId()).isEqualTo(traceId); + log.info("(/trace-async-rest-template) success"); + then(Controller.this.tracer.tracer().currentSpan().context().traceId()).isEqualTo(traceId); + }, failure -> { + then(Controller.this.tracer.tracer().currentSpan().context().traceId()).isEqualTo(traceId); + log.error("(/trace-async-rest-template) failure", failure); + then(Controller.this.tracer.tracer().currentSpan().context().traceId()).isEqualTo(traceId); + }); + } + +} + +class HogeBean { + + private String name; + + private int age; + + HogeBean(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return this.age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml index afd6bae53..715bffe31 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml @@ -1,99 +1,98 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-instrumentation-baggage-tests - jar - Spring Cloud Sleuth Brave Baggage Instrumentation Tests - Spring Cloud Sleuth Brave Baggage Instrumentation Tests - - - org.springframework.cloud - spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT - .. - - - - true - - - - - - - maven-deploy-plugin - - true - - - - - - - - org.springframework.cloud - spring-cloud-sleuth-tests-common - ${project.version} - - - org.springframework.boot - spring-boot-starter-aop - - - org.springframework.integration - spring-integration-core - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.boot - spring-boot-starter-test - - - io.zipkin.brave - brave-tests - - - org.awaitility - awaitility - - - com.squareup.okhttp3 - mockwebserver - - - com.squareup.okhttp3 - okhttp - - 4.8.0 - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-baggage-tests + jar + Spring Cloud Sleuth Brave Baggage Instrumentation Tests + Spring Cloud Sleuth Brave Baggage Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.cloud + spring-cloud-sleuth-tests-common + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.integration + spring-integration-core + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + com.squareup.okhttp3 + mockwebserver + + + com.squareup.okhttp3 + okhttp + + 4.8.0 + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/BaggageEntryTagSpanHandlerTest.java b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/BaggageEntryTagSpanHandlerTest.java index a2e79da1f..789b3cea0 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/BaggageEntryTagSpanHandlerTest.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/BaggageEntryTagSpanHandlerTest.java @@ -1,57 +1,57 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.baggage; - -import brave.sampler.Sampler; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; -import org.springframework.cloud.sleuth.test.TestSpanHandler; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.test.context.ContextConfiguration; - -/** - * @author Taras Danylchuk - */ -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) -@ContextConfiguration(classes = BaggageEntryTagSpanHandlerTest.Config.class) -public class BaggageEntryTagSpanHandlerTest - extends org.springframework.cloud.sleuth.baggage.BaggageEntryTagSpanHandlerTest { - - @Configuration(proxyBeanMethods = false) - static class Config { - - @Bean - TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler, Environment environment) { - return new BraveTestSpanHandler(testSpanHandler); - } - - @Bean - Sampler alwaysSampler() { - return Sampler.ALWAYS_SAMPLE; - } - - @Bean - brave.test.TestSpanHandler braveTestSpanHandler() { - return new brave.test.TestSpanHandler(); - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.baggage; + +import brave.sampler.Sampler; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Taras Danylchuk + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) +@ContextConfiguration(classes = BaggageEntryTagSpanHandlerTest.Config.class) +public class BaggageEntryTagSpanHandlerTest + extends org.springframework.cloud.sleuth.baggage.BaggageEntryTagSpanHandlerTest { + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler, Environment environment) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/MultipleHopsIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/MultipleHopsIntegrationTests.java index ce58ed6bd..e8cecfa3f 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/MultipleHopsIntegrationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/MultipleHopsIntegrationTests.java @@ -1,94 +1,101 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.baggage; - -import brave.baggage.BaggageField; -import brave.baggage.BaggagePropagationConfig; -import brave.sampler.Sampler; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.Span; -import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; -import org.springframework.cloud.sleuth.brave.bridge.BraveAccessor; -import org.springframework.cloud.sleuth.exporter.FinishedSpan; -import org.springframework.cloud.sleuth.test.TestSpanHandler; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.ContextConfiguration; - -import static java.util.Arrays.asList; -import static org.assertj.core.api.BDDAssertions.then; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -@SpringBootTest(webEnvironment = RANDOM_PORT) -@ContextConfiguration(classes = MultipleHopsIntegrationTests.Config.class) -public class MultipleHopsIntegrationTests - extends org.springframework.cloud.sleuth.baggage.multiple.MultipleHopsIntegrationTests { - - static final BaggageField REQUEST_ID = BaggageField.create("x-vcap-request-id"); - static final BaggageField COUNTRY_CODE = BaggageField.create("country-code"); - - @Override - protected void assertSpanNames() { - then(this.spans).extracting(FinishedSpan::getName).containsAll(asList("GET /greeting", "send")); - } - - @Override - protected void assertBaggage(Span initialSpan) { - // set with baggage api - then(this.application.allSpans()).as("All have request ID") - .allMatch(span -> "f4308d05-2228-4468-80f6-92a8377ba193" - .equals(REQUEST_ID.getValue(BraveAccessor.traceContext(span.context())))); - - // baz is not tagged in the initial span, only downstream! - then(this.application.allSpans()).as("All downstream have country-code") - .filteredOn(span -> !span.equals(initialSpan)) - .allMatch(span -> "FO".equals(COUNTRY_CODE.getValue(BraveAccessor.traceContext(span.context())))); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration( - exclude = { MongoAutoConfiguration.class, QuartzAutoConfiguration.class, JmxAutoConfiguration.class }) - static class Config { - - @Bean - TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { - return new BraveTestSpanHandler(testSpanHandler); - } - - @Bean - Sampler alwaysSampler() { - return Sampler.ALWAYS_SAMPLE; - } - - @Bean - brave.test.TestSpanHandler braveTestSpanHandler() { - return new brave.test.TestSpanHandler(); - } - - @Bean - BaggagePropagationConfig notInProperties() { - return BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("bar")); - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.baggage; + +import brave.baggage.BaggageField; +import brave.baggage.BaggagePropagationConfig; +import brave.sampler.Sampler; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.cloud.sleuth.brave.bridge.BraveAccessor; +import org.springframework.cloud.sleuth.exporter.FinishedSpan; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +import static java.util.Arrays.asList; +import static org.assertj.core.api.BDDAssertions.then; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +@SpringBootTest(webEnvironment = RANDOM_PORT) +@ContextConfiguration(classes = MultipleHopsIntegrationTests.Config.class) +public class MultipleHopsIntegrationTests + extends org.springframework.cloud.sleuth.baggage.multiple.MultipleHopsIntegrationTests { + + static final BaggageField REQUEST_ID = BaggageField.create("x-vcap-request-id"); + static final BaggageField COUNTRY_CODE = BaggageField.create("country-code"); + static final BaggageField CASE_INSENSITIVE_ID = BaggageField.create("foo-id"); + static final BaggageField NOT_PROPAGATED_HEADER = BaggageField.create("baz-id"); + + @Override + protected void assertSpanNames() { + then(this.spans).extracting(FinishedSpan::getName).containsAll(asList("GET /greeting", "send")); + } + + @Override + protected void assertBaggage(Span initialSpan) { + // set with baggage api + then(this.application.allSpans()).as("All have request ID") + .allMatch(span -> "f4308d05-2228-4468-80f6-92a8377ba193" + .equals(REQUEST_ID.getValue(BraveAccessor.traceContext(span.context())))); + + // baz is not tagged in the initial span, only downstream! + then(this.application.allSpans()).as("All downstream have country-code") + .filteredOn(span -> !span.equals(initialSpan)) + // it propagates only and all the `spring.sleuth.baggage.remote-fields` in + // case insensitive way + .allMatch(span -> "FO".equals(COUNTRY_CODE.getValue(BraveAccessor.traceContext(span.context())))) + .allMatch(span -> "123" + .equalsIgnoreCase(CASE_INSENSITIVE_ID.getValue(BraveAccessor.traceContext(span.context())))) + .allMatch(span -> NOT_PROPAGATED_HEADER.getValue(BraveAccessor.traceContext(span.context())) == null); + } + + @Configuration(proxyBeanMethods = false) + @EnableAutoConfiguration( + exclude = { MongoAutoConfiguration.class, QuartzAutoConfiguration.class, JmxAutoConfiguration.class }) + static class Config { + + @Bean + TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + @Bean + BaggagePropagationConfig notInProperties() { + return BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("bar")); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/W3CBaggageTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/W3CBaggageTests.java index 84872fa8c..b9c845a30 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/W3CBaggageTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/W3CBaggageTests.java @@ -1,55 +1,55 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.baggage; - -import brave.sampler.Sampler; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; -import org.springframework.cloud.sleuth.test.TestSpanHandler; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.ContextConfiguration; - -/** - * @author Taras Danylchuk - */ -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) -@ContextConfiguration(classes = W3CBaggageTests.Config.class) -public class W3CBaggageTests extends org.springframework.cloud.sleuth.baggage.W3CBaggageTests { - - @Configuration(proxyBeanMethods = false) - static class Config { - - @Bean - TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { - return new BraveTestSpanHandler(testSpanHandler); - } - - @Bean - Sampler alwaysSampler() { - return Sampler.ALWAYS_SAMPLE; - } - - @Bean - brave.test.TestSpanHandler braveTestSpanHandler() { - return new brave.test.TestSpanHandler(); - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.baggage; + +import brave.sampler.Sampler; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Taras Danylchuk + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) +@ContextConfiguration(classes = W3CBaggageTests.Config.class) +public class W3CBaggageTests extends org.springframework.cloud.sleuth.baggage.W3CBaggageTests { + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/pom.xml new file mode 100644 index 000000000..e90b36cdc --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/pom.xml @@ -0,0 +1,89 @@ + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests + jar + Spring Cloud Sleuth Brave Circuitbreaker Reactive Instrumentation Tests + Spring Cloud Sleuth Brave Circuitbreaker Reactive Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.cloud + spring-cloud-sleuth-tests-common + ${project.version} + + + io.projectreactor + reactor-core + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.cloud + spring-cloud-starter-circuitbreaker-reactor-resilience4j + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/ReactiveCircuitBreakerIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/ReactiveCircuitBreakerIntegrationTests.java new file mode 100644 index 000000000..3ef4e1b14 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/ReactiveCircuitBreakerIntegrationTests.java @@ -0,0 +1,60 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.circuitbreaker; + +import brave.sampler.Sampler; +import org.assertj.core.api.BDDAssertions; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.cloud.sleuth.exporter.FinishedSpan; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +@SpringBootTest +@ContextConfiguration(classes = ReactiveCircuitBreakerIntegrationTests.Config.class) +public class ReactiveCircuitBreakerIntegrationTests + extends org.springframework.cloud.sleuth.instrument.circuitbreaker.ReactiveCircuitBreakerIntegrationTests { + + @Override + public void assertException(FinishedSpan finishedSpan) { + BDDAssertions.then(finishedSpan.getTags().get("error")).contains("boom"); + } + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/ReactiveCircuitBreakerTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/ReactiveCircuitBreakerTests.java new file mode 100644 index 000000000..51beea76d --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/ReactiveCircuitBreakerTests.java @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.circuitbreaker; + +import org.assertj.core.api.BDDAssertions; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.exporter.FinishedSpan; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +public class ReactiveCircuitBreakerTests + extends org.springframework.cloud.sleuth.instrument.circuitbreaker.ReactiveCircuitBreakerTests { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + + @Override + public void additionalAssertions(FinishedSpan finishedSpan) { + BDDAssertions.then(finishedSpan.getTags().get("error")).contains("boom2"); + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/resources/application.yml b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/resources/application.yml new file mode 100644 index 000000000..f5756fce9 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/resources/application.yml @@ -0,0 +1,5 @@ +logging.level.org.springframework.cloud: DEBUG +logging.level.com.netflix.discovery.InstanceInfoReplicator: ERROR +logging.level.org.springframework.cloud.sleuth.brave.instrument.web.client.feign: TRACE + +spring.autoconfigure.exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration, org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration, org.springframework.cloud.gateway.config.GatewayAutoConfiguration, org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration, org.springframework.cloud.gateway.config.GatewayMetricsAutoConfiguration diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml index a10c184a0..72a38f2a3 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml @@ -1,85 +1,84 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-instrumentation-circuitbreaker-tests - jar - Spring Cloud Sleuth Brave Circuitbreaker Instrumentation Tests - Spring Cloud Sleuth Brave Circuitbreaker Instrumentation Tests - - - org.springframework.cloud - spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT - .. - - - - true - - - - - - - maven-deploy-plugin - - true - - - - - - - - org.springframework.cloud - spring-cloud-sleuth-tests-common - ${project.version} - - - org.springframework.boot - spring-boot-starter-aop - - - org.springframework.cloud - spring-cloud-starter-circuitbreaker-resilience4j - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.boot - spring-boot-starter-test - - - io.zipkin.brave - brave-tests - - - org.awaitility - awaitility - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-circuitbreaker-tests + jar + Spring Cloud Sleuth Brave Circuitbreaker Instrumentation Tests + Spring Cloud Sleuth Brave Circuitbreaker Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.cloud + spring-cloud-sleuth-tests-common + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.cloud + spring-cloud-starter-circuitbreaker-resilience4j + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/CircuitBreakerIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/CircuitBreakerIntegrationTests.java index b1702188c..58a99df56 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/CircuitBreakerIntegrationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/CircuitBreakerIntegrationTests.java @@ -1,60 +1,60 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.instrument.circuitbreaker; - -import brave.sampler.Sampler; -import org.assertj.core.api.BDDAssertions; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; -import org.springframework.cloud.sleuth.exporter.FinishedSpan; -import org.springframework.cloud.sleuth.test.TestSpanHandler; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.ContextConfiguration; - -@SpringBootTest -@ContextConfiguration(classes = CircuitBreakerIntegrationTests.Config.class) -public class CircuitBreakerIntegrationTests - extends org.springframework.cloud.sleuth.instrument.circuitbreaker.CircuitBreakerIntegrationTests { - - @Override - public void assertException(FinishedSpan finishedSpan) { - BDDAssertions.then(finishedSpan.getTags().get("error")).contains("boom"); - } - - @Configuration(proxyBeanMethods = false) - static class Config { - - @Bean - TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { - return new BraveTestSpanHandler(testSpanHandler); - } - - @Bean - Sampler alwaysSampler() { - return Sampler.ALWAYS_SAMPLE; - } - - @Bean - brave.test.TestSpanHandler braveTestSpanHandler() { - return new brave.test.TestSpanHandler(); - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.circuitbreaker; + +import brave.sampler.Sampler; +import org.assertj.core.api.BDDAssertions; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.cloud.sleuth.exporter.FinishedSpan; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +@SpringBootTest +@ContextConfiguration(classes = CircuitBreakerIntegrationTests.Config.class) +public class CircuitBreakerIntegrationTests + extends org.springframework.cloud.sleuth.instrument.circuitbreaker.CircuitBreakerIntegrationTests { + + @Override + public void assertException(FinishedSpan finishedSpan) { + BDDAssertions.then(finishedSpan.getTags().get("error")).contains("boom"); + } + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/CircuitBreakerTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/CircuitBreakerTests.java index 2d8aae8f1..5498eb864 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/CircuitBreakerTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/CircuitBreakerTests.java @@ -1,43 +1,43 @@ -/* - * Copyright 2013-2020 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 - * - * https://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.brave.instrument.circuitbreaker; - -import org.assertj.core.api.BDDAssertions; - -import org.springframework.cloud.sleuth.brave.BraveTestTracing; -import org.springframework.cloud.sleuth.exporter.FinishedSpan; -import org.springframework.cloud.sleuth.test.TestTracingAware; - -public class CircuitBreakerTests - extends org.springframework.cloud.sleuth.instrument.circuitbreaker.CircuitBreakerTests { - - BraveTestTracing testTracing; - - @Override - public TestTracingAware tracerTest() { - if (this.testTracing == null) { - this.testTracing = new BraveTestTracing(); - } - return this.testTracing; - } - - @Override - public void additionalAssertions(FinishedSpan finishedSpan) { - BDDAssertions.then(finishedSpan.getTags().get("error")).contains("boom2"); - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.circuitbreaker; + +import org.assertj.core.api.BDDAssertions; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.exporter.FinishedSpan; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +public class CircuitBreakerTests + extends org.springframework.cloud.sleuth.instrument.circuitbreaker.CircuitBreakerTests { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + + @Override + public void additionalAssertions(FinishedSpan finishedSpan) { + BDDAssertions.then(finishedSpan.getTags().get("error")).contains("boom2"); + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/pom.xml new file mode 100644 index 000000000..d032591b2 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/pom.xml @@ -0,0 +1,84 @@ + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-config-server-tests + jar + Spring Cloud Sleuth Brave Config Server Instrumentation Tests + Spring Cloud Sleuth Brave Config Server Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.cloud + spring-cloud-sleuth-tests-common + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.cloud + spring-cloud-config-server + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/config/ConfigServerIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/config/ConfigServerIntegrationTests.java new file mode 100644 index 000000000..36ac94359 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/config/ConfigServerIntegrationTests.java @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.config; + +import brave.sampler.Sampler; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ContextConfiguration(classes = ConfigServerIntegrationTests.Config.class) +public class ConfigServerIntegrationTests + extends org.springframework.cloud.sleuth.instrument.config.ConfigServerIntegrationTests { + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/src/test/resources/application.yml b/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/src/test/resources/application.yml new file mode 100644 index 000000000..f0238e134 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/src/test/resources/application.yml @@ -0,0 +1,3 @@ +logging.level.org.springframework.cloud: DEBUG + +spring.autoconfigure.exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration, org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml index 8ee215306..158b12c1e 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml @@ -1,108 +1,108 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-instrumentation-feign-tests - jar - Spring Cloud Sleuth Brave Feign Instrumentation Tests - Spring Cloud Sleuth Brave Feign Instrumentation Tests - - - org.springframework.cloud - spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT - .. - - - - true - - - - - - - maven-deploy-plugin - - true - - - - - - - - ${project.groupId} - spring-cloud-sleuth-tests-common - ${project.version} - - - org.springframework.boot - spring-boot-starter-web - - - com.squareup.okhttp3 - mockwebserver - - - com.squareup.okhttp3 - okhttp - - 4.8.0 - compile - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.cloud - spring-cloud-starter-openfeign - - - org.springframework.cloud - spring-cloud-starter-loadbalancer - - - org.springframework.cloud - spring-cloud-starter-circuitbreaker-resilience4j - - - io.github.openfeign - feign-okhttp - - - org.springframework.boot - spring-boot-starter-test - - - io.zipkin.brave - brave-tests - - - org.awaitility - awaitility - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-feign-tests + jar + Spring Cloud Sleuth Brave Feign Instrumentation Tests + Spring Cloud Sleuth Brave Feign Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + ${project.groupId} + spring-cloud-sleuth-tests-common + ${project.version} + + + org.springframework.boot + spring-boot-starter-web + + + com.squareup.okhttp3 + mockwebserver + + + com.squareup.okhttp3 + okhttp + + 4.8.0 + compile + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + org.springframework.cloud + spring-cloud-starter-circuitbreaker-resilience4j + + + io.github.openfeign + feign-okhttp + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/FeignRetriesTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/FeignRetriesTests.java index 4703c7668..83b015ea6 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/FeignRetriesTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/FeignRetriesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/TraceFeignAspectTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/TraceFeignAspectTests.java index 8bc1a3b48..16e41cf19 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/TraceFeignAspectTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/TraceFeignAspectTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/TracingFeignClientTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/TracingFeignClientTests.java index a5f0b0977..e881ec204 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/TracingFeignClientTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/TracingFeignClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue1125/ManuallyCreatedLoadBalancerFeignClientTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue1125/ManuallyCreatedLoadBalancerFeignClientTests.java index 2613bcce8..1e805ccce 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue1125/ManuallyCreatedLoadBalancerFeignClientTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue1125/ManuallyCreatedLoadBalancerFeignClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue1125delegates/ManuallyCreatedDelegateLoadBalancerFeignClientTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue1125delegates/ManuallyCreatedDelegateLoadBalancerFeignClientTests.java index 7886fd62f..d599bb1d8 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue1125delegates/ManuallyCreatedDelegateLoadBalancerFeignClientTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue1125delegates/ManuallyCreatedDelegateLoadBalancerFeignClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue307/Issue307Tests.java b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue307/Issue307Tests.java index 3f0b12123..2e51a8f5c 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue307/Issue307Tests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue307/Issue307Tests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue362/Issue362Tests.java b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue362/Issue362Tests.java index 01873f772..6b1787652 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue362/Issue362Tests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue362/Issue362Tests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue393/Issue393Tests.java b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue393/Issue393Tests.java index 217af80e7..690a51452 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue393/Issue393Tests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue393/Issue393Tests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue502/Issue502Tests.java b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue502/Issue502Tests.java index acdfed24e..b5ea5f6a8 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue502/Issue502Tests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/feign/issues/issue502/Issue502Tests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml index bcbed073d..75298e26b 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml @@ -1,81 +1,80 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-instrumentation-gateway-tests - jar - Spring Cloud Sleuth Brave Gateway Instrumentation Tests - Spring Cloud Sleuth Brave Gateway Instrumentation Tests - - - org.springframework.cloud - spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT - .. - - - - true - - - - - - - maven-deploy-plugin - - true - - - - - - - - org.springframework.cloud - spring-cloud-sleuth-tests-common - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-gateway - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.boot - spring-boot-starter-test - - - io.zipkin.brave - brave-tests - - - org.awaitility - awaitility - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-gateway-tests + jar + Spring Cloud Sleuth Brave Gateway Instrumentation Tests + Spring Cloud Sleuth Brave Gateway Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.cloud + spring-cloud-sleuth-tests-common + + + org.springframework.cloud + spring-cloud-starter-gateway + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceRequestHttpHeadersFilterTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceRequestHttpHeadersFilterTests.java index 53b239856..b7bac90f9 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceRequestHttpHeadersFilterTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceRequestHttpHeadersFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceResponseHttpHeadersFilterTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceResponseHttpHeadersFilterTests.java index 817d8a847..c8e7407e8 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceResponseHttpHeadersFilterTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceResponseHttpHeadersFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml index 6d583df94..a6c922c72 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml @@ -1,95 +1,95 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-instrumentation-grpc-tests - jar - Spring Cloud Sleuth Brave Grpc Instrumentation Tests - Spring Cloud Sleuth Brave Grpc Instrumentation Tests - - - org.springframework.cloud - spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT - .. - - - - true - - - - - - - maven-deploy-plugin - - true - - - - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.boot - spring-boot-starter-test - - - io.zipkin.brave - brave-tests - - - org.awaitility - awaitility - - - - com.google.guava - guava - ${guava.version} - - - - io.github.lognet - grpc-spring-boot-starter - - - io.zipkin.brave - brave-instrumentation-grpc - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-grpc-tests + jar + Spring Cloud Sleuth Brave Grpc Instrumentation Tests + Spring Cloud Sleuth Brave Grpc Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + com.google.guava + guava + ${guava.version} + + + + io.github.lognet + grpc-spring-boot-starter + + + io.zipkin.brave + brave-instrumentation-grpc + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/grpc/GrpcTracingIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/grpc/GrpcTracingIntegrationTests.java index 578543e6c..1d63fcd09 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/grpc/GrpcTracingIntegrationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/grpc/GrpcTracingIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloReply.java b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloReply.java index da6b92467..4b6bf5480 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloReply.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloReply.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloReplyOrBuilder.java b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloReplyOrBuilder.java index c882cc41e..586fe2a4b 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloReplyOrBuilder.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloReplyOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloRequest.java b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloRequest.java index 18dad29f9..f1e471824 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloRequest.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloRequestOrBuilder.java b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloRequestOrBuilder.java index 08624144b..01113721c 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloRequestOrBuilder.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloServiceGrpc.java b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloServiceGrpc.java index e2654a319..197f437cb 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloServiceGrpc.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloServiceGrpc.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloServiceOuterClass.java b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloServiceOuterClass.java index a492ab4ca..e001cb61f 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloServiceOuterClass.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/stubs/HelloServiceOuterClass.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-kafka-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-kafka-tests/pom.xml new file mode 100644 index 000000000..615564038 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-kafka-tests/pom.xml @@ -0,0 +1,97 @@ + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-kafka-tests + jar + Spring Cloud Sleuth Brave Kafka Instrumentation Tests + Spring Cloud Sleuth Brave Kafka Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + ${project.groupId} + spring-cloud-sleuth-tests-common + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.projectreactor.kafka + reactor-kafka + true + + + org.testcontainers + testcontainers + + + org.testcontainers + junit-jupiter + + + org.testcontainers + kafka + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-kafka-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/kafka/KafkaProducerTest.java b/tests/brave/spring-cloud-sleuth-instrumentation-kafka-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/kafka/KafkaProducerTest.java new file mode 100644 index 000000000..b19b6efc3 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-kafka-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/kafka/KafkaProducerTest.java @@ -0,0 +1,34 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.kafka; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +public class KafkaProducerTest extends org.springframework.cloud.sleuth.instrument.kafka.KafkaProducerTest { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml index 21d12e9f6..44244d5f9 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml @@ -1,85 +1,85 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-instrumentation-lettuce-tests - jar - Spring Cloud Sleuth Brave Lettuce Instrumentation Tests - Spring Cloud Sleuth Brave Lettuce Instrumentation Tests - - - org.springframework.cloud - spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT - .. - - - - true - - - - - - - maven-deploy-plugin - - true - - - - - - - - org.springframework.boot - spring-boot-starter-webflux - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.boot - spring-boot-starter-test - - - io.zipkin.brave - brave-tests - - - org.awaitility - awaitility - - - - io.lettuce - lettuce-core - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-lettuce-tests + jar + Spring Cloud Sleuth Brave Lettuce Instrumentation Tests + Spring Cloud Sleuth Brave Lettuce Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + io.lettuce + lettuce-core + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/redis/BraveRedisAutoConfigurationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/redis/BraveRedisAutoConfigurationTests.java index 22aa0da77..306ba7a2a 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/redis/BraveRedisAutoConfigurationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/redis/BraveRedisAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -62,7 +62,7 @@ public class BraveRedisAutoConfigurationTests { } @Bean - TestTraceLettuceClientResourcesBeanPostProcessor testTraceLettuceClientResourcesBeanPostProcessor( + static TestTraceLettuceClientResourcesBeanPostProcessor testTraceLettuceClientResourcesBeanPostProcessor( BeanFactory beanFactory) { return new TestTraceLettuceClientResourcesBeanPostProcessor(beanFactory); } diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml index 07a37b96f..5296a5e60 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml @@ -1,161 +1,160 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-instrumentation-messaging-tests - jar - Spring Cloud Sleuth Brave Messaging Instrumentation Tests - Spring Cloud Sleuth Brave Messaging Instrumentation Tests - - - org.springframework.cloud - spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT - .. - - - - true - - - - - - - maven-deploy-plugin - - true - - - - - - - - org.springframework.cloud - spring-cloud-sleuth-tests-common - ${project.version} - - - org.springframework.boot - spring-boot-starter-aop - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.cloud - spring-cloud-stream - jar - - - org.springframework.cloud - spring-cloud-stream - test-jar - test-binder - - - org.springframework.boot - spring-boot-starter-test - - - org.junit.vintage - junit-vintage-engine - - - - - io.zipkin.brave - brave-tests - - - org.awaitility - awaitility - - - io.zipkin.brave - brave-instrumentation-spring-rabbit - - - io.zipkin.brave - brave-instrumentation-kafka-clients - - - io.zipkin.brave - brave-instrumentation-kafka-streams - - - io.zipkin.brave - brave-instrumentation-jms - - - javax.jms - javax.jms-api - - - org.springframework - spring-jms - - - - org.springframework.integration - spring-integration-core - - - org.springframework.amqp - spring-rabbit - - - org.springframework.kafka - spring-kafka - - - org.apache.kafka - kafka-streams - - - org.springframework.boot - spring-boot-starter-activemq - - - - javax.resource - javax.resource-api - 1.7.1 - - - org.apache.activemq - activemq-ra - - - org.springframework.boot - spring-boot-starter-websocket - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-messaging-tests + jar + Spring Cloud Sleuth Brave Messaging Instrumentation Tests + Spring Cloud Sleuth Brave Messaging Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.cloud + spring-cloud-sleuth-tests-common + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.cloud + spring-cloud-stream + jar + + + org.springframework.cloud + spring-cloud-stream + test-jar + test-binder + + + org.springframework.boot + spring-boot-starter-test + + + org.junit.vintage + junit-vintage-engine + + + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + io.zipkin.brave + brave-instrumentation-spring-rabbit + + + io.zipkin.brave + brave-instrumentation-kafka-clients + + + io.zipkin.brave + brave-instrumentation-kafka-streams + + + io.zipkin.brave + brave-instrumentation-jms + + + javax.jms + javax.jms-api + + + org.springframework + spring-jms + + + + org.springframework.integration + spring-integration-core + + + org.springframework.amqp + spring-rabbit + + + org.springframework.kafka + spring-kafka + + + org.apache.kafka + kafka-streams + + + org.springframework.boot + spring-boot-starter-activemq + + + + javax.resource + javax.resource-api + 1.7.1 + + + org.apache.activemq + activemq-ra + + + org.springframework.boot + spring-boot-starter-websocket + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/BraveMessagingAutoConfiguration1664Tests.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/BraveMessagingAutoConfiguration1664Tests.java index 347ed1f66..4cf858ccf 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/BraveMessagingAutoConfiguration1664Tests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/BraveMessagingAutoConfiguration1664Tests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/BraveMessagingAutoConfigurationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/BraveMessagingAutoConfigurationTests.java index 406a8c15d..990e5b61a 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/BraveMessagingAutoConfigurationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/BraveMessagingAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -96,6 +96,10 @@ public class BraveMessagingAutoConfigurationTests { public void should_wrap_kafka() { this.producerFactory.createProducer(); then(this.mySleuthKafkaAspect.producerWrapped).isTrue(); + this.mySleuthKafkaAspect.producerWrapped = false; + + this.producerFactory.createNonTransactionalProducer(); + then(this.mySleuthKafkaAspect.producerWrapped).isTrue(); this.consumerFactory.createConsumer(); then(this.mySleuthKafkaAspect.consumerWrapped).isTrue(); @@ -163,7 +167,7 @@ public class BraveMessagingAutoConfigurationTests { } @Bean - SleuthRabbitBeanPostProcessor sleuthRabbitBeanPostProcessor(BeanFactory beanFactory) { + static SleuthRabbitBeanPostProcessor sleuthRabbitBeanPostProcessor(BeanFactory beanFactory) { return new TestSleuthRabbitBeanPostProcessor(beanFactory); } @@ -173,7 +177,7 @@ public class BraveMessagingAutoConfigurationTests { } @Bean - TestSleuthJmsBeanPostProcessor sleuthJmsBeanPostProcessor(BeanFactory beanFactory) { + static TestSleuthJmsBeanPostProcessor sleuthJmsBeanPostProcessor(BeanFactory beanFactory) { return new TestSleuthJmsBeanPostProcessor(beanFactory); } diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TraceWebSocketAutoConfigurationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TraceWebSocketAutoConfigurationTests.java index 5b3748e78..57d89e536 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TraceWebSocketAutoConfigurationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TraceWebSocketAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java index e3c4878e8..c4ba0202e 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -20,6 +20,9 @@ import java.util.List; import java.util.Map; import brave.Tracing; +import brave.baggage.BaggageField; +import brave.baggage.BaggagePropagation; +import brave.baggage.BaggagePropagationConfig; import brave.propagation.B3Propagation; import brave.propagation.TraceContext; import org.junit.jupiter.api.Test; @@ -45,8 +48,11 @@ public class TracingChannelInterceptorTest this.testTracing = new BraveTestTracing() { @Override public Tracing.Builder tracingBuilder() { - return super.tracingBuilder() - .propagationFactory(B3Propagation.newFactoryBuilder().injectFormat(SINGLE).build()); + return super.tracingBuilder().propagationFactory(BaggagePropagation + .newFactoryBuilder(B3Propagation.newFactoryBuilder().injectFormat(SINGLE).build()) + .add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("Foo-Id"))) + .add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("Baz-Id"))) + .build()); } }; this.testTracing.reset(); diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/BraveKafkaStreamsAutoConfigurationTest.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/BraveKafkaStreamsAutoConfigurationTest.java index 6a65fce7c..e070c4e51 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/BraveKafkaStreamsAutoConfigurationTest.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/BraveKafkaStreamsAutoConfigurationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/ITTracingChannelInterceptorTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/ITTracingChannelInterceptorTests.java index 9554b84d6..971cbc6d0 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/ITTracingChannelInterceptorTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/ITTracingChannelInterceptorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/JmsTracingConfigurationTest.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/JmsTracingConfigurationTest.java index 9d92eaedc..781653b0f 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/JmsTracingConfigurationTest.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/JmsTracingConfigurationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/StreamFunctionAdapterTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/StreamFunctionAdapterTests.java index fa4d988ae..49fc64488 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/StreamFunctionAdapterTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/StreamFunctionAdapterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/StreamMessageOperatorsTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/StreamMessageOperatorsTests.java index 7f17912a7..2e3129158 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/StreamMessageOperatorsTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/StreamMessageOperatorsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceContextPropagationChannelInterceptorTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceContextPropagationChannelInterceptorTests.java index 1605fbfe1..d25a4a76d 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceContextPropagationChannelInterceptorTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceContextPropagationChannelInterceptorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceStreamChannelInterceptorTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceStreamChannelInterceptorTests.java index 065684cf1..f0ed6b728 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceStreamChannelInterceptorTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceStreamChannelInterceptorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/CustomExecutorConfig.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/CustomExecutorConfig.java index 51a9636a1..58d4e99f0 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/CustomExecutorConfig.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/CustomExecutorConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/HelloSpringIntegration.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/HelloSpringIntegration.java index d784c9ba6..66a907885 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/HelloSpringIntegration.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/HelloSpringIntegration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/HelloWorldImpl.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/HelloWorldImpl.java index 5f8609a30..f85c5c37e 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/HelloWorldImpl.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/HelloWorldImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/HelloWorldRestController.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/HelloWorldRestController.java index d79a472be..8b63618d0 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/HelloWorldRestController.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/HelloWorldRestController.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/Issue943Tests.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/Issue943Tests.java index 576a94c18..043d916a3 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/Issue943Tests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/Issue943Tests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/MessagingGateway.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/MessagingGateway.java index eb54da8bf..54f82f590 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/MessagingGateway.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/MessagingGateway.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/util/SpanUtil.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/util/SpanUtil.java index 463be41c8..77e48cbb9 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/util/SpanUtil.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/util/SpanUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml index 607216c06..0977a9f1c 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml @@ -1,108 +1,108 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-instrumentation-mvc-tests - jar - Spring Cloud Sleuth Brave Mvc Instrumentation Tests - Spring Cloud Sleuth Brave Mvc Instrumentation Tests - - - org.springframework.cloud - spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT - .. - - - - true - - - - - - - maven-deploy-plugin - - true - - - - - - - - ${project.groupId} - spring-cloud-sleuth-tests-common - ${project.version} - - - org.springframework.boot - spring-boot-starter-aop - - - org.apache.httpcomponents - httpclient - - - com.squareup.okhttp3 - mockwebserver - - - com.squareup.okhttp3 - okhttp - - 4.8.0 - compile - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.boot - spring-boot-starter-test - - - io.zipkin.brave - brave-tests - - - org.awaitility - awaitility - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-mvc-tests + jar + Spring Cloud Sleuth Brave Mvc Instrumentation Tests + Spring Cloud Sleuth Brave Mvc Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + ${project.groupId} + spring-cloud-sleuth-tests-common + ${project.version} + + + org.springframework.boot + spring-boot-starter-aop + + + org.apache.httpcomponents + httpclient + + + com.squareup.okhttp3 + mockwebserver + + + com.squareup.okhttp3 + okhttp + + 4.8.0 + compile + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/AbstractMvcIntegrationTest.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/AbstractMvcIntegrationTest.java index 99ef78cbb..364e2d2db 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/AbstractMvcIntegrationTest.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/AbstractMvcIntegrationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/HttpServerParserTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/HttpServerParserTests.java index 196ab4aea..7d49f16be 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/HttpServerParserTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/HttpServerParserTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java index fec902c66..fb9acb4d0 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithBasePath.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithBasePath.java index 92ccd050a..e0b450056 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithBasePath.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithBasePath.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath.java index 2397cd928..66fbe6810 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath.java index b1877e501..b35589664 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath.java index 1265662f9..d797ef57f 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceAsyncIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceAsyncIntegrationTests.java index ffbc6807b..7cadaef46 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceAsyncIntegrationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceAsyncIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceCustomFilterResponseInjectorTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceCustomFilterResponseInjectorTests.java index f1b007730..88c99b289 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceCustomFilterResponseInjectorTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceCustomFilterResponseInjectorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterIntegrationTests.java index b2527190b..6ed1f1983 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterIntegrationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -45,7 +45,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.CurrentTraceContext; import org.springframework.cloud.sleuth.autoconfig.instrument.web.SleuthWebProperties; +import org.springframework.cloud.sleuth.http.HttpServerHandler; import org.springframework.cloud.sleuth.instrument.web.servlet.TracingFilter; import org.springframework.cloud.sleuth.util.SpanUtil; import org.springframework.context.annotation.Bean; @@ -78,7 +80,10 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest { private static Span span; @Autowired - TracingFilter traceFilter; + CurrentTraceContext currentTraceContext; + + @Autowired + HttpServerHandler httpServerHandler; @Autowired MyFilter myFilter; @@ -222,7 +227,8 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest { @Override protected void configureMockMvcBuilder(DefaultMockMvcBuilder mockMvcBuilder) { - mockMvcBuilder.addFilters(this.traceFilter, this.myFilter); + mockMvcBuilder.addFilters(TracingFilter.create(this.currentTraceContext, this.httpServerHandler), + this.myFilter); } private MvcResult whenSentPingWithoutTracingData() throws Exception { diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterTests.java index 65ac88d6b..739052137 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterWebIntegrationMultipleFiltersTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterWebIntegrationMultipleFiltersTests.java index eeacaa712..0cc7e41fc 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterWebIntegrationMultipleFiltersTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterWebIntegrationMultipleFiltersTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterWebIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterWebIntegrationTests.java index d17863743..0eb5bc3cd 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterWebIntegrationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterWebIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceWebDisabledTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceWebDisabledTests.java index 9ce9dfbf4..8cea86216 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceWebDisabledTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceWebDisabledTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/MultipleAsyncRestTemplateTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/MultipleAsyncRestTemplateTests.java index 84608ae62..0ba549267 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/MultipleAsyncRestTemplateTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/MultipleAsyncRestTemplateTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/RestTemplateTraceAspectIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/RestTemplateTraceAspectIntegrationTests.java index fa3dcf840..0a454dbc0 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/RestTemplateTraceAspectIntegrationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/RestTemplateTraceAspectIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java index 57c9e11a0..7a69db515 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceRestTemplateInterceptorTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceRestTemplateInterceptorTests.java index ba66f0e18..ffe5e7162 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceRestTemplateInterceptorTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceRestTemplateInterceptorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceWebAsyncClientAutoConfigurationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceWebAsyncClientAutoConfigurationTests.java index 6997dc907..80f5cfeee 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceWebAsyncClientAutoConfigurationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/TraceWebAsyncClientAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/exceptionresolver/Issue585Tests.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/exceptionresolver/Issue585Tests.java index c164687b4..295d35662 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/exceptionresolver/Issue585Tests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/exceptionresolver/Issue585Tests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/view/Issue469.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/view/Issue469.java index 71855f9bb..4e62e07d2 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/view/Issue469.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/view/Issue469.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/view/Issue469Tests.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/view/Issue469Tests.java index 4cbcc94c6..873bfba21 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/view/Issue469Tests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/view/Issue469Tests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/util/SpanUtil.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/util/SpanUtil.java index cc5fa1e5f..f2de2e89a 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/util/SpanUtil.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/util/SpanUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml index 9a791ee6f..10575ecb9 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml @@ -1,81 +1,80 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-instrumentation-quartz-tests - jar - Spring Cloud Sleuth Brave Quartz Instrumentation Tests - Spring Cloud Sleuth Brave Quartz Instrumentation Tests - - - org.springframework.cloud - spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT - .. - - - - true - - - - - - - maven-deploy-plugin - - true - - - - - - - - org.springframework.boot - spring-boot-starter-quartz - - - org.springframework.cloud - spring-cloud-sleuth-tests-common - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.boot - spring-boot-starter-test - - - io.zipkin.brave - brave-tests - - - org.awaitility - awaitility - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-quartz-tests + jar + Spring Cloud Sleuth Brave Quartz Instrumentation Tests + Spring Cloud Sleuth Brave Quartz Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.boot + spring-boot-starter-quartz + + + org.springframework.cloud + spring-cloud-sleuth-tests-common + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/quartz/TracingJobListenerTest.java b/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/quartz/TracingJobListenerTest.java index 825e17d6d..bc42f8ced 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/quartz/TracingJobListenerTest.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/quartz/TracingJobListenerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml index d495b1c2c..77786d822 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml @@ -1,107 +1,106 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-instrumentation-reactor-tests - jar - Spring Cloud Sleuth Brave Reactor Instrumentation Tests - Spring Cloud Sleuth Brave Reactor Instrumentation Tests - - - org.springframework.cloud - spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT - .. - - - - true - - - - - - - maven-deploy-plugin - - true - - - - - - - - org.springframework.cloud - spring-cloud-sleuth-tests-common - ${project.version} - - - org.springframework.boot - spring-boot-starter-webflux - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - io.zipkin.brave - brave-instrumentation-http-tests - - - org.eclipse.jetty - * - - - - - org.springframework.boot - spring-boot-starter-test - - - io.zipkin.brave - brave-tests - - - org.awaitility - awaitility - - - io.projectreactor - reactor-core - - - io.projectreactor.netty - reactor-netty-http - - - org.reactivestreams - reactive-streams - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-reactor-tests + jar + Spring Cloud Sleuth Brave Reactor Instrumentation Tests + Spring Cloud Sleuth Brave Reactor Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.cloud + spring-cloud-sleuth-tests-common + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + io.zipkin.brave + brave-instrumentation-http-tests + + + org.eclipse.jetty + * + + + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + io.projectreactor + reactor-core + + + io.projectreactor.netty + reactor-netty-http + + + org.reactivestreams + reactive-streams + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/reactor/FlatMapTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/reactor/FlatMapTests.java index b1530374e..ae6220373 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/reactor/FlatMapTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/reactor/FlatMapTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/reactor/FlowsScopePassingSpanSubscriberTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/reactor/FlowsScopePassingSpanSubscriberTests.java index d3fd5806c..14ff3c40d 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/reactor/FlowsScopePassingSpanSubscriberTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/reactor/FlowsScopePassingSpanSubscriberTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/reactor/ScopePassingSpanSubscriberSpringBootTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/reactor/ScopePassingSpanSubscriberSpringBootTests.java index 1756ee5da..2cad83fea 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/reactor/ScopePassingSpanSubscriberSpringBootTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/reactor/ScopePassingSpanSubscriberSpringBootTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/reactor/ScopePassingSpanSubscriberTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/reactor/ScopePassingSpanSubscriberTests.java index 66f18cb11..14609783b 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/reactor/ScopePassingSpanSubscriberTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/reactor/ScopePassingSpanSubscriberTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/ITSpringConfiguredReactorClient.java b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/ITSpringConfiguredReactorClient.java index d0e9d0aad..f961f1bd3 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/ITSpringConfiguredReactorClient.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/ITSpringConfiguredReactorClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/ReactorNettyHttpClientBraveTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/ReactorNettyHttpClientBraveTests.java index c35e89e5f..1823b94b9 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/ReactorNettyHttpClientBraveTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/ReactorNettyHttpClientBraveTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TestHttpCallbackSubscriber.java b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TestHttpCallbackSubscriber.java index dc16677bd..e2498df9b 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TestHttpCallbackSubscriber.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TestHttpCallbackSubscriber.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/WebClientBraveTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/WebClientBraveTests.java index e3b8cc42f..d39254d25 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/WebClientBraveTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/WebClientBraveTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/resources/application.yml b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/resources/application.yml index 9ed06adbb..1144d1716 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/resources/application.yml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/resources/application.yml @@ -1,3 +1,4 @@ logging.level.org.springframework.cloud: DEBUG +logging.level.org.springframework.cloud.sleuth.autoconfig.instrument.reactor: TRACE logging.level.com.netflix.discovery.InstanceInfoReplicator: ERROR logging.level.org.springframework.cloud.sleuth.brave.instrument.web.client.feign: TRACE \ No newline at end of file diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/pom.xml new file mode 100644 index 000000000..5df34188c --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/pom.xml @@ -0,0 +1,100 @@ + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-rsocket-tests + jar + Spring Cloud Sleuth Brave RSocket Instrumentation Tests + Spring Cloud Sleuth Brave RSocket Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + ${project.groupId} + spring-cloud-sleuth-tests-common + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + org.springframework.boot + spring-boot-starter-rsocket + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/rsocket/TraceRSocketTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/rsocket/TraceRSocketTests.java new file mode 100644 index 000000000..4cd869a93 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/rsocket/TraceRSocketTests.java @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.rsocket; + +import brave.sampler.Sampler; + +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +public class TraceRSocketTests extends org.springframework.cloud.sleuth.instrument.rsocket.TraceRSocketTests { + + @Override + protected Class testConfiguration() { + return Config.class; + } + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + org.springframework.cloud.sleuth.test.TestSpanHandler testSpanHandlerSupplier( + brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/src/test/resources/logback.xml b/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/src/test/resources/logback.xml new file mode 100644 index 000000000..c5c54bb21 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/src/test/resources/logback.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml index 9f2be1e0b..23974f1d8 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml @@ -1,85 +1,84 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-instrumentation-rxjava-tests - jar - Spring Cloud Sleuth Brave RxJava Instrumentation Tests - Spring Cloud Sleuth Brave RxJava Instrumentation Tests - - - org.springframework.cloud - spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT - .. - - - - true - - - - - - - maven-deploy-plugin - - true - - - - - - - - org.springframework.cloud - spring-cloud-sleuth-tests-common - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.boot - spring-boot-starter-test - - - io.zipkin.brave - brave-tests - - - org.awaitility - awaitility - - - io.reactivex - rxjava - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-rxjava-tests + jar + Spring Cloud Sleuth Brave RxJava Instrumentation Tests + Spring Cloud Sleuth Brave RxJava Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.cloud + spring-cloud-sleuth-tests-common + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + io.reactivex + rxjava + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersHookTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersHookTests.java index 8ab4bda76..340c237b2 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersHookTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersHookTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaTests.java index eeeb3c565..79b1a596e 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml index 925d72eec..be4401cc7 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml @@ -1,76 +1,72 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-instrumentation-scheduling-tests - jar - Spring Cloud Sleuth Brave Scheduling Instrumentation Tests - Spring Cloud Sleuth Brave Scheduling Instrumentation Tests - - - org.springframework.cloud - spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT - .. - - - - true - - - - - - - maven-deploy-plugin - - true - - - - - - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.boot - spring-boot-starter-test - - - io.zipkin.brave - brave-tests - - - org.awaitility - awaitility - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-scheduling-tests + jar + Spring Cloud Sleuth Brave Scheduling Instrumentation Tests + Spring Cloud Sleuth Brave Scheduling Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TracingOnScheduledTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TracingOnScheduledTests.java index 6f5ded90f..de4119cbc 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TracingOnScheduledTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TracingOnScheduledTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/pom.xml new file mode 100644 index 000000000..01455919a --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/pom.xml @@ -0,0 +1,81 @@ + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-task-tests + jar + Spring Cloud Sleuth Brave Task Instrumentation Tests + Spring Cloud Sleuth Brave Task Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.cloud + spring-cloud-sleuth-tests-common + ${project.version} + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.cloud + spring-cloud-starter-task + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/task/SpringCloudTaskIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/task/SpringCloudTaskIntegrationTests.java new file mode 100644 index 000000000..55d08c60a --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/task/SpringCloudTaskIntegrationTests.java @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.task; + +import brave.sampler.Sampler; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +@SpringBootTest +@ContextConfiguration(classes = SpringCloudTaskIntegrationTests.Config.class) +public class SpringCloudTaskIntegrationTests + extends org.springframework.cloud.sleuth.instrument.task.SpringCloudTaskIntegrationTests { + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/src/test/resources/application.yml b/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/src/test/resources/application.yml new file mode 100644 index 000000000..2b87cbf49 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/src/test/resources/application.yml @@ -0,0 +1 @@ +logging.level.org.springframework.cloud: DEBUG diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml index 14b35e592..61dbdeaff 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml @@ -1,105 +1,105 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-instrumentation-webflux-tests - jar - Spring Cloud Sleuth Brave WebFlux Instrumentation Tests - Spring Cloud Sleuth Brave WebFlux Instrumentation Tests - - - org.springframework.cloud - spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT - .. - - - - true - - - - - - - maven-deploy-plugin - - true - - - - - - - - ${project.groupId} - spring-cloud-sleuth-tests-common - ${project.version} - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.boot - spring-boot-starter-aop - - - org.springframework.cloud - spring-cloud-starter-loadbalancer - - - org.springframework.cloud - spring-cloud-starter-openfeign - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.boot - spring-boot-starter-webflux - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.boot - spring-boot-starter-test - - - io.zipkin.brave - brave-tests - - - org.awaitility - awaitility - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-webflux-tests + jar + Spring Cloud Sleuth Brave WebFlux Instrumentation Tests + Spring Cloud Sleuth Brave WebFlux Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + ${project.groupId} + spring-cloud-sleuth-tests-common + ${project.version} + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/GH1102Tests.java b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/GH1102Tests.java index 874acd03f..e3878d880 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/GH1102Tests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/GH1102Tests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceWebFluxTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceWebFluxTests.java index e4335ef17..294c0e700 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceWebFluxTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceWebFluxTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -83,6 +83,12 @@ public class TraceWebFluxTests { thenSpanWith404StatusCodeWasReported(spans, response); spans.clear(); + // when + response = whenRequestIsSent(port, "/exception"); + // then + thenSpanWithExceptionWasReported(spans, response); + spans.clear(); + // when ClientResponse nonSampledResponse = whenNonSampledRequestIsSent(port); // then @@ -137,6 +143,12 @@ public class TraceWebFluxTests { then(spans.get(0).tags()).hasEntrySatisfying("http.status_code", value -> then(value).isEqualTo("404")); } + private void thenSpanWithExceptionWasReported(TestSpanHandler spans, ClientResponse response) { + Awaitility.await().untilAsserted(() -> then(response.statusCode().value()).isEqualTo(500)); + then(spans).hasSize(1); + then(spans.get(0).tags()).hasEntrySatisfying("http.status_code", value -> then(value).isEqualTo("500")); + } + private void thenNoSpanWasReported(TestSpanHandler spans, ClientResponse response, Controller2 controller2) { Awaitility.await().untilAsserted(() -> { then(response.statusCode().value()).isEqualTo(200); @@ -229,6 +241,11 @@ public class TraceWebFluxTests { return Flux.just(sampled.toString()); } + @GetMapping("/exception") + public Flux exception() { + throw new RuntimeException("Exception"); + } + } } diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/HttpClientBeanPostProcessorTest.java b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/HttpClientBeanPostProcessorTest.java index 2c53a02f5..67438fc06 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/HttpClientBeanPostProcessorTest.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/HttpClientBeanPostProcessorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/MergedFactory.java b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/MergedFactory.java index 9b313383f..6168ebc72 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/MergedFactory.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/MergedFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/ReactorNettyHttpClientSpringBootTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/ReactorNettyHttpClientSpringBootTests.java index c56a87dab..c14a41d49 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/ReactorNettyHttpClientSpringBootTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/ReactorNettyHttpClientSpringBootTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientCustomParserTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientCustomParserTests.java index 06ddd42f5..8bb5a9eac 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientCustomParserTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientCustomParserTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientDiscoveryExceptionTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientDiscoveryExceptionTests.java index bff80af24..9e17524c2 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientDiscoveryExceptionTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientDiscoveryExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientExceptionTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientExceptionTests.java index 1192c7df1..334c193fc 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientExceptionTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientNotSampledTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientNotSampledTests.java index c33d8993f..c762d7c2e 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientNotSampledTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientNotSampledTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientTests.java index 70b7365fc..d893b007f 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/client/WebClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/util/SpanUtil.java b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/util/SpanUtil.java index ce959c2d3..2568e026e 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/util/SpanUtil.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/util/SpanUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml b/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml index 1f13c2925..ea2db8839 100644 --- a/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml @@ -1,151 +1,150 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-zipkin-tests - jar - Spring Cloud Sleuth Brave Zipkin Tests - Spring Cloud Sleuth Brave Zipkin Tests - - - org.springframework.cloud - spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT - .. - - - - true - - - - - - - maven-deploy-plugin - - true - - - - - - - - org.springframework.cloud - spring-cloud-sleuth-tests-common - ${project.version} - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.cloud - spring-cloud-sleuth-zipkin - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.kafka - spring-kafka - - - org.springframework.amqp - spring-rabbit - - - io.zipkin.zipkin2 - zipkin - - - io.zipkin.reporter2 - zipkin-reporter - - - io.zipkin.reporter2 - zipkin-reporter-brave - - - io.zipkin.reporter2 - zipkin-sender-kafka - - - - org.apache.kafka - kafka-clients - - - - - io.zipkin.reporter2 - zipkin-sender-activemq-client - - - org.apache.activemq - activemq-client - - - - - org.apache.activemq - activemq-client - - - io.zipkin.reporter2 - zipkin-sender-amqp-client - - - - com.rabbitmq - amqp-client - - - - - org.springframework.boot - spring-boot-starter-test - - - io.zipkin.brave - brave-tests - - - org.awaitility - awaitility - - - com.squareup.okhttp3 - mockwebserver - - - com.squareup.okhttp3 - okhttp - - 4.8.0 - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-zipkin-tests + jar + Spring Cloud Sleuth Brave Zipkin Tests + Spring Cloud Sleuth Brave Zipkin Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.cloud + spring-cloud-sleuth-tests-common + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.cloud + spring-cloud-sleuth-zipkin + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.kafka + spring-kafka + + + org.springframework.amqp + spring-rabbit + + + io.zipkin.zipkin2 + zipkin + + + io.zipkin.reporter2 + zipkin-reporter + + + io.zipkin.reporter2 + zipkin-reporter-brave + + + io.zipkin.reporter2 + zipkin-sender-kafka + + + + org.apache.kafka + kafka-clients + + + + + io.zipkin.reporter2 + zipkin-sender-activemq-client + + + org.apache.activemq + activemq-client + + + + + org.apache.activemq + activemq-client + + + io.zipkin.reporter2 + zipkin-sender-amqp-client + + + + com.rabbitmq + amqp-client + + + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + com.squareup.okhttp3 + mockwebserver + + + com.squareup.okhttp3 + okhttp + + 4.8.0 + + + + diff --git a/tests/brave/spring-cloud-sleuth-zipkin-tests/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/BraveDefaultEndpointLocatorConfigurationTest.java b/tests/brave/spring-cloud-sleuth-zipkin-tests/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/BraveDefaultEndpointLocatorConfigurationTest.java index 04cf3c7c1..d5264d8bb 100644 --- a/tests/brave/spring-cloud-sleuth-zipkin-tests/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/BraveDefaultEndpointLocatorConfigurationTest.java +++ b/tests/brave/spring-cloud-sleuth-zipkin-tests/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/BraveDefaultEndpointLocatorConfigurationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-zipkin-tests/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/BraveZipkinAutoConfigurationTests.java b/tests/brave/spring-cloud-sleuth-zipkin-tests/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/BraveZipkinAutoConfigurationTests.java index 83ac61076..7449ab5c3 100644 --- a/tests/brave/spring-cloud-sleuth-zipkin-tests/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/BraveZipkinAutoConfigurationTests.java +++ b/tests/brave/spring-cloud-sleuth-zipkin-tests/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/BraveZipkinAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/brave/spring-cloud-sleuth-zipkin-tests/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/BraveZipkinDiscoveryClientTests.java b/tests/brave/spring-cloud-sleuth-zipkin-tests/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/BraveZipkinDiscoveryClientTests.java index d5b71be30..ff9aa3128 100644 --- a/tests/brave/spring-cloud-sleuth-zipkin-tests/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/BraveZipkinDiscoveryClientTests.java +++ b/tests/brave/spring-cloud-sleuth-zipkin-tests/src/test/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/BraveZipkinDiscoveryClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/pom.xml b/tests/common/pom.xml index 861aff01e..7c1fb98de 100644 --- a/tests/common/pom.xml +++ b/tests/common/pom.xml @@ -1,195 +1,235 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-tests-common - jar - Spring Cloud Sleuth Tests Common - Spring Cloud Sleuth Tests Common - - - org.springframework.cloud - spring-cloud-sleuth-tests - 3.0.2-SNAPSHOT - .. - - - - - org.springframework.cloud - spring-cloud-sleuth-instrumentation - - - org.springframework.boot - spring-boot-starter-test - compile - - - org.awaitility - awaitility - compile - - - com.squareup.okhttp3 - mockwebserver - true - - - org.springframework.integration - spring-integration-core - true - - - org.springframework.boot - spring-boot-starter-websocket - true - - - org.springframework.boot - spring-boot-starter-actuator - true - - - org.springframework.boot - spring-boot-starter-web - true - - - org.springframework.boot - spring-boot-starter-webflux - true - - - org.springframework.cloud - spring-cloud-starter-gateway - true - - - org.springframework.cloud - spring-cloud-starter-circuitbreaker-resilience4j - true - - - org.springframework.boot - spring-boot-starter-quartz - true - - - org.springframework.cloud - spring-cloud-starter-openfeign - true - - - io.github.openfeign - feign-okhttp - true - - - org.springframework.cloud - spring-cloud-starter-loadbalancer - true - - - org.apache.httpcomponents - httpclient - true - - - org.springframework.cloud - spring-cloud-sleuth-autoconfigure - true - - - org.springframework.cloud - spring-cloud-sleuth-brave - true - - - io.zipkin.brave - brave-tests - true - - - org.springframework.cloud - spring-cloud-sleuth-zipkin - true - - - io.zipkin.zipkin2 - zipkin - true - - - io.zipkin.reporter2 - zipkin-reporter - true - - - io.zipkin.reporter2 - zipkin-reporter-brave - true - - - io.zipkin.reporter2 - zipkin-sender-kafka - true - - - - org.apache.kafka - kafka-clients - - - - - io.zipkin.reporter2 - zipkin-sender-activemq-client - true - - - org.apache.activemq - activemq-client - - - - - org.apache.activemq - activemq-client - true - - - io.zipkin.reporter2 - zipkin-sender-amqp-client - true - - - - com.rabbitmq - amqp-client - - - - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-tests-common + jar + Spring Cloud Sleuth Tests Common + Spring Cloud Sleuth Tests Common + + + org.springframework.cloud + spring-cloud-sleuth-tests + 3.1.0-SNAPSHOT + .. + + + + + org.springframework.cloud + spring-cloud-sleuth-instrumentation + + + org.springframework.boot + spring-boot-starter-test + compile + + + org.awaitility + awaitility + compile + + + com.squareup.okhttp3 + mockwebserver + true + + + org.springframework.integration + spring-integration-core + true + + + org.springframework.boot + spring-boot-starter-websocket + true + + + org.springframework.boot + spring-boot-starter-actuator + true + + + org.springframework.boot + spring-boot-starter-web + true + + + org.springframework.boot + spring-boot-starter-webflux + true + + + org.springframework.cloud + spring-cloud-starter-gateway + true + + + org.springframework.cloud + spring-cloud-starter-task + true + + + org.springframework.cloud + spring-cloud-starter-circuitbreaker-resilience4j + true + + + org.springframework.cloud + spring-cloud-starter-circuitbreaker-reactor-resilience4j + true + + + org.springframework.boot + spring-boot-starter-quartz + true + + + org.springframework.cloud + spring-cloud-starter-openfeign + true + + + io.github.openfeign + feign-okhttp + true + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + true + + + org.springframework.cloud + spring-cloud-config-server + true + + + org.apache.httpcomponents + httpclient + true + + + org.springframework.cloud + spring-cloud-sleuth-autoconfigure + true + + + org.springframework.cloud + spring-cloud-sleuth-brave + true + + + io.zipkin.brave + brave-tests + true + + + io.projectreactor.kafka + reactor-kafka + true + + + org.testcontainers + testcontainers + true + + + org.testcontainers + junit-jupiter + true + + + org.testcontainers + kafka + true + + + org.springframework.boot + spring-boot-starter-rsocket + true + + + org.springframework.cloud + spring-cloud-sleuth-zipkin + true + + + io.zipkin.zipkin2 + zipkin + true + + + io.zipkin.reporter2 + zipkin-reporter + true + + + io.zipkin.reporter2 + zipkin-reporter-brave + true + + + io.zipkin.reporter2 + zipkin-sender-kafka + true + + + + org.apache.kafka + kafka-clients + + + + + io.zipkin.reporter2 + zipkin-sender-activemq-client + true + + + org.apache.activemq + activemq-client + + + + + org.apache.activemq + activemq-client + true + + + io.zipkin.reporter2 + zipkin-sender-amqp-client + true + + + + com.rabbitmq + amqp-client + + + + + + + diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/Issue866Configuration.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/Issue866Configuration.java similarity index 97% rename from spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/Issue866Configuration.java rename to tests/common/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/Issue866Configuration.java index 9da3931e9..3c5c5e835 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/Issue866Configuration.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/Issue866Configuration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/DefaultEndpointLocatorConfigurationTest.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/DefaultEndpointLocatorConfigurationTest.java index 7eff7f51d..13928083f 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/DefaultEndpointLocatorConfigurationTest.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/DefaultEndpointLocatorConfigurationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinAutoConfigurationTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinAutoConfigurationTests.java index 8ee4053ac..3267a99b5 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinAutoConfigurationTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/BaggageEntryTagSpanHandlerTest.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/BaggageEntryTagSpanHandlerTest.java index 972140657..e1798776f 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/BaggageEntryTagSpanHandlerTest.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/BaggageEntryTagSpanHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/W3CBaggageTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/W3CBaggageTests.java index 8ec9334dd..baf9c201d 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/W3CBaggageTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/W3CBaggageTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/multiple/DemoApplication.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/multiple/DemoApplication.java index 0485ca987..b145ecdca 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/multiple/DemoApplication.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/multiple/DemoApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/multiple/MultipleHopsIntegrationTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/multiple/MultipleHopsIntegrationTests.java index d6bc105fe..83514b534 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/multiple/MultipleHopsIntegrationTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/multiple/MultipleHopsIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -52,7 +52,7 @@ import static org.assertj.core.api.BDDAssertions.then; import static org.awaitility.Awaitility.await; @ContextConfiguration(classes = MultipleHopsIntegrationTests.TestConfig.class) -@TestPropertySource(properties = { "spring.sleuth.baggage.remote-fields=x-vcap-request-id,country-code", +@TestPropertySource(properties = { "spring.sleuth.baggage.remote-fields=x-vcap-request-id,country-code,Foo-Id", "spring.sleuth.baggage.local-fields=bp", "spring.sleuth.integration.enabled=true" }) public abstract class MultipleHopsIntegrationTests { @@ -62,6 +62,10 @@ public abstract class MultipleHopsIntegrationTests { protected static final String COUNTRY_CODE = "country-code"; + protected static final String CASE_INSENSITIVE_ID = "Foo-Id"; + + protected static final String NOT_PROPAGATED_HEADER = "baz-id"; + @Autowired Tracer tracer; @@ -117,6 +121,8 @@ public abstract class MultipleHopsIntegrationTests { // set request ID in a header not with the api explicitly HttpHeaders headers = new HttpHeaders(); headers.put(REQUEST_ID, Collections.singletonList("f4308d05-2228-4468-80f6-92a8377ba193")); + headers.put(CASE_INSENSITIVE_ID, Collections.singletonList("123")); + headers.put(NOT_PROPAGATED_HEADER, Collections.singletonList("456")); RequestEntity requestEntity = new RequestEntity(headers, HttpMethod.GET, URI.create("http://localhost:" + this.testConfig.port + "/greeting")); this.restTemplate.exchange(requestEntity, String.class); diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/BraveIntegrationTestTracing.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/BraveIntegrationTestTracing.java index 28617fe70..d787e6edb 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/BraveIntegrationTestTracing.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/BraveIntegrationTestTracing.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/BraveTestSpanHandler.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/BraveTestSpanHandler.java index 38292b568..796631e74 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/BraveTestSpanHandler.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/BraveTestSpanHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/BraveTestTracing.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/BraveTestTracing.java index 16f8fcc9e..61658fa07 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/BraveTestTracing.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/BraveTestTracing.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/BraveTestTracingAssertions.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/BraveTestTracingAssertions.java index 0a3d3707e..a0c6aef2d 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/BraveTestTracingAssertions.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/BraveTestTracingAssertions.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveAccessor.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveAccessor.java index 5462222c6..806b4e456 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveAccessor.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/NullSpanTagAnnotationHandlerTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/NullSpanTagAnnotationHandlerTests.java index 7eb82595a..885546cf0 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/NullSpanTagAnnotationHandlerTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/NullSpanTagAnnotationHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectFluxTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectFluxTests.java index 880b9ee12..0ce103c14 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectFluxTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectFluxTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -25,6 +25,7 @@ import java.util.stream.Collectors; import org.assertj.core.api.BDDAssertions; import org.awaitility.Awaitility; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import reactor.core.publisher.Flux; @@ -84,9 +85,11 @@ public abstract class SleuthSpanCreatorAspectFluxTests { } @BeforeEach + @AfterEach public void setup() { this.spans.clear(); this.testBean.reset(); + this.tracer.withSpan(null); } @Test diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectMonoTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectMonoTests.java index 5eb357b10..315a0227f 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectMonoTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectMonoTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -69,6 +69,7 @@ public abstract class SleuthSpanCreatorAspectMonoTests { @BeforeEach public void setup() { this.spans.clear(); + this.tracer.withSpan(null); } @Test diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectNegativeTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectNegativeTests.java index 197dfa947..142708efc 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectNegativeTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectNegativeTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectTests.java index 39c24949a..f746c968e 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -50,6 +50,7 @@ public abstract class SleuthSpanCreatorAspectTests { @BeforeEach public void setup() { this.spans.clear(); + this.tracer.withSpan(null); } @Test diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorCircularDependencyTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorCircularDependencyTests.java index 12555ded1..c0b082fc4 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorCircularDependencyTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorCircularDependencyTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SpanTagAnnotationHandlerTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SpanTagAnnotationHandlerTests.java index 7286c1e19..de9f171b2 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SpanTagAnnotationHandlerTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SpanTagAnnotationHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncDisabledTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncDisabledTests.java index 720a56320..93ebd994a 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncDisabledTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncDisabledTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskSchedulerTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskSchedulerTests.java index bd4a0e8a0..3aa01c258 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskSchedulerTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskSchedulerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -343,7 +343,7 @@ public abstract class LazyTraceThreadPoolTaskSchedulerTests implements TestTraci }; this.executor.newThread(runnable); - BDDMockito.then(this.delegate).should().newThread(runnable); + BDDMockito.then(this.delegate).should().newThread(BDDMockito.isA(TraceRunnable.class)); } @Test @@ -409,7 +409,7 @@ public abstract class LazyTraceThreadPoolTaskSchedulerTests implements TestTraci }; this.executor.createThread(r); - BDDMockito.then(this.delegate).should().createThread(r); + BDDMockito.then(this.delegate).should().createThread(BDDMockito.isA(TraceRunnable.class)); } @Test diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspectTest.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspectTest.java index a752802eb..7bb80e733 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspectTest.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspectTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncListenableTaskExecutorTest.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncListenableTaskExecutorTest.java index 4cfdff322..b1b8c8525 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncListenableTaskExecutorTest.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncListenableTaskExecutorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceCallableTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceCallableTests.java index 346f10536..f9546cd9b 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceCallableTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceCallableTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnableTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnableTests.java index 826fbf0fd..d5134ce49 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnableTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnableTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceScheduledThreadPoolExecutorAnotherConstructorTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceScheduledThreadPoolExecutorAnotherConstructorTests.java new file mode 100644 index 000000000..bd659a8f9 --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceScheduledThreadPoolExecutorAnotherConstructorTests.java @@ -0,0 +1,44 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.async; + +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * @author Marcin Grzejszczak + */ +public abstract class TraceScheduledThreadPoolExecutorAnotherConstructorTests + extends TraceScheduledThreadPoolExecutorTests { + + @Override + protected LazyTraceScheduledThreadPoolExecutor executor() { + return new LazyTraceScheduledThreadPoolExecutor(1, new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r); + } + }, new RejectedExecutionHandler() { + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + + } + }, beanFactory, delegate, "foo"); + } + +} diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceScheduledThreadPoolExecutorTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceScheduledThreadPoolExecutorTests.java new file mode 100644 index 000000000..989ed5a90 --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceScheduledThreadPoolExecutorTests.java @@ -0,0 +1,355 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.async; + +import java.util.concurrent.Callable; +import java.util.concurrent.Delayed; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RunnableScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.awaitility.Awaitility; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.BDDMockito; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanNamer; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.internal.DefaultSpanNamer; +import org.springframework.cloud.sleuth.internal.SleuthContextListenerAccessor; +import org.springframework.cloud.sleuth.test.TestTracingAwareSupplier; + +import static org.assertj.core.api.BDDAssertions.then; + +/** + * @author Marcin Grzejszczak + */ +public abstract class TraceScheduledThreadPoolExecutorTests implements TestTracingAwareSupplier { + + ScheduledThreadPoolExecutor delegate = new ScheduledThreadPoolExecutor(1); + + BeanFactory beanFactory = beanFactory(); + + LazyTraceScheduledThreadPoolExecutor traceThreadPoolTaskExecutor = executor(); + + protected LazyTraceScheduledThreadPoolExecutor executor() { + return new LazyTraceScheduledThreadPoolExecutor(1, this.beanFactory, this.delegate, "foo"); + } + + @BeforeEach + void setup() { + SleuthContextListenerAccessor.set(this.beanFactory, true); + } + + @AfterEach + void clear() { + this.delegate.shutdown(); + } + + private BeanFactory beanFactory() { + BeanFactory beanFactory = BDDMockito.mock(BeanFactory.class); + BDDMockito.given(beanFactory.getBean(Tracer.class)).willReturn(tracerTest().tracing().tracer()); + BDDMockito.given(beanFactory.getBean(SpanNamer.class)).willReturn(new DefaultSpanNamer()); + return beanFactory; + } + + @Test + public void should_schedule_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.schedule(aRunnable(executed, span), 1, TimeUnit.MILLISECONDS).get(1, + TimeUnit.SECONDS); + } + finally { + span.end(); + } + + then(executed.get()).isTrue(); + } + + @Test + public void should_decorate_task_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + Runnable runnable = aRunnable(executed, span); + this.traceThreadPoolTaskExecutor.decorateTask(runnable, runnableScheduledFuture(runnable)).run(); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_decorate_task_trace_callable() throws Exception { + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + RunnableScheduledFuture fromCallable; + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + Callable callable = aCallable(span); + fromCallable = this.traceThreadPoolTaskExecutor.decorateTask(callable, runnableScheduledFuture(callable)); + fromCallable.run(); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(fromCallable.get(10, TimeUnit.MILLISECONDS)).isNotNull(); + }); + } + + private RunnableScheduledFuture runnableScheduledFuture(Callable run) { + return new RunnableScheduledFuture() { + + private Span result; + + @Override + public boolean isPeriodic() { + return false; + } + + @Override + public long getDelay(TimeUnit unit) { + return 0; + } + + @Override + public int compareTo(Delayed o) { + return 0; + } + + @Override + public void run() { + try { + this.result = run.call(); + } + catch (Exception exception) { + } + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public boolean isDone() { + return false; + } + + @Override + public Span get() throws InterruptedException, ExecutionException { + return this.result; + } + + @Override + public Span get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + return this.result; + } + }; + } + + private RunnableScheduledFuture runnableScheduledFuture(Runnable run) { + return new RunnableScheduledFuture() { + + @Override + public boolean isPeriodic() { + return false; + } + + @Override + public long getDelay(TimeUnit unit) { + return 0; + } + + @Override + public int compareTo(Delayed o) { + return 0; + } + + @Override + public void run() { + run.run(); + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public boolean isDone() { + return false; + } + + @Override + public Object get() throws InterruptedException, ExecutionException { + return null; + } + + @Override + public Object get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + return null; + } + }; + } + + @Test + public void should_schedule_trace_callable() throws Exception { + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + Span spanFromCallable; + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + spanFromCallable = this.traceThreadPoolTaskExecutor.schedule(aCallable(span), 1, TimeUnit.MILLISECONDS) + .get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + then(spanFromCallable).isNotNull(); + } + + @Test + public void should_schedule_at_fixed_rate_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleAtFixedRate(aRunnable(executed, span), 1L, 1L, + TimeUnit.MILLISECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_with_fixed_delay_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleWithFixedDelay(aRunnable(executed, span), 1L, 1L, + TimeUnit.MILLISECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_execute_a_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.execute(aRunnable(executed, span)); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_trace_callable() throws Exception { + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + Span spanFromListenable; + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + spanFromListenable = this.traceThreadPoolTaskExecutor.submit(aCallable(span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + then(spanFromListenable).isNotNull(); + } + + @Test + public void should_submit_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.submit(aRunnable(executed, span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + Runnable aRunnable(AtomicBoolean executed, Span currentSpan) { + return () -> { + Span span = tracerTest().tracing().tracer().currentSpan(); + then(span).isNotNull(); + then(span.context().traceId()).isEqualTo(currentSpan.context().traceId()); + executed.set(true); + }; + } + + Callable aCallable(Span currentSpan) { + return () -> { + Span span = tracerTest().tracing().tracer().currentSpan(); + then(span.context().traceId()).isEqualTo(currentSpan.context().traceId()); + return span; + }; + } + +} diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceThreadPoolTaskExecutorTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceThreadPoolTaskExecutorTests.java new file mode 100644 index 000000000..45539d12b --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceThreadPoolTaskExecutorTests.java @@ -0,0 +1,234 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.async; + +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.assertj.core.api.BDDAssertions; +import org.awaitility.Awaitility; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.BDDMockito; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanNamer; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.internal.DefaultSpanNamer; +import org.springframework.cloud.sleuth.internal.SleuthContextListenerAccessor; +import org.springframework.cloud.sleuth.test.TestTracingAwareSupplier; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +/** + * @author Marcin Grzejszczak + */ +public abstract class TraceThreadPoolTaskExecutorTests implements TestTracingAwareSupplier { + + ThreadPoolTaskExecutor delegate = new ThreadPoolTaskExecutor(); + + BeanFactory beanFactory = beanFactory(); + + LazyTraceThreadPoolTaskExecutor traceThreadPoolTaskExecutor = new LazyTraceThreadPoolTaskExecutor(this.beanFactory, + this.delegate); + + @BeforeEach + void setup() { + this.delegate.initialize(); + SleuthContextListenerAccessor.set(this.beanFactory, true); + } + + @AfterEach + void clear() { + this.delegate.shutdown(); + } + + private BeanFactory beanFactory() { + BeanFactory beanFactory = BDDMockito.mock(BeanFactory.class); + BDDMockito.given(beanFactory.getBean(Tracer.class)).willReturn(tracerTest().tracing().tracer()); + BDDMockito.given(beanFactory.getBean(SpanNamer.class)).willReturn(new DefaultSpanNamer()); + return beanFactory; + } + + @Test + public void should_create_thread_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.createThread(aRunnable(executed, span)).start(); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + BDDAssertions.then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_listenable_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.submitListenable(aRunnable(executed, span)).get(); + } + finally { + span.end(); + } + + BDDAssertions.then(executed.get()).isTrue(); + } + + @Test + public void should_submit_listenable_trace_callable() throws Exception { + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + Span spanFromListenable; + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + spanFromListenable = this.traceThreadPoolTaskExecutor.submitListenable(aCallable(span)).get(1, + TimeUnit.SECONDS); + } + finally { + span.end(); + } + + BDDAssertions.then(spanFromListenable).isNotNull(); + } + + @Test + public void should_execute_a_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.execute(aRunnable(executed, span)); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + BDDAssertions.then(executed.get()).isTrue(); + }); + } + + @Test + public void should_execute_with_timeout_a_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.execute(aRunnable(executed, span), 1L); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + BDDAssertions.then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_trace_callable() throws Exception { + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + Span spanFromListenable; + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + spanFromListenable = this.traceThreadPoolTaskExecutor.submit(aCallable(span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + BDDAssertions.then(spanFromListenable).isNotNull(); + } + + @Test + public void should_submit_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.submit(aRunnable(executed, span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + BDDAssertions.then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_trace_runnable_via_new_thread() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.newThread(aRunnable(executed, span)).start(); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + BDDAssertions.then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_trace_runnable_via_create_thread() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.createThread(aRunnable(executed, span)).start(); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + BDDAssertions.then(executed.get()).isTrue(); + }); + } + + Runnable aRunnable(AtomicBoolean executed, Span currentSpan) { + return () -> { + Span span = tracerTest().tracing().tracer().currentSpan(); + BDDAssertions.then(span).isNotNull(); + BDDAssertions.then(span.context().traceId()).isEqualTo(currentSpan.context().traceId()); + executed.set(true); + }; + } + + Callable aCallable(Span currentSpan) { + return () -> { + Span span = tracerTest().tracing().tracer().currentSpan(); + BDDAssertions.then(span.context().traceId()).isEqualTo(currentSpan.context().traceId()); + return span; + }; + } + +} diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceThreadPoolTaskSchedulerTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceThreadPoolTaskSchedulerTests.java new file mode 100644 index 000000000..5c2716f76 --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceThreadPoolTaskSchedulerTests.java @@ -0,0 +1,527 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.async; + +import java.sql.Date; +import java.time.Duration; +import java.time.Instant; +import java.util.concurrent.Callable; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.awaitility.Awaitility; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.BDDMockito; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanNamer; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.internal.DefaultSpanNamer; +import org.springframework.cloud.sleuth.internal.SleuthContextListenerAccessor; +import org.springframework.cloud.sleuth.test.TestTracingAwareSupplier; +import org.springframework.scheduling.Trigger; +import org.springframework.scheduling.TriggerContext; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; + +import static org.assertj.core.api.BDDAssertions.then; + +/** + * @author Marcin Grzejszczak + */ +public abstract class TraceThreadPoolTaskSchedulerTests implements TestTracingAwareSupplier { + + ThreadPoolTaskScheduler delegate = new ThreadPoolTaskScheduler(); + + BeanFactory beanFactory = beanFactory(); + + LazyTraceThreadPoolTaskScheduler traceThreadPoolTaskExecutor = new LazyTraceThreadPoolTaskScheduler( + this.beanFactory, this.delegate, "foo"); + + @BeforeEach + void setup() { + this.delegate.initialize(); + SleuthContextListenerAccessor.set(this.beanFactory, true); + } + + @AfterEach + void clear() { + this.delegate.shutdown(); + } + + private BeanFactory beanFactory() { + BeanFactory beanFactory = BDDMockito.mock(BeanFactory.class); + BDDMockito.given(beanFactory.getBean(Tracer.class)).willReturn(tracerTest().tracing().tracer()); + BDDMockito.given(beanFactory.getBean(SpanNamer.class)).willReturn(new DefaultSpanNamer()); + return beanFactory; + } + + @Test + public void should_initialize_wrapped_executor() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.initializeExecutor(new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r); + } + }, new RejectedExecutionHandler() { + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + + } + }).submit(aRunnable(executed, span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_create_wrapped_executor() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.createExecutor(1, new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r); + } + }, new RejectedExecutionHandler() { + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + + } + }).submit(aRunnable(executed, span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_get_scheduled_wrapped_executor() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.getScheduledExecutor().submit(aRunnable(executed, span)).get(1, + TimeUnit.SECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_get_scheduled_thread_pool_wrapped_executor() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.getScheduledThreadPoolExecutor().submit(aRunnable(executed, span)).get(1, + TimeUnit.SECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_create_thread_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.createThread(aRunnable(executed, span)).start(); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.schedule(aRunnable(executed, span), Instant.now()).get(1, + TimeUnit.SECONDS); + } + finally { + span.end(); + } + + then(executed.get()).isTrue(); + } + + @Test + public void should_schedule_trace_runnable_with_start_time() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.schedule(aRunnable(executed, span), Date.from(Instant.now())).get(1, + TimeUnit.SECONDS); + } + finally { + span.end(); + } + + then(executed.get()).isTrue(); + } + + @Test + public void should_schedule_trace_runnable_with_trigger() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.schedule(aRunnable(executed, span), new Trigger() { + @Override + public java.util.Date nextExecutionTime(TriggerContext triggerContext) { + return java.util.Date.from(Instant.now()); + } + }).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + then(executed.get()).isTrue(); + } + + @Test + public void should_schedule_at_fixed_rate_trace_runnable_with_date() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleAtFixedRate(aRunnable(executed, span), Date.from(Instant.now()), + 1L); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_at_fixed_rate_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleAtFixedRate(aRunnable(executed, span), 1L); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_at_fixed_rate_trace_runnable_with_instant() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleAtFixedRate(aRunnable(executed, span), Instant.now(), + Duration.ofMillis(10)); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_at_fixed_rate_trace_runnable_with_duration() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleAtFixedRate(aRunnable(executed, span), Duration.ofMillis(10)); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_with_fixed_delay_trace_runnable_with_date() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleWithFixedDelay(aRunnable(executed, span), Date.from(Instant.now()), + 1L); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_with_fixed_delay_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleWithFixedDelay(aRunnable(executed, span), 1L); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_with_fixed_delay_trace_runnable_with_instant() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleWithFixedDelay(aRunnable(executed, span), Instant.now(), + Duration.ofMillis(10)); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_with_fixed_delay_trace_runnable_with_duration() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleWithFixedDelay(aRunnable(executed, span), Duration.ofMillis(10)); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_listenable_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.submitListenable(aRunnable(executed, span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_listenable_trace_callable() throws Exception { + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + Span spanFromListenable; + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + spanFromListenable = this.traceThreadPoolTaskExecutor.submitListenable(aCallable(span)).get(1, + TimeUnit.SECONDS); + } + finally { + span.end(); + } + + then(spanFromListenable).isNotNull(); + } + + @Test + public void should_execute_a_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.execute(aRunnable(executed, span)); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_execute_with_timeout_a_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.execute(aRunnable(executed, span), 1L); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_trace_callable() throws Exception { + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + Span spanFromListenable; + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + spanFromListenable = this.traceThreadPoolTaskExecutor.submit(aCallable(span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + then(spanFromListenable).isNotNull(); + } + + @Test + public void should_submit_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.submit(aRunnable(executed, span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_trace_runnable_via_new_thread() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.newThread(aRunnable(executed, span)).start(); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_trace_runnable_via_create_thread() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.createThread(aRunnable(executed, span)).start(); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + Runnable aRunnable(AtomicBoolean executed, Span currentSpan) { + return () -> { + Span span = tracerTest().tracing().tracer().currentSpan(); + then(span).isNotNull(); + then(span.context().traceId()).isEqualTo(currentSpan.context().traceId()); + executed.set(true); + }; + } + + Callable aCallable(Span currentSpan) { + return () -> { + Span span = tracerTest().tracing().tracer().currentSpan(); + then(span.context().traceId()).isEqualTo(currentSpan.context().traceId()); + return span; + }; + } + +} diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java index 88433a412..5327e6cce 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableScheduledExecutorServiceTest.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableScheduledExecutorServiceTest.java index fc337c663..7d975bcf7 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableScheduledExecutorServiceTest.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableScheduledExecutorServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerIntegrationTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerIntegrationTests.java index af2d4baa5..a6cb0eea7 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerIntegrationTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerTests.java index b60cd516d..412489331 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/ReactiveCircuitBreakerIntegrationTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/ReactiveCircuitBreakerIntegrationTests.java new file mode 100644 index 000000000..3ee120771 --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/ReactiveCircuitBreakerIntegrationTests.java @@ -0,0 +1,146 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.circuitbreaker; + +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.cloud.circuitbreaker.resilience4j.ReactiveResilience4JCircuitBreakerFactory; +import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory; +import org.springframework.cloud.sleuth.ScopedSpan; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.exporter.FinishedSpan; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +@ContextConfiguration(classes = ReactiveCircuitBreakerIntegrationTests.TestConfig.class) +public abstract class ReactiveCircuitBreakerIntegrationTests { + + @Autowired + TestSpanHandler spans; + + @Autowired + Tracer tracer; + + @Autowired + ReactiveCircuitBreakerFactory factory; + + @Autowired + CircuitService circuitService; + + @BeforeEach + public void setup() { + this.spans.clear(); + } + + @Test + public void should_pass_tracing_information_when_using_circuit_breaker() { + // given + Tracer tracer = this.tracer; + ScopedSpan scopedSpan = null; + try { + scopedSpan = tracer.startScopedSpan("start"); + // when + Span span = this.factory.create("name").run(Mono.defer(() -> Mono.just(tracer.currentSpan()))).block(); + + BDDAssertions.then(span).isNotNull(); + BDDAssertions.then(scopedSpan.context().traceId()).isEqualTo(span.context().traceId()); + } + finally { + scopedSpan.end(); + } + } + + @Test + public void should_pass_tracing_information_when_using_circuit_breaker_with_fallback() { + // when + BDDAssertions.then(this.circuitService.call().block()).isEqualTo("fallback"); + + BDDAssertions.then(this.spans).hasSize(2); + String traceId = this.circuitService.firstSpan.context().traceId(); + BDDAssertions.then(this.circuitService.secondSpan.context().traceId()).isEqualTo(traceId); + + FinishedSpan finishedSpan = this.spans.get(0); + BDDAssertions.then(finishedSpan.getName()).contains("CircuitBreakerIntegrationTests"); + + finishedSpan = this.spans.get(1); + BDDAssertions.then(finishedSpan.getName()).contains("function"); + } + + public void assertException(FinishedSpan finishedSpan) { + throw new UnsupportedOperationException("Implement this assertion"); + } + + @Configuration(proxyBeanMethods = false) + @EnableAutoConfiguration + public static class TestConfig { + + @Bean + ReactiveResilience4JCircuitBreakerFactory reactiveResilience4JCircuitBreakerFactory() { + return new ReactiveResilience4JCircuitBreakerFactory(); + } + + @Bean + CircuitService circuitService(ReactiveCircuitBreakerFactory reactiveCircuitBreakerFactory, Tracer tracer) { + return new CircuitService(reactiveCircuitBreakerFactory, tracer); + } + + } + + static class CircuitService { + + private static final Logger log = LoggerFactory.getLogger(CircuitService.class); + + private final ReactiveCircuitBreakerFactory factory; + + private final Tracer tracer; + + Span firstSpan; + + Span secondSpan; + + CircuitService(ReactiveCircuitBreakerFactory factory, Tracer tracer) { + this.factory = factory; + this.tracer = tracer; + } + + Mono call() { + return this.factory.create("circuit").run(Mono.defer(() -> { + this.firstSpan = this.tracer.currentSpan(); + log.info(" Hello from consumer", + this.tracer.currentSpan().context().traceId()); + return Mono.error(new IllegalStateException("boom")); + }), throwable -> { + this.secondSpan = this.tracer.currentSpan(); + log.info(" Hello from producer", + this.tracer.currentSpan().context().traceId()); + return Mono.just("fallback"); + }); + } + + } + +} diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/ReactiveCircuitBreakerTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/ReactiveCircuitBreakerTests.java new file mode 100644 index 000000000..021fbcd9e --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/ReactiveCircuitBreakerTests.java @@ -0,0 +1,94 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.circuitbreaker; + +import java.util.concurrent.atomic.AtomicReference; + +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; + +import org.springframework.cloud.circuitbreaker.resilience4j.ReactiveResilience4JCircuitBreakerFactory; +import org.springframework.cloud.sleuth.ScopedSpan; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.exporter.FinishedSpan; +import org.springframework.cloud.sleuth.test.TestTracingAwareSupplier; + +public abstract class ReactiveCircuitBreakerTests implements TestTracingAwareSupplier { + + @Test + public void should_pass_tracing_information_when_using_circuit_breaker() { + // given + Tracer tracer = tracerTest().tracing().tracer(); + ScopedSpan scopedSpan = null; + try { + scopedSpan = tracer.startScopedSpan("start"); + // when + Span span = new TraceReactiveCircuitBreaker(new ReactiveResilience4JCircuitBreakerFactory().create("name"), + tracer, tracerTest().tracing().currentTraceContext()) + .run(Mono.defer(() -> Mono.just(tracer.currentSpan()))).block(); + + BDDAssertions.then(span).isNotNull(); + BDDAssertions.then(scopedSpan.context().traceId()).isEqualTo(span.context().traceId()); + } + finally { + scopedSpan.end(); + } + } + + @Test + public void should_pass_tracing_information_when_using_circuit_breaker_with_fallback() { + // given + Tracer tracer = tracerTest().tracing().tracer(); + AtomicReference first = new AtomicReference<>(); + AtomicReference second = new AtomicReference<>(); + ScopedSpan scopedSpan = null; + try { + scopedSpan = tracer.startScopedSpan("start"); + // when + BDDAssertions.thenThrownBy(() -> new TraceReactiveCircuitBreaker( + new ReactiveResilience4JCircuitBreakerFactory().create("name"), tracer, + tracerTest().tracing().currentTraceContext()).run(Mono.defer(() -> { + first.set(tracer.currentSpan()); + throw new IllegalStateException("boom"); + }), throwable -> { + second.set(tracer.currentSpan()); + throw new IllegalStateException("boom2"); + }).block()).isInstanceOf(IllegalStateException.class).hasMessageContaining("boom2"); + + BDDAssertions.then(tracerTest().handler().reportedSpans()).hasSize(2); + BDDAssertions.then(first.get()).isNotNull(); + BDDAssertions.then(second.get()).isNotNull(); + BDDAssertions.then(scopedSpan.context().traceId()).isEqualTo(first.get().context().traceId()); + BDDAssertions.then(scopedSpan.context().traceId()).isEqualTo(second.get().context().traceId()); + BDDAssertions.then(first.get().context().spanId()).isNotEqualTo(second.get().context().spanId()); + + FinishedSpan finishedSpan = tracerTest().handler().reportedSpans().get(1); + BDDAssertions.then(finishedSpan.getName()).contains("function"); + additionalAssertions(finishedSpan); + } + finally { + scopedSpan.end(); + } + } + + public void additionalAssertions(FinishedSpan finishedSpan) { + throw new UnsupportedOperationException("Assert errors"); + } + +} diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/config/ConfigServerIntegrationTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/config/ConfigServerIntegrationTests.java new file mode 100644 index 000000000..8a954219e --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/config/ConfigServerIntegrationTests.java @@ -0,0 +1,98 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.config; + +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.cloud.config.server.EnableConfigServer; +import org.springframework.cloud.sleuth.exporter.FinishedSpan; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.web.client.RestTemplate; + +import static org.assertj.core.api.BDDAssertions.then; +import static org.awaitility.Awaitility.await; + +@ContextConfiguration(classes = ConfigServerIntegrationTests.TestConfig.class) +@TestPropertySource(properties = { "server.port=0", + "spring.cloud.config.server.git.uri=https://github.com/spring-cloud-samples/config-repo" }) +public abstract class ConfigServerIntegrationTests { + + @Autowired + TestSpanHandler spans; + + @Autowired + WebClientService webClientService; + + @LocalServerPort + int port; + + @BeforeEach + public void setup() { + this.spans.clear(); + } + + @Test + public void should_instrument_config_server() { + this.webClientService.call(port); + + await().atMost(30, TimeUnit.SECONDS).untilAsserted(() -> { + then(this.spans.reportedSpans()).as("1 for mvc, 1 for composite env repo and 1 for git env repo") + .hasSize(3); + then(this.spans.reportedSpans().stream().map(FinishedSpan::getTraceId).collect(Collectors.toSet())) + .as("There must be 1 trace id").hasSize(1); + }); + } + + @Configuration(proxyBeanMethods = false) + @EnableAutoConfiguration + @EnableConfigServer + public static class TestConfig { + + @Bean + WebClientService webClientService() { + return new WebClientService(); + } + + } + + public static class WebClientService { + + private static final Logger log = LoggerFactory.getLogger(WebClientService.class); + + void call(int port) { + log.info("Sending request"); + String result = new RestTemplate().getForObject("http://localhost:" + port + "/foo/default/main", + String.class); + log.info("Got [\n" + result + "\n]"); + } + + } + +} diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaProducerTest.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaProducerTest.java new file mode 100644 index 000000000..c541eac73 --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaProducerTest.java @@ -0,0 +1,98 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.kafka; + +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.kafka.clients.producer.Callback; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.common.serialization.StringSerializer; +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.testcontainers.containers.KafkaContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.propagation.Propagator; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.cloud.sleuth.test.TestTracingAwareSupplier; + +import static org.awaitility.Awaitility.await; + +@Testcontainers +public abstract class KafkaProducerTest implements TestTracingAwareSupplier { + + protected Tracer tracer = tracerTest().tracing().tracer(); + + protected Propagator propagator = tracerTest().tracing().propagator(); + + protected TestSpanHandler spans = tracerTest().handler(); + + protected TracingKafkaProducer kafkaProducer; + + @Container + protected final KafkaContainer kafkaContainer = new KafkaContainer( + DockerImageName.parse("confluentinc/cp-kafka:5.2.1")).withExposedPorts(9093) + .waitingFor(Wait.forListeningPort()); + + @BeforeEach + void setup() { + kafkaContainer.start(); + Map properties = new HashMap<>(); + properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaContainer.getBootstrapServers()); + properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + kafkaProducer = new TracingKafkaProducer<>(new KafkaProducer<>(properties), tracer, propagator, + new TracingKafkaPropagatorSetter()); + } + + @AfterEach + void destroy() { + kafkaContainer.stop(); + } + + @Test + public void should_create_and_finish_producer_span() { + AtomicBoolean acknowledged = new AtomicBoolean(false); + Callback callback = (metadata, ex) -> acknowledged.set(true); + ProducerRecord producerRecord = new ProducerRecord<>("spring-cloud-sleuth-otel-topic", "test", + "test"); + this.kafkaProducer.send(producerRecord, callback); + await().atMost(Duration.ofSeconds(5)).until(acknowledged::get); + + BDDAssertions.then(this.tracer.currentSpan()).isNull(); + BDDAssertions.then(this.spans).isNotEmpty(); + BDDAssertions.then(this.spans.get(0).getKind()).isEqualTo(Span.Kind.PRODUCER); + } + + @Override + public void cleanUpTracing() { + this.spans.clear(); + } + +} diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceWebSocketAutoConfigurationTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceWebSocketAutoConfigurationTests.java index ad9d2853c..49e262cb0 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceWebSocketAutoConfigurationTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceWebSocketAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java index 73015437e..f36f7c5d8 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -45,8 +45,10 @@ import org.springframework.messaging.support.ErrorMessage; import org.springframework.messaging.support.ExecutorChannelInterceptor; import org.springframework.messaging.support.ExecutorSubscribableChannel; import org.springframework.messaging.support.MessageBuilder; +import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.StringUtils; +import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.messaging.support.NativeMessageHeaderAccessor.NATIVE_HEADERS; @@ -348,6 +350,45 @@ public abstract class TracingChannelInterceptorTest implements TestTracingAwareS assertThat(this.spans).extracting(FinishedSpan::getRemoteServiceName).containsOnly("broker", null); } + @Test + public void should_propagate_headers_case_insensitive() { + channel.addInterceptor(this.interceptor); + Map headers = new HashMap<>(); + headers.put("Foo-Id", "123"); + headers.put("baz-id", "456"); + + channel.send(MessageBuilder.createMessage("foo", new MessageHeaders(headers))); + + Message actualMessage = channel.receive(); + + assertThat(actualMessage.getHeaders()).isNotEmpty(); + assertThat(actualMessage.getHeaders().get("not-propagated-header")).isNull(); + assertThat(actualMessage.getHeaders().get("Foo-Id")).isEqualTo("123"); + assertThat(actualMessage.getHeaders().get("baz-id")).isEqualTo("456"); + } + + @Test + public void should_propagate_native_headers_case_insensitive() { + channel.addInterceptor(this.interceptor); + LinkedMultiValueMap nativeHeaders = new LinkedMultiValueMap<>(); + nativeHeaders.put("Foo-Id", singletonList("123")); + nativeHeaders.put("baz-id", singletonList("456")); + Map headers = new HashMap<>(); + headers.put(NATIVE_HEADERS, nativeHeaders); + + channel.send(MessageBuilder.createMessage("foo", new MessageHeaders(headers))); + + Message actualMessage = channel.receive(); + + assertThat(actualMessage.getHeaders()).isNotEmpty(); + LinkedMultiValueMap actualNativeHeaders = (LinkedMultiValueMap) actualMessage.getHeaders() + .get(NATIVE_HEADERS); + assertThat(actualNativeHeaders).isNotEmpty(); + assertThat(actualNativeHeaders.get("not-propagated-header")).isNull(); + assertThat(actualNativeHeaders.get("Foo-Id")).isEqualTo(singletonList("123")); + assertThat(actualNativeHeaders.get("baz-id")).isEqualTo(singletonList("456")); + } + public ChannelInterceptor producerSideOnly(ChannelInterceptor delegate) { return new ChannelInterceptorAdapter() { @Override @@ -424,26 +465,26 @@ class B3Context { } -// @formatter:off -// tag::message_span_customizer[] -class MyMessageSpanCustomizer extends DefaultMessageSpanCustomizer { - @Override - public Span customizeHandle(Span spanCustomizer, - Message message, MessageChannel messageChannel) { - return super.customizeHandle(spanCustomizer, message, messageChannel) - .name("changedHandle") - .tag("handleKey", "handleValue") - .tag("channelName", channelName(messageChannel)); - } - - @Override - public Span.Builder customizeSend(Span.Builder builder, - Message message, MessageChannel messageChannel) { - return super.customizeSend(builder, message, messageChannel) - .name("changedSend") - .tag("sendKey", "sendValue") - .tag("channelName", channelName(messageChannel)); - } -} -// end::message_span_customizer[] +// @formatter:off +// tag::message_span_customizer[] +class MyMessageSpanCustomizer extends DefaultMessageSpanCustomizer { + @Override + public Span customizeHandle(Span spanCustomizer, + Message message, MessageChannel messageChannel) { + return super.customizeHandle(spanCustomizer, message, messageChannel) + .name("changedHandle") + .tag("handleKey", "handleValue") + .tag("channelName", channelName(messageChannel)); + } + + @Override + public Span.Builder customizeSend(Span.Builder builder, + Message message, MessageChannel messageChannel) { + return super.customizeSend(builder, message, messageChannel) + .name("changedSend") + .tag("sendKey", "sendValue") + .tag("channelName", channelName(messageChannel)); + } +} +// end::message_span_customizer[] // @formatter:on diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListenerTest.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListenerTest.java index 164f93dd0..faf1f7102 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListenerTest.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListenerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/FlowsScopePassingSpanSubscriberTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/FlowsScopePassingSpanSubscriberTests.java index ecca4b380..57d2b2cbe 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/FlowsScopePassingSpanSubscriberTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/FlowsScopePassingSpanSubscriberTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberSpringBootTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberSpringBootTests.java index cf2d14c22..cecbebef3 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberSpringBootTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberSpringBootTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -22,6 +22,7 @@ import java.util.concurrent.atomic.AtomicReference; import org.awaitility.Awaitility; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; @@ -165,6 +166,7 @@ public abstract class ScopePassingSpanSubscriberSpringBootTests { } @Test + @Disabled("Will work only for on each - by accident") public void should_pass_tracing_info_when_using_reactor_async_processor() { final AtomicReference spanInOperation = new AtomicReference<>(); diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberTests.java index 7df4424ec..b2227096d 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/sample/FlatMapTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/sample/FlatMapTests.java index 71c827f52..8288389e5 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/sample/FlatMapTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/sample/FlatMapTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -77,13 +77,14 @@ public abstract class FlatMapTests { } @Test - public void should_work_with_flat_maps(CapturedOutput capture) { + public void should_work_with_flat_maps_with_on_queues_instrumentation(CapturedOutput capture) { // given ConfigurableApplicationContext context = new SpringApplicationBuilder(FlatMapTests.TestConfiguration.class, testConfiguration(), Issue866Configuration.class) .web(WebApplicationType.REACTIVE) .properties("server.port=0", "spring.jmx.enabled=false", - "spring.application.name=TraceWebFluxTests", "security.basic.enabled=false", + "spring.sleuth.reactor.instrumentation-type=DECORATE_QUEUES", + "spring.application.name=TraceWebFluxOnQueuesTests", "security.basic.enabled=false", "management.security.enabled=false") .run(); assertReactorTracing(context, capture, () -> context.getBean(TestConfiguration.class).spanInFoo); @@ -98,8 +99,22 @@ public abstract class FlatMapTests { testConfiguration(), Issue866Configuration.class) .web(WebApplicationType.REACTIVE) .properties("server.port=0", "spring.jmx.enabled=false", - "spring.sleuth.reactor.decorate-on-each=false", - "spring.application.name=TraceWebFlux2Tests", "security.basic.enabled=false", + "spring.sleuth.reactor.instrumentation-type=DECORATE_ON_LAST", + "spring.application.name=TraceWebFluxOnLastTests", "security.basic.enabled=false", + "management.security.enabled=false") + .run(); + assertReactorTracing(context, capture, () -> context.getBean(TestConfiguration.class).spanInFoo); + } + + @Test + public void should_work_with_flat_maps_with_on_each_operator_instrumentation(CapturedOutput capture) { + // given + ConfigurableApplicationContext context = new SpringApplicationBuilder(FlatMapTests.TestConfiguration.class, + testConfiguration(), Issue866Configuration.class) + .web(WebApplicationType.REACTIVE) + .properties("server.port=0", "spring.jmx.enabled=false", + "spring.sleuth.reactor.instrumentation-type=DECORATE_ON_EACH", + "spring.application.name=TraceWebFluxOnEachTests", "security.basic.enabled=false", "management.security.enabled=false") .run(); assertReactorTracing(context, capture, () -> context.getBean(TestConfiguration.class).spanInFoo); @@ -113,7 +128,7 @@ public abstract class FlatMapTests { .web(WebApplicationType.REACTIVE) .properties("server.port=0", "spring.jmx.enabled=false", "spring.sleuth.reactor.instrumentation-type=MANUAL", - "spring.application.name=TraceWebFlux3Tests", "security.basic.enabled=false", + "spring.application.name=TraceWebFluxOnManualTests", "security.basic.enabled=false", "management.security.enabled=false") .run(); assertReactorTracing(context, capture, () -> context.getBean(TestManualConfiguration.class).spanInFoo); diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/sample/ManualRequestSender.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/sample/ManualRequestSender.java index 01f9d4120..c018c20e7 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/sample/ManualRequestSender.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/sample/ManualRequestSender.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/sample/RequestSender.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/sample/RequestSender.java index d3a486fed..be3e91197 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/sample/RequestSender.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/sample/RequestSender.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TraceRSocketTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TraceRSocketTests.java new file mode 100644 index 000000000..4b7a5180d --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TraceRSocketTests.java @@ -0,0 +1,368 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.rsocket; + +import java.net.URI; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; + +import io.rsocket.frame.FrameType; +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.util.context.ContextView; + +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.exporter.FinishedSpan; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.messaging.rsocket.RSocketRequester; +import org.springframework.messaging.rsocket.RSocketRequester.Builder; +import org.springframework.messaging.rsocket.RSocketStrategies; +import org.springframework.stereotype.Controller; +import org.springframework.util.MimeType; + +import static org.assertj.core.api.BDDAssertions.then; + +public abstract class TraceRSocketTests { + + public static final String EXPECTED_TRACE_ID = "b919095138aa4c6e"; + + @Test + public void should_instrument_responder() throws Exception { + // setup + ConfigurableApplicationContext context = new SpringApplicationBuilder(MyConfig.class, testConfiguration()) + .web(WebApplicationType.REACTIVE) + .properties("server.port=0", "spring.rsocket.server.transport=websocket", + "spring.rsocket.server.mapping-path=/rsocket", "spring.jmx.enabled=false", + "spring.application.name=TraceRSocketTests", "security.basic.enabled=false", + "management.security.enabled=false") + .run(); + final TestSpanHandler spans = context.getBean(TestSpanHandler.class); + final int port = context.getBean(Environment.class).getProperty("local.server.port", Integer.class); + final TestController controller2 = context.getBean(TestController.class); + final RSocketStrategies strategies = context.getBean(RSocketStrategies.class); + + final Builder rsocketRequesterBuilder = RSocketRequester.builder().rsocketStrategies(strategies); + + final RSocketRequester rSocketRequester = rsocketRequesterBuilder + .websocket(URI.create("ws://localhost:" + port + "/rsocket")); + + // REQUEST FNF + whenRequestFnFIsSent(rSocketRequester, "api.c2.fnf").block(); + + FrameType receivedFrame = controller2.getReceivedFrames().take(); + thenSpanWasReportedWithTags(spans, "api.c2.fnf", receivedFrame); + spans.clear(); + controller2.reset(); + + // REQUEST RESPONSE + whenRequestResponseIsSent(rSocketRequester, "api.c2.rr").block(); + + receivedFrame = controller2.getReceivedFrames().take(); + thenSpanWasReportedWithTags(spans, "api.c2.rr", receivedFrame); + spans.clear(); + controller2.reset(); + + // REQUEST STREAM + whenRequestStreamIsSent(rSocketRequester, "api.c2.rs").blockLast(); + + receivedFrame = controller2.getReceivedFrames().take(); + thenSpanWasReportedWithTags(spans, "api.c2.rs", receivedFrame); + spans.clear(); + controller2.reset(); + + // REQUEST CHANNEL + whenRequestChannelIsSent(rSocketRequester, "api.c2.rc").blockLast(); + + receivedFrame = controller2.getReceivedFrames().take(); + thenSpanWasReportedWithTags(spans, "api.c2.rc", receivedFrame); + spans.clear(); + controller2.reset(); + + // REQUEST FNF + whenNonSampledRequestFnfIsSent(rSocketRequester); + controller2.getReceivedFrames().take(); + // then + thenNoSpanWasReported(spans, controller2, EXPECTED_TRACE_ID); + spans.clear(); + controller2.reset(); + + // REQUEST RESPONSE + whenNonSampledRequestResponseIsSent(rSocketRequester); + controller2.getReceivedFrames().take(); + // then + thenNoSpanWasReported(spans, controller2, EXPECTED_TRACE_ID); + spans.clear(); + controller2.reset(); + + // REQUEST STREAM + whenNonSampledRequestStreamIsSent(rSocketRequester); + controller2.getReceivedFrames().take(); + // then + thenNoSpanWasReported(spans, controller2, EXPECTED_TRACE_ID); + spans.clear(); + controller2.reset(); + + // REQUEST CHANNEL + whenNonSampledRequestChannelIsSent(rSocketRequester); + controller2.getReceivedFrames().take(); + // then + thenNoSpanWasReported(spans, controller2, EXPECTED_TRACE_ID); + spans.clear(); + controller2.reset(); + + // cleanup + context.close(); + } + + @Test + public void should_instrument_requester_and_responder() throws Exception { + // setup + ConfigurableApplicationContext context = new SpringApplicationBuilder(MyConfig.class, testConfiguration()) + .web(WebApplicationType.REACTIVE) + .properties("server.port=0", "spring.rsocket.server.transport=websocket", + "spring.rsocket.server.mapping-path=/rsocket", "spring.jmx.enabled=false", + "spring.application.name=TraceRSocketTests", "security.basic.enabled=false", + "management.security.enabled=false") + .run(); + + final org.springframework.cloud.sleuth.Tracer tracer = context + .getBean(org.springframework.cloud.sleuth.Tracer.class); + final TestSpanHandler spans = context.getBean(TestSpanHandler.class); + final int port = context.getBean(Environment.class).getProperty("local.server.port", Integer.class); + final TestController controller2 = context.getBean(TestController.class); + + final Builder rsocketRequesterBuilder = context.getBean(Builder.class); + + final RSocketRequester rSocketRequester = rsocketRequesterBuilder + .websocket(URI.create("ws://localhost:" + port + "/rsocket")); + + // REQUEST FNF + final org.springframework.cloud.sleuth.Span nextSpanFnf = tracer.nextSpan().start(); + whenRequestFnFIsSent(rSocketRequester, "api.c2.fnf") + .contextWrite(ctx -> ctx.put(TraceContext.class, nextSpanFnf.context())) + .doFinally(signalType -> nextSpanFnf.end()).block(); + controller2.getReceivedFrames().take(); + thenNoSpanWasReported(spans, controller2, nextSpanFnf.context().traceId()); + spans.clear(); + controller2.reset(); + + // REQUEST RESPONSE + final org.springframework.cloud.sleuth.Span nextSpanRR = tracer.nextSpan().start(); + whenRequestResponseIsSent(rSocketRequester, "api.c2.rr") + .contextWrite(ctx -> ctx.put(TraceContext.class, nextSpanRR.context())) + .doFinally(signalType -> nextSpanRR.end()).block(); + + controller2.getReceivedFrames().take(); + thenNoSpanWasReported(spans, controller2, nextSpanRR.context().traceId()); + spans.clear(); + controller2.reset(); + + // REQUEST STREAM + final org.springframework.cloud.sleuth.Span nextSpanRS = tracer.nextSpan().start(); + whenRequestStreamIsSent(rSocketRequester, "api.c2.rs") + .contextWrite(ctx -> ctx.put(TraceContext.class, nextSpanRS.context())) + .doFinally(signalType -> nextSpanRS.end()).blockLast(); + + controller2.getReceivedFrames().take(); + thenNoSpanWasReported(spans, controller2, nextSpanRS.context().traceId()); + spans.clear(); + controller2.reset(); + + // REQUEST CHANNEL + final org.springframework.cloud.sleuth.Span nextSpanRC = tracer.nextSpan().start(); + whenRequestChannelIsSent(rSocketRequester, "api.c2.rc") + .contextWrite(ctx -> ctx.put(TraceContext.class, nextSpanRC.context())) + .doFinally(signalType -> nextSpanRC.end()).blockLast(); + + controller2.getReceivedFrames().take(); + thenNoSpanWasReported(spans, controller2, nextSpanRC.context().traceId()); + spans.clear(); + controller2.reset(); + + // cleanup + context.close(); + } + + protected abstract Class testConfiguration(); + + private void thenSpanWasReportedWithTags(TestSpanHandler spans, String path, FrameType frameType) { + then(spans).hasSize(1); + // TODO: Preferred option would be : [api.c2.{name}] + FinishedSpan span = spans.get(0); + then(span.getName()).isEqualTo(frameType.name() + " " + path); + then(span.getTags()).containsEntry("messaging.controller.class", + "org.springframework.cloud.sleuth.instrument.rsocket.TraceRSocketTests$TestController"); + then(span.getTags()).containsKey("messaging.controller.method"); + } + + private Mono whenRequestFnFIsSent(RSocketRequester requester, String path) { + return requester.route(path).send(); + } + + private Mono whenRequestResponseIsSent(RSocketRequester requester, String path) { + return requester.route(path).retrieveMono(String.class); + } + + private Flux whenRequestStreamIsSent(RSocketRequester requester, String path) { + return requester.route(path).retrieveFlux(String.class); + } + + private Flux whenRequestChannelIsSent(RSocketRequester requester, String path) { + return requester.route(path).data(Flux.fromArray(new String[] { "test1", "test2" })).retrieveFlux(String.class); + } + + private void whenNonSampledRequestFnfIsSent(RSocketRequester requester) { + requester.route("api.c2.fnf").metadata(EXPECTED_TRACE_ID + "-" + EXPECTED_TRACE_ID + "-0", new MimeType("b3") { + @Override + public String toString() { + return "b3"; + } + }).send().block(); + } + + private void whenNonSampledRequestResponseIsSent(RSocketRequester requester) { + requester.route("api.c2.rr").metadata(EXPECTED_TRACE_ID + "-" + EXPECTED_TRACE_ID + "-0", new MimeType("b3") { + @Override + public String toString() { + return "b3"; + } + }).retrieveMono(String.class).block(); + } + + private void whenNonSampledRequestStreamIsSent(RSocketRequester requester) { + requester.route("api.c2.rs").metadata(EXPECTED_TRACE_ID + "-" + EXPECTED_TRACE_ID + "-0", new MimeType("b3") { + @Override + public String toString() { + return "b3"; + } + }).retrieveFlux(String.class).blockLast(); + } + + private void whenNonSampledRequestChannelIsSent(RSocketRequester requester) { + requester.route("api.c2.rc").metadata(EXPECTED_TRACE_ID + "-" + EXPECTED_TRACE_ID + "-0", new MimeType("b3") { + @Override + public String toString() { + return "b3"; + } + }).data(Flux.fromArray(new String[] { "test1", "test2" })).retrieveFlux(String.class).blockLast(); + } + + private void thenNoSpanWasReported(TestSpanHandler spans, TestController controller2, String expectedTraceId) { + // then(spans).isEmpty(); // FIXME: does not work for request case + then(controller2.getSpan()).isNotNull(); + then(controller2.getSpan().context().traceId()).isEqualTo(expectedTraceId); + } + + @Configuration(proxyBeanMethods = false) + @EnableAutoConfiguration + static class MyConfig { + + @Bean + TestController controller(Tracer tracer) { + return new TestController(tracer); + } + + } + + @Controller + @MessageMapping("api.c2") + static class TestController { + + final Tracer tracer; + + Span span; + + ContextView interceptedContext; + + BlockingQueue receivedFrames = new LinkedBlockingDeque<>(); + + TestController(Tracer tracer) { + this.tracer = tracer; + } + + BlockingQueue getReceivedFrames() { + return this.receivedFrames; + } + + Span getSpan() { + return this.span; + } + + void reset() { + this.span = null; + } + + @MessageMapping("fnf") + Mono testFnf() { + + this.span = this.tracer.currentSpan(); + + return Mono.deferContextual(c -> { + interceptedContext = c; + receivedFrames.offer(FrameType.REQUEST_FNF); + return Mono.empty(); + }); + } + + @MessageMapping("rr") + Mono testRR() { + this.span = this.tracer.currentSpan(); + + return Mono.deferContextual(c -> { + interceptedContext = c; + receivedFrames.offer(FrameType.REQUEST_RESPONSE); + return Mono.just("response"); + }); + } + + @MessageMapping("rs") + Flux testRS() { + this.span = this.tracer.currentSpan(); + + return Flux.deferContextual(c -> { + interceptedContext = c; + receivedFrames.offer(FrameType.REQUEST_STREAM); + return Flux.just("stream"); + }); + } + + @MessageMapping("rc") + Flux testRC(@Payload Flux inbound) { + this.span = this.tracer.currentSpan(); + + return Flux.deferContextual(c -> { + interceptedContext = c; + receivedFrames.offer(FrameType.REQUEST_CHANNEL); + return inbound; + }); + } + + } + +} diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/task/SpringCloudTaskIntegrationTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/task/SpringCloudTaskIntegrationTests.java new file mode 100644 index 000000000..e1c5f83f3 --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/task/SpringCloudTaskIntegrationTests.java @@ -0,0 +1,107 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.task; + +import java.util.Iterator; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.cloud.sleuth.exporter.FinishedSpan; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.cloud.task.configuration.EnableTask; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; + +import static org.assertj.core.api.BDDAssertions.then; + +@ContextConfiguration(classes = SpringCloudTaskIntegrationTests.TestConfig.class) +@TestPropertySource(properties = "spring.application.name=MyApplication") +public abstract class SpringCloudTaskIntegrationTests { + + @Autowired + TestSpanHandler spans; + + @Test + public void should_pass_tracing_information_when_using_spring_cloud_task() { + Set traceIds = this.spans.reportedSpans().stream().map(FinishedSpan::getTraceId) + .collect(Collectors.toSet()); + then(traceIds).as("There's one traceid").hasSize(1); + Set spanIds = this.spans.reportedSpans().stream().map(FinishedSpan::getSpanId) + .collect(Collectors.toSet()); + + then(spanIds).as("There are 3 spans").hasSize(3); + Iterator spanIterator = this.spans.reportedSpans().iterator(); + + FinishedSpan first = spanIterator.next(); + FinishedSpan second = spanIterator.next(); + FinishedSpan third = spanIterator.next(); + then(first.getName()).isEqualTo("myApplicationRunner"); + then(second.getName()).isEqualTo("myCommandLineRunner"); + then(third.getName()).isEqualTo("MyApplication"); + } + + @Configuration(proxyBeanMethods = false) + @EnableAutoConfiguration + @EnableTask + public static class TestConfig { + + @Bean + MyCommandLineRunner myCommandLineRunner() { + return new MyCommandLineRunner(); + } + + @Bean + MyApplicationRunner myApplicationRunner() { + return new MyApplicationRunner(); + } + + } + + static class MyCommandLineRunner implements CommandLineRunner { + + private static final Log log = LogFactory.getLog(MyCommandLineRunner.class); + + @Override + public void run(String... args) throws Exception { + log.info("Ran MyCommandLineRunner"); + } + + } + + static class MyApplicationRunner implements ApplicationRunner { + + private static final Log log = LogFactory.getLog(MyApplicationRunner.class); + + @Override + public void run(ApplicationArguments args) throws Exception { + log.info("Ran MyApplicationRunner"); + } + + } + +} diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerParserTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerParserTests.java index e7d0d3be3..49e5c5abe 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerParserTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerParserTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java index 4adc11f98..ed474403e 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -53,6 +53,7 @@ public abstract class IgnoreAutoConfiguredSkipPatternsIntegrationTests { @AfterEach public void clearSpans() { this.spans.clear(); + this.tracer.withSpan(null); } @Test diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithBasePath.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithBasePath.java index 8afac2ab3..f4477f57f 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithBasePath.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithBasePath.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath.java index 845138a40..9dbbb5129 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath.java index 3ad7f9d88..1f6206ad8 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath.java index 5161eccd4..33957c03a 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java index bce777ec8..cb03298a9 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessorTest.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessorTest.java index 1774cf075..ff85ff7ff 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessorTest.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/MultipleAsyncRestTemplateTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/MultipleAsyncRestTemplateTests.java index 7c8395db4..ab56537e9 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/MultipleAsyncRestTemplateTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/MultipleAsyncRestTemplateTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/ReactorNettyHttpClientSpringBootTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/ReactorNettyHttpClientSpringBootTests.java index f7e37f9a5..5d89199cd 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/ReactorNettyHttpClientSpringBootTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/ReactorNettyHttpClientSpringBootTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java index ff6ae25c0..69777c4e7 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -24,6 +24,7 @@ import org.assertj.core.api.BDDAssertions; import org.junit.jupiter.api.Test; import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter; +import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.test.TestTracingAwareSupplier; import org.springframework.http.HttpHeaders; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; @@ -44,7 +45,11 @@ public abstract class TraceRequestHttpHeadersFilterTests implements TestTracingA MockServerWebExchange exchange = MockServerWebExchange.builder(request).build(); HttpHeaders filteredHeaders = filter.filter(requestHeaders(httpHeaders), exchange); + thenTraceContinuedWithNewSpan(httpHeaders, filteredHeaders); + BDDAssertions.then((Object) exchange.getAttribute(TraceRequestHttpHeadersFilter.SPAN_ATTRIBUTE)).isNotNull(); + } + private void thenTraceContinuedWithNewSpan(HttpHeaders httpHeaders, HttpHeaders filteredHeaders) { // we want to continue the trace BDDAssertions.then(high(filteredHeaders.get("X-B3-TraceId"))).isEqualTo(high(httpHeaders.get("X-B3-TraceId"))); // but we want to have a new span id @@ -53,6 +58,25 @@ public abstract class TraceRequestHttpHeadersFilterTests implements TestTracingA BDDAssertions.then(filteredHeaders.get("X-Hello-Request")) .isEqualTo(Collections.singletonList("Request World")); BDDAssertions.then(filteredHeaders.get("X-Auth-User")).hasSize(1); + } + + @Test + public void should_continue_span_tracing_when_span_already_in_exchange_attributes() { + HttpHeadersFilter filter = new TraceRequestHttpHeadersFilter(tracerTest().tracing().tracer(), + tracerTest().tracing().httpClientHandler(), tracerTest().tracing().propagator()); + HttpHeaders httpHeaders = new HttpHeaders(); + Span span = tracerTest().tracing().tracer().nextSpan(); + httpHeaders.set("X-Hello", "World"); + httpHeaders.set("X-B3-TraceId", span.context().traceId()); + httpHeaders.set("X-B3-SpanId", span.context().spanId()); + MockServerHttpRequest request = MockServerHttpRequest.post("foo/bar").headers(httpHeaders).build(); + MockServerWebExchange exchange = MockServerWebExchange.builder(request).build(); + exchange.getAttributes().put(TraceRequestHttpHeadersFilter.TRACE_REQUEST_ATTR_FROM_TRACE_WEB_FILTER, span); + + HttpHeaders filteredHeaders = filter.filter(requestHeaders(httpHeaders), exchange); + + // we want to continue the trace + thenTraceContinuedWithNewSpan(httpHeaders, filteredHeaders); BDDAssertions.then((Object) exchange.getAttribute(TraceRequestHttpHeadersFilter.SPAN_ATTRIBUTE)).isNotNull(); } diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceResponseHttpHeadersFilterTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceResponseHttpHeadersFilterTests.java index a83dbcdb0..65e56527e 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceResponseHttpHeadersFilterTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceResponseHttpHeadersFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java index b542e5175..2eddab7ca 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorTests.java index b38a4f6d0..1685907d0 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/discoveryexception/WebClientDiscoveryExceptionTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/discoveryexception/WebClientDiscoveryExceptionTests.java index a8c9889f4..86a5ccf8b 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/discoveryexception/WebClientDiscoveryExceptionTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/discoveryexception/WebClientDiscoveryExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/exception/WebClientExceptionTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/exception/WebClientExceptionTests.java index eea050c41..b69c15564 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/exception/WebClientExceptionTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/exception/WebClientExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignRetriesTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignRetriesTests.java index 1857904ec..6d608ff9a 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignRetriesTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignRetriesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignAspectTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignAspectTests.java index e7eaad042..736596666 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignAspectTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignAspectTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignClientTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignClientTests.java index f329abc89..42885bfa0 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignClientTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/notsampled/WebClientNotSampledTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/notsampled/WebClientNotSampledTests.java index 66a17fb8b..15df91162 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/notsampled/WebClientNotSampledTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/notsampled/WebClientNotSampledTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/parser/WebClientCustomParserTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/parser/WebClientCustomParserTests.java index 59dcb6186..4275bf577 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/parser/WebClientCustomParserTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/parser/WebClientCustomParserTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/sampled/WebClientTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/sampled/WebClientTests.java index 09e878673..89fad7d8f 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/sampled/WebClientTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/sampled/WebClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. @@ -130,6 +130,11 @@ public abstract class WebClientTests { this.fooController.clear(); } + @BeforeEach + public void setup() { + log.info("Starting test"); + } + @ParameterizedTest @MethodSource("parametersForShouldCreateANewSpanWithClientSideTagsWhenNoPreviousTracingWasPresent") @SuppressWarnings("unchecked") @@ -141,15 +146,23 @@ public abstract class WebClientTests { then(this.spans).isNotEmpty(); Optional noTraceSpan = this.spans.reportedSpans().stream() .filter(span -> span.getName().contains("GET") && !span.getTags().isEmpty() - && span.getTags().containsKey("http.path")) + && span.getTags().containsKey(pathKey())) .findFirst(); then(noTraceSpan.isPresent()).isTrue(); - then(noTraceSpan.get().getTags()).containsEntry("http.path", "/notrace").containsEntry("http.method", - "GET"); + then(noTraceSpan.get().getTags()).containsEntry(pathKey(), "/notrace").containsEntry("http.method", "GET"); // TODO: matches cause there is an issue with Feign not providing the full URL // at the interceptor level - then(noTraceSpan.get().getTags().get("http.path")).matches(".*/notrace"); + then(noTraceSpan.get().getTags().get(pathKey())).matches(".*/notrace"); }); + thenThereIsNoCurrentSpan(); + } + + protected String pathKey() { + return "http.path"; + } + + private void thenThereIsNoCurrentSpan() { + log.info("Current span [" + this.tracer.currentSpan() + "]"); then(this.tracer.currentSpan()).isNull(); } @@ -197,7 +210,7 @@ public abstract class WebClientTests { span.end(); } - then(this.tracer.currentSpan()).isNull(); + thenThereIsNoCurrentSpan(); then(this.spans).isNotEmpty(); } @@ -213,7 +226,7 @@ public abstract class WebClientTests { finally { span.end(); } - then(this.tracer.currentSpan()).isNull(); + thenThereIsNoCurrentSpan(); then(this.spans.reportedSpans().stream().filter(r -> r.getKind() != null).map(r -> r.getKind().name()) .collect(Collectors.toList())).isNotEmpty().contains("CLIENT"); } @@ -234,7 +247,7 @@ public abstract class WebClientTests { span.end(); } - then(this.tracer.currentSpan()).isNull(); + thenThereIsNoCurrentSpan(); then(this.spans.reportedSpans().stream().filter(r -> r.getKind() != null).map(r -> r.getKind().name()) .collect(Collectors.toList())).isNotEmpty().contains("CLIENT"); } @@ -286,7 +299,7 @@ public abstract class WebClientTests { span.end(); } - then(this.tracer.currentSpan()).isNull(); + thenThereIsNoCurrentSpan(); then(this.spans).isNotEmpty(); } @@ -305,7 +318,7 @@ public abstract class WebClientTests { catch (HttpClientErrorException e) { } - then(this.tracer.currentSpan()).isNull(); + thenThereIsNoCurrentSpan(); Optional storedSpan = this.spans.reportedSpans().stream() .filter(span -> "404".equals(span.getTags().get("http.status_code"))).findFirst(); then(storedSpan.isPresent()).isTrue(); @@ -325,7 +338,7 @@ public abstract class WebClientTests { public void shouldNotExecuteErrorControllerWhenUrlIsFound() { this.template.getForEntity("http://fooservice/notrace", String.class); - then(this.tracer.currentSpan()).isNull(); + thenThereIsNoCurrentSpan(); then(this.testErrorController.getSpan()).isNull(); } @@ -341,9 +354,10 @@ public abstract class WebClientTests { finally { span.end(); } - then(this.tracer.currentSpan()).isNull(); + thenThereIsNoCurrentSpan(); then(this.customizer.isExecuted()).isTrue(); - then(this.spans).extracting("kind.name").contains("CLIENT"); + then(this.spans.reportedSpans().stream().filter(s -> s.getKind() != null).map(s -> s.getKind().name()) + .collect(Collectors.toList())).contains("CLIENT"); } @Test diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/SleuthContextListenerAccessor.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/internal/SleuthContextListenerAccessor.java similarity index 95% rename from tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/SleuthContextListenerAccessor.java rename to tests/common/src/main/java/org/springframework/cloud/sleuth/internal/SleuthContextListenerAccessor.java index 46fa56b3e..649bac15a 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/SleuthContextListenerAccessor.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/internal/SleuthContextListenerAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TestSpanHandler.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TestSpanHandler.java index f0839ea4c..17681a5ea 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TestSpanHandler.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TestSpanHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TestTracingAssertions.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TestTracingAssertions.java index 495f17f00..143fe7350 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TestTracingAssertions.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TestTracingAssertions.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TestTracingAware.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TestTracingAware.java index 526572d45..bd7d4a7b6 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TestTracingAware.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TestTracingAware.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TestTracingAwareSupplier.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TestTracingAwareSupplier.java index 50b1da1b7..2d823306e 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TestTracingAwareSupplier.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TestTracingAwareSupplier.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TracerAware.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TracerAware.java index e2a2f1cd1..e2844f9fc 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TracerAware.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/test/TracerAware.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinDiscoveryClientTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinDiscoveryClientTests.java index 71d4bf539..d27f3ca86 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinDiscoveryClientTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinDiscoveryClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/pom.xml b/tests/pom.xml index c7949b553..91c56e31a 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -1,42 +1,42 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-tests - pom - Spring Cloud Sleuth Tests - Spring Cloud Sleuth Tests - - - org.springframework.cloud - spring-cloud-sleuth - 3.0.2-SNAPSHOT - .. - - - - common - brave - - - + + + + + 4.0.0 + + spring-cloud-sleuth-tests + pom + Spring Cloud Sleuth Tests + Spring Cloud Sleuth Tests + + + org.springframework.cloud + spring-cloud-sleuth + 3.1.0-SNAPSHOT + .. + + + + common + brave + + +