Skip to content

Commit 1c991a7

Browse files
committed
Merge pull request #43085 from wickdynex
* pr/43085: Polish "Make ZipkinHttpClientSender the default BytesMessageSender' Make ZipkinHttpClientSender the default BytesMessageSender Closes gh-43085
2 parents e9abe34 + b051a74 commit 1c991a7

File tree

2 files changed

+83
-78
lines changed

2 files changed

+83
-78
lines changed

Diff for: spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java

+46-45
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -52,37 +52,60 @@
5252
*
5353
* @author Moritz Halbritter
5454
* @author Stefan Bratanov
55+
* @author Wick Dynex
5556
*/
5657
class ZipkinConfigurations {
5758

5859
@Configuration(proxyBeanMethods = false)
59-
@Import({ UrlConnectionSenderConfiguration.class, WebClientSenderConfiguration.class,
60-
RestTemplateSenderConfiguration.class, HttpClientSenderConfiguration.class })
60+
@Import({ HttpClientSenderConfiguration.class, WebClientSenderConfiguration.class,
61+
RestTemplateSenderConfiguration.class, UrlConnectionSenderConfiguration.class })
6162
static class SenderConfiguration {
6263

6364
}
6465

6566
@Configuration(proxyBeanMethods = false)
66-
@ConditionalOnClass(URLConnectionSender.class)
67+
@ConditionalOnClass(HttpClient.class)
6768
@EnableConfigurationProperties(ZipkinProperties.class)
68-
static class UrlConnectionSenderConfiguration {
69+
static class HttpClientSenderConfiguration {
6970

7071
@Bean
7172
@ConditionalOnMissingBean(BytesMessageSender.class)
72-
URLConnectionSender urlConnectionSender(ZipkinProperties properties, Encoding encoding,
73+
ZipkinHttpClientSender httpClientSender(ZipkinProperties properties, Encoding encoding,
74+
ObjectProvider<ZipkinHttpClientBuilderCustomizer> customizers,
7375
ObjectProvider<ZipkinConnectionDetails> connectionDetailsProvider,
7476
ObjectProvider<HttpEndpointSupplier.Factory> endpointSupplierFactoryProvider) {
7577
ZipkinConnectionDetails connectionDetails = connectionDetailsProvider
7678
.getIfAvailable(() -> new PropertiesZipkinConnectionDetails(properties));
7779
HttpEndpointSupplier.Factory endpointSupplierFactory = endpointSupplierFactoryProvider
7880
.getIfAvailable(HttpEndpointSuppliers::constantFactory);
79-
URLConnectionSender.Builder builder = URLConnectionSender.newBuilder();
80-
builder.connectTimeout((int) properties.getConnectTimeout().toMillis());
81-
builder.readTimeout((int) properties.getReadTimeout().toMillis());
82-
builder.endpointSupplierFactory(endpointSupplierFactory);
83-
builder.endpoint(connectionDetails.getSpanEndpoint());
84-
builder.encoding(encoding);
85-
return builder.build();
81+
Builder httpClientBuilder = HttpClient.newBuilder().connectTimeout(properties.getConnectTimeout());
82+
customizers.orderedStream().forEach((customizer) -> customizer.customize(httpClientBuilder));
83+
return new ZipkinHttpClientSender(encoding, endpointSupplierFactory, connectionDetails.getSpanEndpoint(),
84+
httpClientBuilder.build(), properties.getReadTimeout());
85+
}
86+
87+
}
88+
89+
@Configuration(proxyBeanMethods = false)
90+
@ConditionalOnClass(WebClient.class)
91+
@EnableConfigurationProperties(ZipkinProperties.class)
92+
static class WebClientSenderConfiguration {
93+
94+
@Bean
95+
@ConditionalOnMissingBean(BytesMessageSender.class)
96+
@SuppressWarnings({ "deprecation", "removal" })
97+
ZipkinWebClientSender webClientSender(ZipkinProperties properties, Encoding encoding,
98+
ObjectProvider<ZipkinWebClientBuilderCustomizer> customizers,
99+
ObjectProvider<ZipkinConnectionDetails> connectionDetailsProvider,
100+
ObjectProvider<HttpEndpointSupplier.Factory> endpointSupplierFactoryProvider) {
101+
ZipkinConnectionDetails connectionDetails = connectionDetailsProvider
102+
.getIfAvailable(() -> new PropertiesZipkinConnectionDetails(properties));
103+
HttpEndpointSupplier.Factory endpointSupplierFactory = endpointSupplierFactoryProvider
104+
.getIfAvailable(HttpEndpointSuppliers::constantFactory);
105+
WebClient.Builder builder = WebClient.builder();
106+
customizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
107+
return new ZipkinWebClientSender(encoding, endpointSupplierFactory, connectionDetails.getSpanEndpoint(),
108+
builder.build(), properties.getConnectTimeout().plus(properties.getReadTimeout()));
86109
}
87110

88111
}
@@ -126,48 +149,26 @@ private RestTemplateBuilder applyCustomizers(RestTemplateBuilder restTemplateBui
126149
}
127150

128151
@Configuration(proxyBeanMethods = false)
129-
@ConditionalOnClass(WebClient.class)
130-
@EnableConfigurationProperties(ZipkinProperties.class)
131-
static class WebClientSenderConfiguration {
132-
133-
@Bean
134-
@ConditionalOnMissingBean(BytesMessageSender.class)
135-
@SuppressWarnings({ "deprecation", "removal" })
136-
ZipkinWebClientSender webClientSender(ZipkinProperties properties, Encoding encoding,
137-
ObjectProvider<ZipkinWebClientBuilderCustomizer> customizers,
138-
ObjectProvider<ZipkinConnectionDetails> connectionDetailsProvider,
139-
ObjectProvider<HttpEndpointSupplier.Factory> endpointSupplierFactoryProvider) {
140-
ZipkinConnectionDetails connectionDetails = connectionDetailsProvider
141-
.getIfAvailable(() -> new PropertiesZipkinConnectionDetails(properties));
142-
HttpEndpointSupplier.Factory endpointSupplierFactory = endpointSupplierFactoryProvider
143-
.getIfAvailable(HttpEndpointSuppliers::constantFactory);
144-
WebClient.Builder builder = WebClient.builder();
145-
customizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
146-
return new ZipkinWebClientSender(encoding, endpointSupplierFactory, connectionDetails.getSpanEndpoint(),
147-
builder.build(), properties.getConnectTimeout().plus(properties.getReadTimeout()));
148-
}
149-
150-
}
151-
152-
@Configuration(proxyBeanMethods = false)
153-
@ConditionalOnClass(HttpClient.class)
152+
@ConditionalOnClass(URLConnectionSender.class)
154153
@EnableConfigurationProperties(ZipkinProperties.class)
155-
static class HttpClientSenderConfiguration {
154+
static class UrlConnectionSenderConfiguration {
156155

157156
@Bean
158157
@ConditionalOnMissingBean(BytesMessageSender.class)
159-
ZipkinHttpClientSender httpClientSender(ZipkinProperties properties, Encoding encoding,
160-
ObjectProvider<ZipkinHttpClientBuilderCustomizer> customizers,
158+
URLConnectionSender urlConnectionSender(ZipkinProperties properties, Encoding encoding,
161159
ObjectProvider<ZipkinConnectionDetails> connectionDetailsProvider,
162160
ObjectProvider<HttpEndpointSupplier.Factory> endpointSupplierFactoryProvider) {
163161
ZipkinConnectionDetails connectionDetails = connectionDetailsProvider
164162
.getIfAvailable(() -> new PropertiesZipkinConnectionDetails(properties));
165163
HttpEndpointSupplier.Factory endpointSupplierFactory = endpointSupplierFactoryProvider
166164
.getIfAvailable(HttpEndpointSuppliers::constantFactory);
167-
Builder httpClientBuilder = HttpClient.newBuilder().connectTimeout(properties.getConnectTimeout());
168-
customizers.orderedStream().forEach((customizer) -> customizer.customize(httpClientBuilder));
169-
return new ZipkinHttpClientSender(encoding, endpointSupplierFactory, connectionDetails.getSpanEndpoint(),
170-
httpClientBuilder.build(), properties.getReadTimeout());
165+
URLConnectionSender.Builder builder = URLConnectionSender.newBuilder();
166+
builder.connectTimeout((int) properties.getConnectTimeout().toMillis());
167+
builder.readTimeout((int) properties.getReadTimeout().toMillis());
168+
builder.endpointSupplierFactory(endpointSupplierFactory);
169+
builder.endpoint(connectionDetails.getSpanEndpoint());
170+
builder.encoding(encoding);
171+
return builder.build();
171172
}
172173

173174
}

Diff for: spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsSenderConfigurationTests.java

+37-33
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
1717
package org.springframework.boot.actuate.autoconfigure.tracing.zipkin;
1818

1919
import java.io.IOException;
20+
import java.net.http.HttpClient;
2021
import java.nio.charset.StandardCharsets;
2122
import java.util.List;
2223
import java.util.concurrent.TimeUnit;
@@ -31,6 +32,7 @@
3132
import zipkin2.reporter.urlconnection.URLConnectionSender;
3233

3334
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.SenderConfiguration;
35+
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.UrlConnectionSenderConfiguration;
3436
import org.springframework.boot.autoconfigure.AutoConfigurations;
3537
import org.springframework.boot.test.context.FilteredClassLoader;
3638
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@@ -39,6 +41,7 @@
3941
import org.springframework.boot.web.client.RestTemplateBuilder;
4042
import org.springframework.context.annotation.Bean;
4143
import org.springframework.context.annotation.Configuration;
44+
import org.springframework.web.client.RestTemplate;
4245
import org.springframework.web.reactive.function.client.WebClient;
4346

4447
import static org.assertj.core.api.Assertions.assertThat;
@@ -49,6 +52,7 @@
4952
* Tests for {@link SenderConfiguration}.
5053
*
5154
* @author Moritz Halbritter
55+
* @author Wick Dynex
5256
*/
5357
@SuppressWarnings({ "deprecation", "removal" })
5458
class ZipkinConfigurationsSenderConfigurationTests {
@@ -63,34 +67,33 @@ class ZipkinConfigurationsSenderConfigurationTests {
6367
.withConfiguration(AutoConfigurations.of(DefaultEncodingConfiguration.class, SenderConfiguration.class));
6468

6569
@Test
66-
void shouldSupplyBeans() {
70+
void shouldSupplyDefaultHttpClientSenderBeans() {
6771
this.contextRunner.run((context) -> {
6872
assertThat(context).hasSingleBean(BytesMessageSender.class);
69-
assertThat(context).hasSingleBean(URLConnectionSender.class);
73+
assertThat(context).hasSingleBean(ZipkinHttpClientSender.class);
7074
assertThat(context).doesNotHaveBean(ZipkinRestTemplateSender.class);
75+
assertThat(context).doesNotHaveBean(ZipkinWebClientSenderTests.class);
76+
assertThat(context).doesNotHaveBean(URLConnectionSender.class);
7177
});
7278
}
7379

7480
@Test
75-
void shouldUseHttpClientIfUrlSenderIsNotAvailable() {
76-
this.contextRunner.withUserConfiguration(HttpClientConfiguration.class)
77-
.withClassLoader(new FilteredClassLoader("zipkin2.reporter.urlconnection", "org.springframework.web.client",
78-
"org.springframework.web.reactive.function.client"))
81+
void shouldUseUrlSenderIfHttpSenderIsNotAvailable() {
82+
this.contextRunner.withUserConfiguration(UrlConnectionSenderConfiguration.class)
83+
.withClassLoader(new FilteredClassLoader(HttpClient.class, WebClient.class, RestTemplate.class))
7984
.run((context) -> {
80-
assertThat(context).doesNotHaveBean(URLConnectionSender.class);
85+
assertThat(context).doesNotHaveBean(ZipkinHttpClientSender.class);
8186
assertThat(context).hasSingleBean(BytesMessageSender.class);
82-
assertThat(context).hasSingleBean(ZipkinHttpClientSender.class);
83-
then(context.getBean(ZipkinHttpClientBuilderCustomizer.class)).should()
84-
.customize(ArgumentMatchers.any());
87+
assertThat(context).hasSingleBean(URLConnectionSender.class);
8588
});
8689
}
8790

8891
@Test
89-
void shouldPreferWebClientSenderIfWebApplicationIsReactiveAndUrlSenderIsNotAvailable() {
92+
void shouldPreferWebClientSenderIfWebApplicationIsReactiveAndHttpClientSenderIsNotAvailable() {
9093
this.reactiveContextRunner.withUserConfiguration(RestTemplateConfiguration.class, WebClientConfiguration.class)
91-
.withClassLoader(new FilteredClassLoader("zipkin2.reporter.urlconnection"))
94+
.withClassLoader(new FilteredClassLoader(HttpClient.class))
9295
.run((context) -> {
93-
assertThat(context).doesNotHaveBean(URLConnectionSender.class);
96+
assertThat(context).doesNotHaveBean(ZipkinHttpClientSender.class);
9497
assertThat(context).hasSingleBean(BytesMessageSender.class);
9598
assertThat(context).hasSingleBean(ZipkinWebClientSender.class);
9699
then(context.getBean(ZipkinWebClientBuilderCustomizer.class)).should()
@@ -99,55 +102,55 @@ void shouldPreferWebClientSenderIfWebApplicationIsReactiveAndUrlSenderIsNotAvail
99102
}
100103

101104
@Test
102-
void shouldPreferWebClientSenderIfWebApplicationIsServletAndUrlSenderIsNotAvailable() {
105+
void shouldPreferWebClientSenderIfWebApplicationIsServletAndHttpClientSenderIsNotAvailable() {
103106
this.servletContextRunner.withUserConfiguration(RestTemplateConfiguration.class, WebClientConfiguration.class)
104-
.withClassLoader(new FilteredClassLoader("zipkin2.reporter.urlconnection"))
107+
.withClassLoader(new FilteredClassLoader(HttpClient.class))
105108
.run((context) -> {
106-
assertThat(context).doesNotHaveBean(URLConnectionSender.class);
109+
assertThat(context).doesNotHaveBean(ZipkinHttpClientSender.class);
107110
assertThat(context).hasSingleBean(BytesMessageSender.class);
108111
assertThat(context).hasSingleBean(ZipkinWebClientSender.class);
109112
});
110113
}
111114

112115
@Test
113-
void shouldPreferWebClientInNonWebApplicationAndUrlConnectionSenderIsNotAvailable() {
116+
void shouldPreferWebClientInNonWebApplicationAndHttpClientSenderIsNotAvailable() {
114117
this.contextRunner.withUserConfiguration(RestTemplateConfiguration.class, WebClientConfiguration.class)
115-
.withClassLoader(new FilteredClassLoader("zipkin2.reporter.urlconnection"))
118+
.withClassLoader(new FilteredClassLoader(HttpClient.class))
116119
.run((context) -> {
117-
assertThat(context).doesNotHaveBean(URLConnectionSender.class);
120+
assertThat(context).doesNotHaveBean(ZipkinHttpClientSender.class);
118121
assertThat(context).hasSingleBean(BytesMessageSender.class);
119122
assertThat(context).hasSingleBean(ZipkinWebClientSender.class);
120123
});
121124
}
122125

123126
@Test
124-
void willUseRestTemplateInNonWebApplicationIfUrlConnectionSenderAndWebClientAreNotAvailable() {
127+
void willUseRestTemplateInNonWebApplicationIfSenderAndWebClientAreNotAvailable() {
125128
this.contextRunner.withUserConfiguration(RestTemplateConfiguration.class)
126-
.withClassLoader(new FilteredClassLoader(URLConnectionSender.class, WebClient.class))
129+
.withClassLoader(new FilteredClassLoader(HttpClient.class, WebClient.class))
127130
.run((context) -> {
128-
assertThat(context).doesNotHaveBean(URLConnectionSender.class);
131+
assertThat(context).doesNotHaveBean(HttpClient.class);
129132
assertThat(context).hasSingleBean(BytesMessageSender.class);
130133
assertThat(context).hasSingleBean(ZipkinRestTemplateSender.class);
131134
});
132135
}
133136

134137
@Test
135-
void willUseRestTemplateInServletWebApplicationIfUrlConnectionSenderAndWebClientNotAvailable() {
138+
void willUseRestTemplateInServletWebApplicationIfHttpClientSenderAndWebClientNotAvailable() {
136139
this.servletContextRunner.withUserConfiguration(RestTemplateConfiguration.class)
137-
.withClassLoader(new FilteredClassLoader(URLConnectionSender.class, WebClient.class))
140+
.withClassLoader(new FilteredClassLoader(HttpClient.class, WebClient.class))
138141
.run((context) -> {
139-
assertThat(context).doesNotHaveBean(URLConnectionSender.class);
142+
assertThat(context).doesNotHaveBean(ZipkinHttpClientSender.class);
140143
assertThat(context).hasSingleBean(BytesMessageSender.class);
141144
assertThat(context).hasSingleBean(ZipkinRestTemplateSender.class);
142145
});
143146
}
144147

145148
@Test
146-
void willUseRestTemplateInReactiveWebApplicationIfUrlConnectionSenderAndWebClientAreNotAvailable() {
149+
void willUseRestTemplateInReactiveWebApplicationIfHttpClientSenderAndWebClientAreNotAvailable() {
147150
this.reactiveContextRunner.withUserConfiguration(RestTemplateConfiguration.class)
148-
.withClassLoader(new FilteredClassLoader(URLConnectionSender.class, WebClient.class))
151+
.withClassLoader(new FilteredClassLoader(HttpClient.class, WebClient.class))
149152
.run((context) -> {
150-
assertThat(context).doesNotHaveBean(URLConnectionSender.class);
153+
assertThat(context).doesNotHaveBean(ZipkinHttpClientSender.class);
151154
assertThat(context).hasSingleBean(BytesMessageSender.class);
152155
assertThat(context).hasSingleBean(ZipkinRestTemplateSender.class);
153156
});
@@ -158,7 +161,7 @@ void shouldNotUseWebClientSenderIfNoBuilderIsAvailable() {
158161
this.reactiveContextRunner.run((context) -> {
159162
assertThat(context).doesNotHaveBean(ZipkinWebClientSender.class);
160163
assertThat(context).hasSingleBean(BytesMessageSender.class);
161-
assertThat(context).hasSingleBean(URLConnectionSender.class);
164+
assertThat(context).hasSingleBean(ZipkinHttpClientSender.class);
162165
});
163166
}
164167

@@ -177,7 +180,7 @@ void shouldApplyZipkinRestTemplateBuilderCustomizers() throws IOException {
177180
this.reactiveContextRunner
178181
.withPropertyValues("management.zipkin.tracing.endpoint=" + mockWebServer.url("/"))
179182
.withUserConfiguration(RestTemplateConfiguration.class)
180-
.withClassLoader(new FilteredClassLoader(URLConnectionSender.class, WebClient.class))
183+
.withClassLoader(new FilteredClassLoader(HttpClient.class, WebClient.class))
181184
.run((context) -> {
182185
assertThat(context).hasSingleBean(ZipkinRestTemplateSender.class);
183186
ZipkinRestTemplateSender sender = context.getBean(ZipkinRestTemplateSender.class);
@@ -192,6 +195,7 @@ void shouldApplyZipkinRestTemplateBuilderCustomizers() throws IOException {
192195
@Test
193196
void shouldUseCustomHttpEndpointSupplierFactory() {
194197
this.contextRunner.withUserConfiguration(CustomHttpEndpointSupplierFactoryConfiguration.class)
198+
.withClassLoader(new FilteredClassLoader(HttpClient.class, WebClient.class, RestTemplate.class))
195199
.run((context) -> assertThat(context.getBean(URLConnectionSender.class))
196200
.extracting("delegate.endpointSupplier")
197201
.isInstanceOf(CustomHttpEndpointSupplier.class));
@@ -201,7 +205,7 @@ void shouldUseCustomHttpEndpointSupplierFactory() {
201205
@SuppressWarnings("resource")
202206
void shouldUseCustomHttpEndpointSupplierFactoryWhenReactive() {
203207
this.reactiveContextRunner.withUserConfiguration(WebClientConfiguration.class)
204-
.withClassLoader(new FilteredClassLoader(URLConnectionSender.class))
208+
.withClassLoader(new FilteredClassLoader(HttpClient.class))
205209
.withUserConfiguration(CustomHttpEndpointSupplierFactoryConfiguration.class)
206210
.run((context) -> assertThat(context.getBean(ZipkinWebClientSender.class)).extracting("endpointSupplier")
207211
.isInstanceOf(CustomHttpEndpointSupplier.class));
@@ -211,7 +215,7 @@ void shouldUseCustomHttpEndpointSupplierFactoryWhenReactive() {
211215
@SuppressWarnings("resource")
212216
void shouldUseCustomHttpEndpointSupplierFactoryWhenRestTemplate() {
213217
this.contextRunner.withUserConfiguration(RestTemplateConfiguration.class)
214-
.withClassLoader(new FilteredClassLoader(URLConnectionSender.class, WebClient.class))
218+
.withClassLoader(new FilteredClassLoader(HttpClient.class, WebClient.class))
215219
.withUserConfiguration(CustomHttpEndpointSupplierFactoryConfiguration.class)
216220
.run((context) -> assertThat(context.getBean(ZipkinRestTemplateSender.class)).extracting("endpointSupplier")
217221
.isInstanceOf(CustomHttpEndpointSupplier.class));

0 commit comments

Comments
 (0)