Skip to content

Commit 013e148

Browse files
committedFeb 20, 2024
Implement JDK HttpClient based Zipkin sender
Closes gh-39545
1 parent 52648d9 commit 013e148

File tree

12 files changed

+392
-10
lines changed

12 files changed

+392
-10
lines changed
 

‎spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/HttpSender.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -74,7 +74,7 @@ protected void postSpans(URI endpoint, byte[] body) throws IOException {
7474
* @param headers headers for the POST request
7575
* @param body list of possibly gzipped, encoded spans.
7676
*/
77-
abstract void postSpans(URI endpoint, HttpHeaders headers, byte[] body);
77+
abstract void postSpans(URI endpoint, HttpHeaders headers, byte[] body) throws IOException;
7878

7979
HttpHeaders getDefaultHeaders() {
8080
HttpHeaders headers = new HttpHeaders();

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

+31-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -16,6 +16,9 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.tracing.zipkin;
1818

19+
import java.net.http.HttpClient;
20+
import java.net.http.HttpClient.Builder;
21+
1922
import brave.Tag;
2023
import brave.Tags;
2124
import brave.handler.MutableSpan;
@@ -53,7 +56,7 @@ class ZipkinConfigurations {
5356

5457
@Configuration(proxyBeanMethods = false)
5558
@Import({ UrlConnectionSenderConfiguration.class, WebClientSenderConfiguration.class,
56-
RestTemplateSenderConfiguration.class })
59+
RestTemplateSenderConfiguration.class, HttpClientSenderConfiguration.class })
5760
static class SenderConfiguration {
5861

5962
}
@@ -90,6 +93,7 @@ static class RestTemplateSenderConfiguration {
9093

9194
@Bean
9295
@ConditionalOnMissingBean(BytesMessageSender.class)
96+
@SuppressWarnings("removal")
9397
ZipkinRestTemplateSender restTemplateSender(ZipkinProperties properties, Encoding encoding,
9498
ObjectProvider<ZipkinRestTemplateBuilderCustomizer> customizers,
9599
ObjectProvider<ZipkinConnectionDetails> connectionDetailsProvider,
@@ -106,6 +110,7 @@ ZipkinRestTemplateSender restTemplateSender(ZipkinProperties properties, Encodin
106110
restTemplateBuilder.build());
107111
}
108112

113+
@SuppressWarnings("removal")
109114
private RestTemplateBuilder applyCustomizers(RestTemplateBuilder restTemplateBuilder,
110115
ObjectProvider<ZipkinRestTemplateBuilderCustomizer> customizers) {
111116
Iterable<ZipkinRestTemplateBuilderCustomizer> orderedCustomizers = () -> customizers.orderedStream()
@@ -126,6 +131,7 @@ static class WebClientSenderConfiguration {
126131

127132
@Bean
128133
@ConditionalOnMissingBean(BytesMessageSender.class)
134+
@SuppressWarnings("removal")
129135
ZipkinWebClientSender webClientSender(ZipkinProperties properties, Encoding encoding,
130136
ObjectProvider<ZipkinWebClientBuilderCustomizer> customizers,
131137
ObjectProvider<ZipkinConnectionDetails> connectionDetailsProvider,
@@ -142,6 +148,29 @@ ZipkinWebClientSender webClientSender(ZipkinProperties properties, Encoding enco
142148

143149
}
144150

151+
@Configuration(proxyBeanMethods = false)
152+
@ConditionalOnClass(HttpClient.class)
153+
@EnableConfigurationProperties(ZipkinProperties.class)
154+
static class HttpClientSenderConfiguration {
155+
156+
@Bean
157+
@ConditionalOnMissingBean(BytesMessageSender.class)
158+
ZipkinHttpClientSender httpClientSender(ZipkinProperties properties, Encoding encoding,
159+
ObjectProvider<ZipkinHttpClientBuilderCustomizer> customizers,
160+
ObjectProvider<ZipkinConnectionDetails> connectionDetailsProvider,
161+
ObjectProvider<HttpEndpointSupplier.Factory> endpointSupplierFactoryProvider) {
162+
ZipkinConnectionDetails connectionDetails = connectionDetailsProvider
163+
.getIfAvailable(() -> new PropertiesZipkinConnectionDetails(properties));
164+
HttpEndpointSupplier.Factory endpointSupplierFactory = endpointSupplierFactoryProvider
165+
.getIfAvailable(HttpEndpointSuppliers::constantFactory);
166+
Builder httpClientBuilder = HttpClient.newBuilder().connectTimeout(properties.getConnectTimeout());
167+
customizers.orderedStream().forEach((customizer) -> customizer.customize(httpClientBuilder));
168+
return new ZipkinHttpClientSender(encoding, endpointSupplierFactory, connectionDetails.getSpanEndpoint(),
169+
httpClientBuilder.build(), properties.getReadTimeout());
170+
}
171+
172+
}
173+
145174
@Configuration(proxyBeanMethods = false)
146175
@ConditionalOnClass(AsyncZipkinSpanHandler.class)
147176
static class BraveConfiguration {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2012-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.autoconfigure.tracing.zipkin;
18+
19+
import java.net.http.HttpClient;
20+
21+
/**
22+
* Callback interface that can be implemented by beans wishing to customize the
23+
* {@link HttpClient.Builder} used to send spans to Zipkin.
24+
*
25+
* @author Moritz Halbritter
26+
* @since 3.3.0
27+
*/
28+
@FunctionalInterface
29+
public interface ZipkinHttpClientBuilderCustomizer {
30+
31+
/**
32+
* Customize the http client builder.
33+
* @param httpClient the http client builder to customize
34+
*/
35+
void customize(HttpClient.Builder httpClient);
36+
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2012-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.autoconfigure.tracing.zipkin;
18+
19+
import java.io.IOException;
20+
import java.net.URI;
21+
import java.net.http.HttpClient;
22+
import java.net.http.HttpRequest;
23+
import java.net.http.HttpRequest.BodyPublishers;
24+
import java.net.http.HttpRequest.Builder;
25+
import java.net.http.HttpResponse;
26+
import java.net.http.HttpResponse.BodyHandlers;
27+
import java.time.Duration;
28+
29+
import zipkin2.reporter.Encoding;
30+
import zipkin2.reporter.HttpEndpointSupplier.Factory;
31+
32+
import org.springframework.http.HttpHeaders;
33+
34+
/**
35+
* A {@link HttpSender} which uses the JDK {@link HttpClient} for HTTP communication.
36+
*
37+
* @author Moritz Halbritter
38+
*/
39+
class ZipkinHttpClientSender extends HttpSender {
40+
41+
private final HttpClient httpClient;
42+
43+
private final Duration readTimeout;
44+
45+
ZipkinHttpClientSender(Encoding encoding, Factory endpointSupplierFactory, String endpoint, HttpClient httpClient,
46+
Duration readTimeout) {
47+
super(encoding, endpointSupplierFactory, endpoint);
48+
this.httpClient = httpClient;
49+
this.readTimeout = readTimeout;
50+
}
51+
52+
@Override
53+
void postSpans(URI endpoint, HttpHeaders headers, byte[] body) throws IOException {
54+
Builder request = HttpRequest.newBuilder()
55+
.POST(BodyPublishers.ofByteArray(body))
56+
.uri(endpoint)
57+
.timeout(this.readTimeout);
58+
headers.forEach((key, values) -> values.forEach((value) -> request.header(key, value)));
59+
try {
60+
HttpResponse<Void> response = this.httpClient.send(request.build(), BodyHandlers.discarding());
61+
if (response.statusCode() / 100 != 2) {
62+
throw new IOException("Expected HTTP status 2xx, got %d".formatted(response.statusCode()));
63+
}
64+
}
65+
catch (InterruptedException ex) {
66+
Thread.currentThread().interrupt();
67+
throw new IOException("Got interrupted while sending spans", ex);
68+
}
69+
}
70+
71+
}

‎spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateBuilderCustomizer.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -24,8 +24,11 @@
2424
*
2525
* @author Marcin Grzejszczak
2626
* @since 3.0.0
27+
* @deprecated since 3.3.0 for removal in 3.5.0 in favor of
28+
* {@link ZipkinHttpClientBuilderCustomizer}
2729
*/
2830
@FunctionalInterface
31+
@Deprecated(since = "3.3.0", forRemoval = true)
2932
public interface ZipkinRestTemplateBuilderCustomizer {
3033

3134
/**

‎spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSender.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -32,6 +32,7 @@
3232
* @author Moritz Halbritter
3333
* @author Stefan Bratanov
3434
*/
35+
@Deprecated(since = "3.3.0", forRemoval = true)
3536
class ZipkinRestTemplateSender extends HttpSender {
3637

3738
private final RestTemplate restTemplate;

‎spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinWebClientBuilderCustomizer.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -25,8 +25,11 @@
2525
*
2626
* @author Marcin Grzejszczak
2727
* @since 3.0.0
28+
* @deprecated since 3.3.0 for removal in 3.5.0 in favor of
29+
* {@link ZipkinHttpClientBuilderCustomizer}
2830
*/
2931
@FunctionalInterface
32+
@Deprecated(since = "3.3.0", forRemoval = true)
3033
public interface ZipkinWebClientBuilderCustomizer {
3134

3235
/**

‎spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinWebClientSender.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -31,6 +31,7 @@
3131
* @author Stefan Bratanov
3232
* @author Moritz Halbritter
3333
*/
34+
@Deprecated(since = "3.3.0", forRemoval = true)
3435
class ZipkinWebClientSender extends HttpSender {
3536

3637
private final WebClient webClient;

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

+25
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
*
5151
* @author Moritz Halbritter
5252
*/
53+
@SuppressWarnings("removal")
5354
class ZipkinConfigurationsSenderConfigurationTests {
5455

5556
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
@@ -70,6 +71,20 @@ void shouldSupplyBeans() {
7071
});
7172
}
7273

74+
@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"))
79+
.run((context) -> {
80+
assertThat(context).doesNotHaveBean(URLConnectionSender.class);
81+
assertThat(context).hasSingleBean(BytesMessageSender.class);
82+
assertThat(context).hasSingleBean(ZipkinHttpClientSender.class);
83+
then(context.getBean(ZipkinHttpClientBuilderCustomizer.class)).should()
84+
.customize(ArgumentMatchers.any());
85+
});
86+
}
87+
7388
@Test
7489
void shouldPreferWebClientSenderIfWebApplicationIsReactiveAndUrlSenderIsNotAvailable() {
7590
this.reactiveContextRunner.withUserConfiguration(RestTemplateConfiguration.class, WebClientConfiguration.class)
@@ -220,6 +235,16 @@ ZipkinWebClientBuilderCustomizer webClientBuilder() {
220235

221236
}
222237

238+
@Configuration(proxyBeanMethods = false)
239+
private static final class HttpClientConfiguration {
240+
241+
@Bean
242+
ZipkinHttpClientBuilderCustomizer httpClientBuilderCustomizer() {
243+
return mock(ZipkinHttpClientBuilderCustomizer.class);
244+
}
245+
246+
}
247+
223248
@Configuration(proxyBeanMethods = false)
224249
private static final class CustomConfiguration {
225250

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
/*
2+
* Copyright 2012-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.autoconfigure.tracing.zipkin;
18+
19+
import java.io.IOException;
20+
import java.net.URI;
21+
import java.net.http.HttpClient;
22+
import java.time.Duration;
23+
import java.util.Base64;
24+
import java.util.Collections;
25+
import java.util.List;
26+
import java.util.concurrent.TimeUnit;
27+
import java.util.concurrent.atomic.AtomicInteger;
28+
import java.util.function.Consumer;
29+
30+
import okhttp3.mockwebserver.MockResponse;
31+
import okhttp3.mockwebserver.MockWebServer;
32+
import okhttp3.mockwebserver.QueueDispatcher;
33+
import okhttp3.mockwebserver.RecordedRequest;
34+
import org.junit.jupiter.api.AfterAll;
35+
import org.junit.jupiter.api.BeforeAll;
36+
import org.junit.jupiter.api.BeforeEach;
37+
import org.junit.jupiter.api.Test;
38+
import zipkin2.reporter.BytesMessageSender;
39+
import zipkin2.reporter.Encoding;
40+
import zipkin2.reporter.HttpEndpointSupplier;
41+
import zipkin2.reporter.HttpEndpointSuppliers;
42+
43+
import org.springframework.http.HttpHeaders;
44+
45+
import static org.assertj.core.api.Assertions.assertThat;
46+
import static org.assertj.core.api.Assertions.assertThatException;
47+
import static org.assertj.core.api.Assertions.assertThatIOException;
48+
49+
/**
50+
* Tests for {@link ZipkinHttpClientSender}.
51+
*
52+
* @author Moritz Halbritter
53+
*/
54+
class ZipkinHttpClientSenderTests extends ZipkinHttpSenderTests {
55+
56+
private static ClearableDispatcher dispatcher;
57+
58+
private static MockWebServer mockBackEnd;
59+
60+
private static String zipkinUrl;
61+
62+
@BeforeAll
63+
static void beforeAll() throws IOException {
64+
dispatcher = new ClearableDispatcher();
65+
mockBackEnd = new MockWebServer();
66+
mockBackEnd.setDispatcher(dispatcher);
67+
mockBackEnd.start();
68+
zipkinUrl = mockBackEnd.url("/api/v2/spans").toString();
69+
}
70+
71+
@AfterAll
72+
static void afterAll() throws IOException {
73+
mockBackEnd.shutdown();
74+
}
75+
76+
@Override
77+
@BeforeEach
78+
void beforeEach() throws Exception {
79+
super.beforeEach();
80+
clearResponses();
81+
clearRequests();
82+
}
83+
84+
@Override
85+
BytesMessageSender createSender() {
86+
return createSender(Encoding.JSON, Duration.ofSeconds(10));
87+
}
88+
89+
ZipkinHttpClientSender createSender(Encoding encoding, Duration timeout) {
90+
return createSender(HttpEndpointSuppliers.constantFactory(), encoding, timeout);
91+
}
92+
93+
ZipkinHttpClientSender createSender(HttpEndpointSupplier.Factory endpointSupplierFactory, Encoding encoding,
94+
Duration timeout) {
95+
HttpClient httpClient = HttpClient.newBuilder().connectTimeout(timeout).build();
96+
return new ZipkinHttpClientSender(encoding, endpointSupplierFactory, zipkinUrl, httpClient, timeout);
97+
}
98+
99+
@Test
100+
void sendShouldSendSpansToZipkin() throws IOException, InterruptedException {
101+
mockBackEnd.enqueue(new MockResponse());
102+
List<byte[]> encodedSpans = List.of(toByteArray("span1"), toByteArray("span2"));
103+
this.sender.send(encodedSpans);
104+
requestAssertions((request) -> {
105+
assertThat(request.getMethod()).isEqualTo("POST");
106+
assertThat(request.getHeader("Content-Type")).isEqualTo("application/json");
107+
assertThat(request.getBody().readUtf8()).isEqualTo("[span1,span2]");
108+
});
109+
}
110+
111+
@Test
112+
void sendShouldSendSpansToZipkinInProto3() throws IOException, InterruptedException {
113+
mockBackEnd.enqueue(new MockResponse());
114+
List<byte[]> encodedSpans = List.of(toByteArray("span1"), toByteArray("span2"));
115+
try (BytesMessageSender sender = createSender(Encoding.PROTO3, Duration.ofSeconds(10))) {
116+
sender.send(encodedSpans);
117+
}
118+
requestAssertions((request) -> {
119+
assertThat(request.getMethod()).isEqualTo("POST");
120+
assertThat(request.getHeader("Content-Type")).isEqualTo("application/x-protobuf");
121+
assertThat(request.getBody().readUtf8()).isEqualTo("span1span2");
122+
});
123+
}
124+
125+
/**
126+
* This tests that a dynamic {@linkplain HttpEndpointSupplier} updates are visible to
127+
* {@link HttpSender#postSpans(URI, HttpHeaders, byte[])}.
128+
*/
129+
@Test
130+
void sendUsesDynamicEndpoint() throws Exception {
131+
mockBackEnd.enqueue(new MockResponse());
132+
mockBackEnd.enqueue(new MockResponse());
133+
AtomicInteger suffix = new AtomicInteger();
134+
try (BytesMessageSender sender = createSender((e) -> new HttpEndpointSupplier() {
135+
@Override
136+
public String get() {
137+
return zipkinUrl + "/" + suffix.incrementAndGet();
138+
}
139+
140+
@Override
141+
public void close() {
142+
}
143+
}, Encoding.JSON, Duration.ofSeconds(10))) {
144+
sender.send(Collections.emptyList());
145+
sender.send(Collections.emptyList());
146+
}
147+
assertThat(mockBackEnd.takeRequest().getPath()).endsWith("/1");
148+
assertThat(mockBackEnd.takeRequest().getPath()).endsWith("/2");
149+
}
150+
151+
@Test
152+
void sendShouldHandleHttpFailures() throws InterruptedException {
153+
mockBackEnd.enqueue(new MockResponse().setResponseCode(500));
154+
assertThatException().isThrownBy(() -> this.sender.send(Collections.emptyList()))
155+
.withMessageContaining("Expected HTTP status 2xx, got 500");
156+
requestAssertions((request) -> assertThat(request.getMethod()).isEqualTo("POST"));
157+
}
158+
159+
@Test
160+
void sendShouldCompressData() throws IOException, InterruptedException {
161+
String uncompressed = "a".repeat(10000);
162+
// This is gzip compressed 10000 times 'a'
163+
byte[] compressed = Base64.getDecoder()
164+
.decode("H4sIAAAAAAAA/+3BMQ0AAAwDIKFLj/k3UR8NcA8AAAAAAAAAAAADUsAZfeASJwAA");
165+
mockBackEnd.enqueue(new MockResponse());
166+
this.sender.send(List.of(toByteArray(uncompressed)));
167+
requestAssertions((request) -> {
168+
assertThat(request.getMethod()).isEqualTo("POST");
169+
assertThat(request.getHeader("Content-Type")).isEqualTo("application/json");
170+
assertThat(request.getHeader("Content-Encoding")).isEqualTo("gzip");
171+
assertThat(request.getBody().readByteArray()).isEqualTo(compressed);
172+
});
173+
}
174+
175+
@Test
176+
void shouldTimeout() throws IOException {
177+
try (BytesMessageSender sender = createSender(Encoding.JSON, Duration.ofMillis(1))) {
178+
MockResponse response = new MockResponse().setResponseCode(200).setHeadersDelay(100, TimeUnit.MILLISECONDS);
179+
mockBackEnd.enqueue(response);
180+
assertThatIOException().isThrownBy(() -> sender.send(Collections.emptyList()))
181+
.withMessageContaining("timed out");
182+
}
183+
}
184+
185+
private void requestAssertions(Consumer<RecordedRequest> assertions) throws InterruptedException {
186+
RecordedRequest request = mockBackEnd.takeRequest();
187+
assertThat(request).satisfies(assertions);
188+
}
189+
190+
private static void clearRequests() throws InterruptedException {
191+
RecordedRequest request;
192+
do {
193+
request = mockBackEnd.takeRequest(0, TimeUnit.SECONDS);
194+
}
195+
while (request != null);
196+
}
197+
198+
private static void clearResponses() {
199+
dispatcher.clear();
200+
}
201+
202+
private static final class ClearableDispatcher extends QueueDispatcher {
203+
204+
void clear() {
205+
getResponseQueue().clear();
206+
}
207+
208+
}
209+
210+
}

‎spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSenderTests.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -49,6 +49,7 @@
4949
* @author Moritz Halbritter
5050
* @author Stefan Bratanov
5151
*/
52+
@SuppressWarnings("removal")
5253
class ZipkinRestTemplateSenderTests extends ZipkinHttpSenderTests {
5354

5455
private static final String ZIPKIN_URL = "http://localhost:9411/api/v2/spans";

‎spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinWebClientSenderTests.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -51,6 +51,7 @@
5151
*
5252
* @author Stefan Bratanov
5353
*/
54+
@SuppressWarnings("removal")
5455
class ZipkinWebClientSenderTests extends ZipkinHttpSenderTests {
5556

5657
private static ClearableDispatcher dispatcher;

0 commit comments

Comments
 (0)
Please sign in to comment.