diff --git a/pom.xml b/pom.xml index e8de33455..72c5de8a5 100644 --- a/pom.xml +++ b/pom.xml @@ -154,6 +154,13 @@ pom import + + org.springframework.cloud + spring-cloud-gateway-dependencies + ${spring-cloud-gateway.version} + pom + import + org.springframework.cloud spring-cloud-stream-dependencies @@ -244,6 +251,7 @@ 1.8 2.1.0.BUILD-SNAPSHOT 2.1.0.BUILD-SNAPSHOT + 2.1.0.BUILD-SNAPSHOT Fishtown.BUILD-SNAPSHOT 2.1.0.BUILD-SNAPSHOT 2.1.0.BUILD-SNAPSHOT diff --git a/spring-cloud-sleuth-core/pom.xml b/spring-cloud-sleuth-core/pom.xml index 3e746be01..16a4e7ea0 100644 --- a/spring-cloud-sleuth-core/pom.xml +++ b/spring-cloud-sleuth-core/pom.xml @@ -81,6 +81,11 @@ org.springframework.cloud spring-cloud-commons + + org.springframework.cloud + spring-cloud-starter-gateway + true + org.springframework.cloud spring-cloud-starter-openfeign diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java new file mode 100644 index 000000000..05649ca59 --- /dev/null +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java @@ -0,0 +1,247 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.sleuth.instrument.web.client; + +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; + +import brave.Span; +import brave.Tracer; +import brave.http.HttpClientHandler; +import brave.http.HttpTracing; +import brave.propagation.Propagation; +import brave.propagation.TraceContext; +import io.netty.bootstrap.Bootstrap; +import io.netty.handler.codec.http.HttpHeaders; +import reactor.core.publisher.Mono; +import reactor.netty.Connection; +import reactor.netty.http.client.HttpClient; +import reactor.netty.http.client.HttpClientRequest; +import reactor.netty.http.client.HttpClientResponse; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.BeanPostProcessor; + +class HttpClientBeanPostProcessor implements BeanPostProcessor { + + private final BeanFactory beanFactory; + + HttpClientBeanPostProcessor(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + if (bean instanceof HttpClient) { + return ((HttpClient) bean).mapConnect(new TracingMapConnect(this.beanFactory)) + .doOnRequest(TracingDoOnRequest.create(this.beanFactory)) + .doOnRequestError(TracingDoOnErrorRequest.create(this.beanFactory)) + .doOnResponse(TracingDoOnResponse.create(this.beanFactory)) + .doOnResponseError(TracingDoOnErrorResponse.create(this.beanFactory)); + } + return bean; + } + + private static class TracingMapConnect implements + BiFunction, Bootstrap, Mono> { + + private final BeanFactory beanFactory; + + private Tracer tracer; + + TracingMapConnect(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @Override + public Mono apply(Mono mono, + Bootstrap bootstrap) { + return mono.subscriberContext(context -> context.put(AtomicReference.class, + new AtomicReference<>(tracer().currentSpan()))); + } + + private Tracer tracer() { + if (this.tracer == null) { + this.tracer = this.beanFactory.getBean(Tracer.class); + } + return this.tracer; + } + + } + + private static class TracingDoOnRequest + implements BiConsumer { + + static final Propagation.Setter SETTER = new Propagation.Setter() { + @Override + public void put(HttpHeaders carrier, String key, String value) { + if (!carrier.contains(key)) { + carrier.add(key, value); + } + } + + @Override + public String toString() { + return "HttpHeaders::add"; + } + }; + + final Tracer tracer; + + final HttpClientHandler handler; + + final TraceContext.Injector injector; + + final HttpTracing httpTracing; + + final Propagation propagation; + + TracingDoOnRequest(HttpTracing httpTracing) { + this.tracer = httpTracing.tracing().tracer(); + this.handler = HttpClientHandler.create(httpTracing, new HttpAdapter()); + this.propagation = httpTracing.tracing().propagation(); + this.injector = this.propagation.injector(SETTER); + this.httpTracing = httpTracing; + } + + static TracingDoOnRequest create(BeanFactory beanFactory) { + return new TracingDoOnRequest(beanFactory.getBean(HttpTracing.class)); + } + + @Override + public void accept(HttpClientRequest req, Connection connection) { + if (this.propagation.keys().stream() + .anyMatch(key -> req.requestHeaders().contains(key))) { + // request already instrumented + return; + } + AtomicReference reference = req.currentContext() + .getOrDefault(AtomicReference.class, new AtomicReference()); + Span span = this.handler.handleSend(this.injector, req.requestHeaders(), req, + (Span) reference.get()); + reference.set(span); + } + + } + + private static class TracingDoOnResponse extends AbstractTracingDoOnHandler + implements BiConsumer { + + TracingDoOnResponse(HttpTracing httpTracing) { + super(httpTracing); + } + + static TracingDoOnResponse create(BeanFactory beanFactory) { + return new TracingDoOnResponse(beanFactory.getBean(HttpTracing.class)); + } + + @Override + public void accept(HttpClientResponse httpClientResponse, Connection connection) { + handle(httpClientResponse, null); + } + + } + + private static class TracingDoOnErrorRequest extends AbstractTracingDoOnHandler + implements BiConsumer { + + TracingDoOnErrorRequest(HttpTracing httpTracing) { + super(httpTracing); + } + + static TracingDoOnErrorRequest create(BeanFactory beanFactory) { + return new TracingDoOnErrorRequest(beanFactory.getBean(HttpTracing.class)); + } + + @Override + public void accept(HttpClientRequest request, Throwable throwable) { + handle(null, throwable); + } + + } + + private static class TracingDoOnErrorResponse extends AbstractTracingDoOnHandler + implements BiConsumer { + + TracingDoOnErrorResponse(HttpTracing httpTracing) { + super(httpTracing); + } + + static TracingDoOnErrorResponse create(BeanFactory beanFactory) { + return new TracingDoOnErrorResponse(beanFactory.getBean(HttpTracing.class)); + } + + @Override + public void accept(HttpClientResponse httpClientResponse, Throwable throwable) { + handle(httpClientResponse, throwable); + } + + } + + private static abstract class AbstractTracingDoOnHandler { + + final Tracer tracer; + + final HttpClientHandler handler; + + AbstractTracingDoOnHandler(HttpTracing httpTracing) { + this.tracer = httpTracing.tracing().tracer(); + this.handler = HttpClientHandler.create(httpTracing, new HttpAdapter()); + } + + protected void handle(HttpClientResponse httpClientResponse, + Throwable throwable) { + AtomicReference reference = httpClientResponse.currentContext() + .getOrDefault(AtomicReference.class, null); + if (reference == null || reference.get() == null) { + return; + } + this.handler.handleReceive(httpClientResponse, throwable, + (Span) reference.get()); + } + + } + + private static class HttpAdapter + extends brave.http.HttpClientAdapter { + + @Override + public String method(HttpClientRequest request) { + return request.method().name(); + } + + @Override + public String url(HttpClientRequest request) { + return request.uri(); + } + + @Override + public String requestHeader(HttpClientRequest request, String name) { + Object result = request.requestHeaders().get(name); + return result != null ? result.toString() : ""; + } + + @Override + public Integer statusCode(HttpClientResponse response) { + return response.status().code(); + } + + } + +} \ No newline at end of file diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java new file mode 100644 index 000000000..41604465c --- /dev/null +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java @@ -0,0 +1,169 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.sleuth.instrument.web.client; + +import brave.Span; +import brave.Tracer; +import brave.http.HttpClientHandler; +import brave.http.HttpTracing; +import brave.propagation.Propagation; +import brave.propagation.TraceContext; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter; +import org.springframework.http.HttpHeaders; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.web.server.ServerWebExchange; + +class TraceRequestHttpHeadersFilter extends AbstractHttpHeadersFilter { + + private static final Log log = LogFactory.getLog(TraceRequestHttpHeadersFilter.class); + + static HttpHeadersFilter create(HttpTracing httpTracing) { + return new TraceRequestHttpHeadersFilter(httpTracing); + } + + private TraceRequestHttpHeadersFilter(HttpTracing httpTracing) { + super(httpTracing); + } + + @Override + public HttpHeaders filter(HttpHeaders input, ServerWebExchange exchange) { + Object storedSpan = exchange.getAttribute(SPAN_ATTRIBUTE); + if (log.isDebugEnabled()) { + log.debug("Will instrument the HTTP request headers"); + } + Span span = clientSent(exchange, storedSpan); + if (log.isDebugEnabled()) { + log.debug("Client span created for the request " + span); + } + exchange.getAttributes().put(SPAN_ATTRIBUTE, span); + return new HttpHeaders(exchange.getRequest().getHeaders()); + } + + private Span clientSent(ServerWebExchange exchange, Object storedSpan) { + if (storedSpan != null) { + return this.handler.handleSend(this.injector, exchange.getRequest(), + (Span) storedSpan); + } + return this.handler.handleSend(this.injector, exchange.getRequest()); + } + + @Override + public boolean supports(Type type) { + return type.equals(Type.REQUEST); + } + +} + +class TraceResponseHttpHeadersFilter extends AbstractHttpHeadersFilter { + + private static final Log log = LogFactory.getLog(TraceResponseHttpHeadersFilter.class); + + static HttpHeadersFilter create(HttpTracing httpTracing) { + return new TraceResponseHttpHeadersFilter(httpTracing); + } + + private TraceResponseHttpHeadersFilter(HttpTracing httpTracing) { + super(httpTracing); + } + + @Override + public HttpHeaders filter(HttpHeaders input, ServerWebExchange exchange) { + Object storedSpan = exchange.getAttribute(SPAN_ATTRIBUTE); + if (storedSpan == null) { + return input; + } + if (log.isDebugEnabled()) { + log.debug("Will instrument the response"); + } + this.handler.handleReceive(exchange.getResponse(), null, (Span) storedSpan); + if (log.isDebugEnabled()) { + log.debug("The response was handled"); + } + return new HttpHeaders(input); + } + + @Override + public boolean supports(Type type) { + return type.equals(Type.RESPONSE); + } + +} + +abstract class AbstractHttpHeadersFilter implements HttpHeadersFilter { + + static final String SPAN_ATTRIBUTE = Span.class.getName(); + + private static final Propagation.Setter SETTER = new Propagation.Setter() { + @Override + public void put(ServerHttpRequest carrier, String key, String value) { + if (!carrier.getHeaders().containsKey(key)) { + carrier.getHeaders().add(key, value); + } + } + + @Override + public String toString() { + return "ServerHttpRequest::HttpHeaders::add"; + } + }; + + final Tracer tracer; + + final HttpClientHandler handler; + + final TraceContext.Injector injector; + + final HttpTracing httpTracing; + + AbstractHttpHeadersFilter(HttpTracing httpTracing) { + this.tracer = httpTracing.tracing().tracer(); + this.handler = HttpClientHandler.create(httpTracing, new ServerHttpAdapter()); + this.injector = httpTracing.tracing().propagation().injector(SETTER); + this.httpTracing = httpTracing; + } + + private static class ServerHttpAdapter + extends brave.http.HttpClientAdapter { + + @Override + public String method(ServerHttpRequest request) { + return request.getMethodValue(); + } + + @Override + public String url(ServerHttpRequest request) { + return request.getURI().toString(); + } + + @Override + public String requestHeader(ServerHttpRequest request, String name) { + Object result = request.getHeaders().get(name); + return result != null ? result.toString() : ""; + } + + @Override + public Integer statusCode(ServerHttpResponse response) { + return response.getStatusCode() != null ? response.getStatusCode().value() + : null; + } + + } + +} \ No newline at end of file diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java index fbdb26059..b440e63b7 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java @@ -19,30 +19,14 @@ package org.springframework.cloud.sleuth.instrument.web.client; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import brave.Span; -import brave.Tracer; -import brave.http.HttpClientHandler; import brave.http.HttpTracing; import brave.httpasyncclient.TracingHttpAsyncClientBuilder; import brave.httpclient.TracingHttpClientBuilder; -import brave.propagation.Propagation; -import brave.propagation.TraceContext; import brave.spring.web.TracingClientHttpRequestInterceptor; -import io.netty.bootstrap.Bootstrap; -import io.netty.handler.codec.http.HttpHeaders; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.nio.client.HttpAsyncClientBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import reactor.core.publisher.Mono; -import reactor.netty.Connection; import reactor.netty.http.client.HttpClient; -import reactor.netty.http.client.HttpClientRequest; -import reactor.netty.http.client.HttpClientResponse; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; @@ -57,6 +41,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoRestTemplateCustomizer; import org.springframework.boot.web.client.RestTemplateCustomizer; import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; +import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter; import org.springframework.cloud.sleuth.instrument.web.TraceWebServletAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -102,7 +87,7 @@ public class TraceWebClientAutoConfiguration { private TracingClientHttpRequestInterceptor clientInterceptor; @Bean - static TraceRestTemplateBeanPostProcessor traceRestTemplateBPP( + static TraceRestTemplateBeanPostProcessor traceRestTemplateBeanPostProcessor( ListableBeanFactory beanFactory) { return new TraceRestTemplateBeanPostProcessor(beanFactory); } @@ -153,6 +138,22 @@ public class TraceWebClientAutoConfiguration { } + @Configuration + @ConditionalOnClass(HttpHeadersFilter.class) + static class HttpHeadersFilterConfig { + + @Bean + HttpHeadersFilter traceRequestHttpHeadersFilter(HttpTracing httpTracing) { + return TraceRequestHttpHeadersFilter.create(httpTracing); + } + + @Bean + HttpHeadersFilter traceResponseHttpHeadersFilter(HttpTracing httpTracing) { + return TraceResponseHttpHeadersFilter.create(httpTracing); + } + + } + @Configuration @ConditionalOnClass(HttpClient.class) static class NettyConfiguration { @@ -315,210 +316,6 @@ class LazyTracingClientHttpRequestInterceptor implements ClientHttpRequestInterc } -class HttpClientBeanPostProcessor implements BeanPostProcessor { - - private final BeanFactory beanFactory; - - HttpClientBeanPostProcessor(BeanFactory beanFactory) { - this.beanFactory = beanFactory; - } - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) - throws BeansException { - if (bean instanceof HttpClient) { - return ((HttpClient) bean).mapConnect(new TracingMapConnect(this.beanFactory)) - .doOnRequest(TracingDoOnRequest.create(this.beanFactory)) - .doOnRequestError(TracingDoOnErrorRequest.create(this.beanFactory)) - .doOnResponse(TracingDoOnResponse.create(this.beanFactory)) - .doOnResponseError(TracingDoOnErrorResponse.create(this.beanFactory)); - } - return bean; - } - - private static class TracingMapConnect implements - BiFunction, Bootstrap, Mono> { - - private final BeanFactory beanFactory; - - private Tracer tracer; - - TracingMapConnect(BeanFactory beanFactory) { - this.beanFactory = beanFactory; - } - - @Override - public Mono apply(Mono mono, - Bootstrap bootstrap) { - return mono.subscriberContext(context -> context.put(AtomicReference.class, - new AtomicReference<>(tracer().currentSpan()))); - } - - private Tracer tracer() { - if (this.tracer == null) { - this.tracer = this.beanFactory.getBean(Tracer.class); - } - return this.tracer; - } - - } - - private static class TracingDoOnRequest - implements BiConsumer { - - static final Propagation.Setter SETTER = new Propagation.Setter() { - @Override - public void put(HttpHeaders carrier, String key, String value) { - if (!carrier.contains(key)) { - carrier.add(key, value); - } - } - - @Override - public String toString() { - return "HttpHeaders::add"; - } - }; - - private static final Logger log = LoggerFactory - .getLogger(TracingDoOnRequest.class); - - final Tracer tracer; - - final HttpClientHandler handler; - - final TraceContext.Injector injector; - - final HttpTracing httpTracing; - - TracingDoOnRequest(HttpTracing httpTracing) { - this.tracer = httpTracing.tracing().tracer(); - this.handler = HttpClientHandler.create(httpTracing, new HttpAdapter()); - this.injector = httpTracing.tracing().propagation().injector(SETTER); - this.httpTracing = httpTracing; - } - - static TracingDoOnRequest create(BeanFactory beanFactory) { - return new TracingDoOnRequest(beanFactory.getBean(HttpTracing.class)); - } - - @Override - public void accept(HttpClientRequest req, Connection connection) { - AtomicReference reference = req.currentContext() - .getOrDefault(AtomicReference.class, new AtomicReference()); - Span span = this.handler.handleSend(this.injector, req.requestHeaders(), req, - (Span) reference.get()); - reference.set(span); - } - - } - - private static class TracingDoOnResponse extends AbstractTracingDoOnHandler - implements BiConsumer { - - TracingDoOnResponse(HttpTracing httpTracing) { - super(httpTracing); - } - - static TracingDoOnResponse create(BeanFactory beanFactory) { - return new TracingDoOnResponse(beanFactory.getBean(HttpTracing.class)); - } - - @Override - public void accept(HttpClientResponse httpClientResponse, Connection connection) { - handle(httpClientResponse, null); - } - - } - - private static class TracingDoOnErrorRequest extends AbstractTracingDoOnHandler - implements BiConsumer { - - TracingDoOnErrorRequest(HttpTracing httpTracing) { - super(httpTracing); - } - - static TracingDoOnErrorRequest create(BeanFactory beanFactory) { - return new TracingDoOnErrorRequest(beanFactory.getBean(HttpTracing.class)); - } - - @Override - public void accept(HttpClientRequest request, Throwable throwable) { - handle(null, throwable); - } - - } - - private static class TracingDoOnErrorResponse extends AbstractTracingDoOnHandler - implements BiConsumer { - - TracingDoOnErrorResponse(HttpTracing httpTracing) { - super(httpTracing); - } - - static TracingDoOnErrorResponse create(BeanFactory beanFactory) { - return new TracingDoOnErrorResponse(beanFactory.getBean(HttpTracing.class)); - } - - @Override - public void accept(HttpClientResponse httpClientResponse, Throwable throwable) { - handle(httpClientResponse, throwable); - } - - } - - private static abstract class AbstractTracingDoOnHandler { - - final Tracer tracer; - - final HttpClientHandler handler; - - AbstractTracingDoOnHandler(HttpTracing httpTracing) { - this.tracer = httpTracing.tracing().tracer(); - this.handler = HttpClientHandler.create(httpTracing, new HttpAdapter()); - } - - protected void handle(HttpClientResponse httpClientResponse, - Throwable throwable) { - AtomicReference reference = httpClientResponse.currentContext() - .getOrDefault(AtomicReference.class, null); - if (reference == null || reference.get() == null) { - return; - } - this.handler.handleReceive(httpClientResponse, throwable, - (Span) reference.get()); - } - - } - - private static class HttpAdapter - extends brave.http.HttpClientAdapter { - - @Override - public String method(HttpClientRequest request) { - return request.method().name(); - } - - @Override - public String url(HttpClientRequest request) { - return request.uri(); - } - - @Override - public String requestHeader(HttpClientRequest request, String name) { - Object result = request.requestHeaders().get(name); - return result != null ? result.toString() : ""; - } - - @Override - public Integer statusCode(HttpClientResponse response) { - return response.status().code(); - } - - } - -} - class TraceUserInfoRestTemplateCustomizer implements UserInfoRestTemplateCustomizer { private final BeanFactory beanFactory; @@ -545,4 +342,4 @@ class TraceUserInfoRestTemplateCustomizer implements UserInfoRestTemplateCustomi } } -} +} \ No newline at end of file diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/JmsTracingConfigurationTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/JmsTracingConfigurationTest.java index 3e656a33c..53caff3d3 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/JmsTracingConfigurationTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/JmsTracingConfigurationTest.java @@ -22,6 +22,7 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; + import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.JMSException; @@ -37,15 +38,19 @@ import brave.propagation.TraceContext; import org.apache.activemq.ra.ActiveMQActivationSpec; import org.apache.activemq.ra.ActiveMQResourceAdapter; import org.junit.Test; +import zipkin2.Annotation; +import zipkin2.Span; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration; import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration; import org.springframework.boot.jms.XAConnectionFactoryWrapper; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.cloud.gateway.config.GatewayAutoConfiguration; +import org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jca.support.ResourceAdapterFactoryBean; @@ -57,8 +62,6 @@ import org.springframework.jms.config.JmsListenerEndpointRegistrar; import org.springframework.jms.config.SimpleJmsListenerEndpoint; import org.springframework.jms.core.JmsTemplate; import org.springframework.jms.listener.endpoint.JmsMessageEndpointManager; -import zipkin2.Annotation; -import zipkin2.Span; import static org.assertj.core.api.Assertions.assertThat; @@ -273,7 +276,8 @@ public class JmsTracingConfigurationTest { } @Configuration -@EnableAutoConfiguration +@EnableAutoConfiguration(exclude = { GatewayAutoConfiguration.class, + GatewayClassPathWarningAutoConfiguration.class }) class JmsTestTracingConfiguration { static final String CONTEXT_LEAK = "context.leak"; diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SpringDataInstrumentationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SpringDataInstrumentationTests.java index e0c3494d5..2f29d79a5 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SpringDataInstrumentationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SpringDataInstrumentationTests.java @@ -30,12 +30,15 @@ import org.awaitility.Awaitility; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import zipkin2.Span; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.gateway.config.GatewayAutoConfiguration; +import org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration; import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -49,8 +52,6 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.client.RestTemplate; -import zipkin2.Span; - import static org.assertj.core.api.Assertions.tuple; import static org.assertj.core.api.BDDAssertions.then; @@ -114,7 +115,8 @@ public class SpringDataInstrumentationTests { } @Configuration -@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class) +@EnableAutoConfiguration(exclude = { SecurityAutoConfiguration.class, + GatewayAutoConfiguration.class, GatewayClassPathWarningAutoConfiguration.class }) @EntityScan(basePackageClasses = Reservation.class) class ReservationServiceApplication { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/integration/WebClientTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/integration/WebClientTests.java index 3ebcbf896..7ddb02ddd 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/integration/WebClientTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/integration/WebClientTests.java @@ -27,6 +27,7 @@ import java.util.Optional; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; + import javax.servlet.http.HttpServletRequest; import brave.Span; @@ -55,6 +56,13 @@ import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import reactor.core.publisher.Hooks; +import reactor.core.scheduler.Schedulers; +import reactor.netty.http.client.HttpClient; +import reactor.netty.http.client.HttpClientResponse; +import zipkin2.Annotation; +import zipkin2.reporter.Reporter; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -66,6 +74,8 @@ import org.springframework.boot.web.client.RestTemplateCustomizer; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.web.servlet.error.ErrorAttributes; import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.cloud.gateway.config.GatewayAutoConfiguration; +import org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration; import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.FeignClient; @@ -86,12 +96,6 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; import org.springframework.web.reactive.function.client.WebClient; -import reactor.core.publisher.Hooks; -import reactor.core.scheduler.Schedulers; -import reactor.netty.http.client.HttpClient; -import reactor.netty.http.client.HttpClientResponse; -import zipkin2.Annotation; -import zipkin2.reporter.Reporter; import static org.assertj.core.api.Assertions.fail; import static org.assertj.core.api.BDDAssertions.then; @@ -510,7 +514,9 @@ public class WebClientTests { } @Configuration - @EnableAutoConfiguration(exclude = TraceWebServletAutoConfiguration.class) + @EnableAutoConfiguration(exclude = { TraceWebServletAutoConfiguration.class, + GatewayClassPathWarningAutoConfiguration.class, + GatewayAutoConfiguration.class }) @EnableFeignClients @RibbonClient(value = "fooservice", configuration = SimpleRibbonClientConfiguration.class) public static class TestConfiguration { diff --git a/spring-cloud-sleuth-core/src/test/resources/application.yml b/spring-cloud-sleuth-core/src/test/resources/application.yml index f28658bb9..5ca3b2e2e 100644 --- a/spring-cloud-sleuth-core/src/test/resources/application.yml +++ b/spring-cloud-sleuth-core/src/test/resources/application.yml @@ -20,6 +20,6 @@ logging.level.org.springframework.cloud: DEBUG logging.level.org.springframework.cloud.sleuth.instrument.web.client.feign: TRACE #disable hibernate by default -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 +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 spring.data.jdbc.repositories.enabled: false spring.data.jpa.repositories.enabled: false \ No newline at end of file