diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java index 76ecc4cd830d..82b87eb6775b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java @@ -32,7 +32,6 @@ import zipkin2.reporter.SpanBytesEncoder; import zipkin2.reporter.brave.AsyncZipkinSpanHandler; import zipkin2.reporter.brave.MutableSpanBytesEncoder; -import zipkin2.reporter.urlconnection.URLConnectionSender; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.actuate.autoconfigure.tracing.ConditionalOnEnabledTracing; @@ -40,12 +39,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.reactive.function.client.WebClient; /** * Configurations for Zipkin. Those are imported by {@link ZipkinAutoConfiguration}. @@ -56,99 +52,11 @@ class ZipkinConfigurations { @Configuration(proxyBeanMethods = false) - @Import({ UrlConnectionSenderConfiguration.class, WebClientSenderConfiguration.class, - RestTemplateSenderConfiguration.class, HttpClientSenderConfiguration.class }) + @Import({ HttpClientSenderConfiguration.class }) static class SenderConfiguration { } - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(URLConnectionSender.class) - @EnableConfigurationProperties(ZipkinProperties.class) - static class UrlConnectionSenderConfiguration { - - @Bean - @ConditionalOnMissingBean(BytesMessageSender.class) - URLConnectionSender urlConnectionSender(ZipkinProperties properties, Encoding encoding, - ObjectProvider connectionDetailsProvider, - ObjectProvider endpointSupplierFactoryProvider) { - ZipkinConnectionDetails connectionDetails = connectionDetailsProvider - .getIfAvailable(() -> new PropertiesZipkinConnectionDetails(properties)); - HttpEndpointSupplier.Factory endpointSupplierFactory = endpointSupplierFactoryProvider - .getIfAvailable(HttpEndpointSuppliers::constantFactory); - URLConnectionSender.Builder builder = URLConnectionSender.newBuilder(); - builder.connectTimeout((int) properties.getConnectTimeout().toMillis()); - builder.readTimeout((int) properties.getReadTimeout().toMillis()); - builder.endpointSupplierFactory(endpointSupplierFactory); - builder.endpoint(connectionDetails.getSpanEndpoint()); - builder.encoding(encoding); - return builder.build(); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(RestTemplate.class) - @EnableConfigurationProperties(ZipkinProperties.class) - static class RestTemplateSenderConfiguration { - - @Bean - @ConditionalOnMissingBean(BytesMessageSender.class) - @SuppressWarnings({ "deprecation", "removal" }) - ZipkinRestTemplateSender restTemplateSender(ZipkinProperties properties, Encoding encoding, - ObjectProvider customizers, - ObjectProvider connectionDetailsProvider, - ObjectProvider endpointSupplierFactoryProvider) { - ZipkinConnectionDetails connectionDetails = connectionDetailsProvider - .getIfAvailable(() -> new PropertiesZipkinConnectionDetails(properties)); - HttpEndpointSupplier.Factory endpointSupplierFactory = endpointSupplierFactoryProvider - .getIfAvailable(HttpEndpointSuppliers::constantFactory); - RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder() - .setConnectTimeout(properties.getConnectTimeout()) - .setReadTimeout(properties.getReadTimeout()); - restTemplateBuilder = applyCustomizers(restTemplateBuilder, customizers); - return new ZipkinRestTemplateSender(encoding, endpointSupplierFactory, connectionDetails.getSpanEndpoint(), - restTemplateBuilder.build()); - } - - @SuppressWarnings({ "deprecation", "removal" }) - private RestTemplateBuilder applyCustomizers(RestTemplateBuilder restTemplateBuilder, - ObjectProvider customizers) { - Iterable orderedCustomizers = () -> customizers.orderedStream() - .iterator(); - RestTemplateBuilder currentBuilder = restTemplateBuilder; - for (ZipkinRestTemplateBuilderCustomizer customizer : orderedCustomizers) { - currentBuilder = customizer.customize(currentBuilder); - } - return currentBuilder; - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(WebClient.class) - @EnableConfigurationProperties(ZipkinProperties.class) - static class WebClientSenderConfiguration { - - @Bean - @ConditionalOnMissingBean(BytesMessageSender.class) - @SuppressWarnings({ "deprecation", "removal" }) - ZipkinWebClientSender webClientSender(ZipkinProperties properties, Encoding encoding, - ObjectProvider customizers, - ObjectProvider connectionDetailsProvider, - ObjectProvider endpointSupplierFactoryProvider) { - ZipkinConnectionDetails connectionDetails = connectionDetailsProvider - .getIfAvailable(() -> new PropertiesZipkinConnectionDetails(properties)); - HttpEndpointSupplier.Factory endpointSupplierFactory = endpointSupplierFactoryProvider - .getIfAvailable(HttpEndpointSuppliers::constantFactory); - WebClient.Builder builder = WebClient.builder(); - customizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); - return new ZipkinWebClientSender(encoding, endpointSupplierFactory, connectionDetails.getSpanEndpoint(), - builder.build(), properties.getConnectTimeout().plus(properties.getReadTimeout())); - } - - } - @Configuration(proxyBeanMethods = false) @ConditionalOnClass(HttpClient.class) @EnableConfigurationProperties(ZipkinProperties.class) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsSenderConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsSenderConfigurationTests.java index 7988fd310837..8d525ddfcd5e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsSenderConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsSenderConfigurationTests.java @@ -16,14 +16,6 @@ package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import okhttp3.mockwebserver.RecordedRequest; import org.junit.jupiter.api.Test; import org.mockito.ArgumentMatchers; import zipkin2.reporter.BytesMessageSender; @@ -36,10 +28,8 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.web.reactive.function.client.WebClient; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.then; @@ -64,11 +54,7 @@ class ZipkinConfigurationsSenderConfigurationTests { @Test void shouldSupplyBeans() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(BytesMessageSender.class); - assertThat(context).hasSingleBean(URLConnectionSender.class); - assertThat(context).doesNotHaveBean(ZipkinRestTemplateSender.class); - }); + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(BytesMessageSender.class)); } @Test @@ -85,83 +71,6 @@ void shouldUseHttpClientIfUrlSenderIsNotAvailable() { }); } - @Test - void shouldPreferWebClientSenderIfWebApplicationIsReactiveAndUrlSenderIsNotAvailable() { - this.reactiveContextRunner.withUserConfiguration(RestTemplateConfiguration.class, WebClientConfiguration.class) - .withClassLoader(new FilteredClassLoader("zipkin2.reporter.urlconnection")) - .run((context) -> { - assertThat(context).doesNotHaveBean(URLConnectionSender.class); - assertThat(context).hasSingleBean(BytesMessageSender.class); - assertThat(context).hasSingleBean(ZipkinWebClientSender.class); - then(context.getBean(ZipkinWebClientBuilderCustomizer.class)).should() - .customize(ArgumentMatchers.any()); - }); - } - - @Test - void shouldPreferWebClientSenderIfWebApplicationIsServletAndUrlSenderIsNotAvailable() { - this.servletContextRunner.withUserConfiguration(RestTemplateConfiguration.class, WebClientConfiguration.class) - .withClassLoader(new FilteredClassLoader("zipkin2.reporter.urlconnection")) - .run((context) -> { - assertThat(context).doesNotHaveBean(URLConnectionSender.class); - assertThat(context).hasSingleBean(BytesMessageSender.class); - assertThat(context).hasSingleBean(ZipkinWebClientSender.class); - }); - } - - @Test - void shouldPreferWebClientInNonWebApplicationAndUrlConnectionSenderIsNotAvailable() { - this.contextRunner.withUserConfiguration(RestTemplateConfiguration.class, WebClientConfiguration.class) - .withClassLoader(new FilteredClassLoader("zipkin2.reporter.urlconnection")) - .run((context) -> { - assertThat(context).doesNotHaveBean(URLConnectionSender.class); - assertThat(context).hasSingleBean(BytesMessageSender.class); - assertThat(context).hasSingleBean(ZipkinWebClientSender.class); - }); - } - - @Test - void willUseRestTemplateInNonWebApplicationIfUrlConnectionSenderAndWebClientAreNotAvailable() { - this.contextRunner.withUserConfiguration(RestTemplateConfiguration.class) - .withClassLoader(new FilteredClassLoader(URLConnectionSender.class, WebClient.class)) - .run((context) -> { - assertThat(context).doesNotHaveBean(URLConnectionSender.class); - assertThat(context).hasSingleBean(BytesMessageSender.class); - assertThat(context).hasSingleBean(ZipkinRestTemplateSender.class); - }); - } - - @Test - void willUseRestTemplateInServletWebApplicationIfUrlConnectionSenderAndWebClientNotAvailable() { - this.servletContextRunner.withUserConfiguration(RestTemplateConfiguration.class) - .withClassLoader(new FilteredClassLoader(URLConnectionSender.class, WebClient.class)) - .run((context) -> { - assertThat(context).doesNotHaveBean(URLConnectionSender.class); - assertThat(context).hasSingleBean(BytesMessageSender.class); - assertThat(context).hasSingleBean(ZipkinRestTemplateSender.class); - }); - } - - @Test - void willUseRestTemplateInReactiveWebApplicationIfUrlConnectionSenderAndWebClientAreNotAvailable() { - this.reactiveContextRunner.withUserConfiguration(RestTemplateConfiguration.class) - .withClassLoader(new FilteredClassLoader(URLConnectionSender.class, WebClient.class)) - .run((context) -> { - assertThat(context).doesNotHaveBean(URLConnectionSender.class); - assertThat(context).hasSingleBean(BytesMessageSender.class); - assertThat(context).hasSingleBean(ZipkinRestTemplateSender.class); - }); - } - - @Test - void shouldNotUseWebClientSenderIfNoBuilderIsAvailable() { - this.reactiveContextRunner.run((context) -> { - assertThat(context).doesNotHaveBean(ZipkinWebClientSender.class); - assertThat(context).hasSingleBean(BytesMessageSender.class); - assertThat(context).hasSingleBean(URLConnectionSender.class); - }); - } - @Test void shouldBackOffOnCustomBeans() { this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { @@ -170,71 +79,6 @@ void shouldBackOffOnCustomBeans() { }); } - @Test - void shouldApplyZipkinRestTemplateBuilderCustomizers() throws IOException { - try (MockWebServer mockWebServer = new MockWebServer()) { - mockWebServer.enqueue(new MockResponse().setResponseCode(204)); - this.reactiveContextRunner - .withPropertyValues("management.zipkin.tracing.endpoint=" + mockWebServer.url("/")) - .withUserConfiguration(RestTemplateConfiguration.class) - .withClassLoader(new FilteredClassLoader(URLConnectionSender.class, WebClient.class)) - .run((context) -> { - assertThat(context).hasSingleBean(ZipkinRestTemplateSender.class); - ZipkinRestTemplateSender sender = context.getBean(ZipkinRestTemplateSender.class); - sender.send(List.of("spans".getBytes(StandardCharsets.UTF_8))); - RecordedRequest recordedRequest = mockWebServer.takeRequest(1, TimeUnit.SECONDS); - assertThat(recordedRequest).isNotNull(); - assertThat(recordedRequest.getHeaders().get("x-dummy")).isEqualTo("dummy"); - }); - } - } - - @Test - void shouldUseCustomHttpEndpointSupplierFactory() { - this.contextRunner.withUserConfiguration(CustomHttpEndpointSupplierFactoryConfiguration.class) - .run((context) -> assertThat(context.getBean(URLConnectionSender.class)) - .extracting("delegate.endpointSupplier") - .isInstanceOf(CustomHttpEndpointSupplier.class)); - } - - @Test - void shouldUseCustomHttpEndpointSupplierFactoryWhenReactive() { - this.reactiveContextRunner.withUserConfiguration(WebClientConfiguration.class) - .withClassLoader(new FilteredClassLoader(URLConnectionSender.class)) - .withUserConfiguration(CustomHttpEndpointSupplierFactoryConfiguration.class) - .run((context) -> assertThat(context.getBean(ZipkinWebClientSender.class)).extracting("endpointSupplier") - .isInstanceOf(CustomHttpEndpointSupplier.class)); - } - - @Test - void shouldUseCustomHttpEndpointSupplierFactoryWhenRestTemplate() { - this.contextRunner.withUserConfiguration(RestTemplateConfiguration.class) - .withClassLoader(new FilteredClassLoader(URLConnectionSender.class, WebClient.class)) - .withUserConfiguration(CustomHttpEndpointSupplierFactoryConfiguration.class) - .run((context) -> assertThat(context.getBean(ZipkinRestTemplateSender.class)).extracting("endpointSupplier") - .isInstanceOf(CustomHttpEndpointSupplier.class)); - } - - @Configuration(proxyBeanMethods = false) - private static final class RestTemplateConfiguration { - - @Bean - ZipkinRestTemplateBuilderCustomizer zipkinRestTemplateBuilderCustomizer() { - return new DummyZipkinRestTemplateBuilderCustomizer(); - } - - } - - @Configuration(proxyBeanMethods = false) - private static final class WebClientConfiguration { - - @Bean - ZipkinWebClientBuilderCustomizer webClientBuilder() { - return mock(ZipkinWebClientBuilderCustomizer.class); - } - - } - @Configuration(proxyBeanMethods = false) private static final class HttpClientConfiguration { @@ -255,15 +99,6 @@ BytesMessageSender customSender() { } - private static final class DummyZipkinRestTemplateBuilderCustomizer implements ZipkinRestTemplateBuilderCustomizer { - - @Override - public RestTemplateBuilder customize(RestTemplateBuilder restTemplateBuilder) { - return restTemplateBuilder.defaultHeader("x-dummy", "dummy"); - } - - } - @Configuration(proxyBeanMethods = false) private static final class CustomHttpEndpointSupplierFactoryConfiguration {