优化
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
package com.baiyue.common.web;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.MDC;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class OutboundTraceHeadersTest {
|
||||
|
||||
@AfterEach
|
||||
void clearMdc() {
|
||||
MDC.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
void currentContextCreatesAValidChildWithoutUsingBusinessValues() {
|
||||
MDC.put(CorrelationContext.REQUEST_ID, "req-trusted");
|
||||
MDC.put(CorrelationContext.TRACE_ID, "4bf92f3577b34da6a3ce929d0e0e4736");
|
||||
|
||||
OutboundTraceHeaders headers = OutboundTraceHeaders.fromCurrentOrNew();
|
||||
|
||||
assertThat(headers.requestId()).isEqualTo("req-trusted");
|
||||
assertThat(headers.traceId()).isEqualTo("4bf92f3577b34da6a3ce929d0e0e4736");
|
||||
assertThat(headers.traceParent())
|
||||
.matches("00-4bf92f3577b34da6a3ce929d0e0e4736-[0-9a-f]{16}-01");
|
||||
}
|
||||
|
||||
@Test
|
||||
void canonicalPersistedUuidIsCompactedAndInvalidValueStartsNewTrace() {
|
||||
OutboundTraceHeaders uuid = OutboundTraceHeaders.fromTrustedTraceOrNew(
|
||||
"550e8400-e29b-41d4-a716-446655440000");
|
||||
OutboundTraceHeaders invalid = OutboundTraceHeaders.fromTrustedTraceOrNew(
|
||||
"ORDER:customer-99:booking-123");
|
||||
|
||||
assertThat(uuid.traceId()).isEqualTo("550e8400e29b41d4a716446655440000");
|
||||
assertThat(invalid.traceId()).matches("[0-9a-f]{32}")
|
||||
.isNotEqualTo("ORDER:customer-99:booking-123");
|
||||
assertThat(invalid.requestId()).matches("[0-9a-f-]{36}");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.baiyue.common.web;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.mock.http.client.MockClientHttpRequest;
|
||||
import org.springframework.mock.http.client.MockClientHttpResponse;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class RestClientTraceInterceptorTest {
|
||||
private final RestClientTraceInterceptor interceptor = new RestClientTraceInterceptor();
|
||||
|
||||
@AfterEach
|
||||
void clearMdc() {
|
||||
MDC.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
void trustedContextOverwritesAllCallerProvidedTraceHeaders() throws Exception {
|
||||
MDC.put(CorrelationContext.REQUEST_ID, "req-rest-client");
|
||||
MDC.put(CorrelationContext.TRACE_ID, "4bf92f3577b34da6a3ce929d0e0e4736");
|
||||
MockClientHttpRequest request = new MockClientHttpRequest();
|
||||
request.getHeaders().add(CorrelationContext.REQUEST_ID_HEADER, "business-request-id");
|
||||
request.getHeaders().add(CorrelationContext.TRACE_ID_HEADER, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
request.getHeaders().add(CorrelationContext.TRACE_PARENT_HEADER,
|
||||
"00-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bbbbbbbbbbbbbbbb-00");
|
||||
AtomicReference<org.springframework.http.HttpHeaders> captured = new AtomicReference<>();
|
||||
|
||||
interceptor.intercept(request, new byte[0], (outbound, body) -> {
|
||||
captured.set(outbound.getHeaders());
|
||||
return new MockClientHttpResponse(new byte[0], org.springframework.http.HttpStatus.OK);
|
||||
});
|
||||
|
||||
assertThat(captured.get().getValuesAsList(CorrelationContext.REQUEST_ID_HEADER))
|
||||
.containsExactly("req-rest-client");
|
||||
assertThat(captured.get().getValuesAsList(CorrelationContext.TRACE_ID_HEADER))
|
||||
.containsExactly("4bf92f3577b34da6a3ce929d0e0e4736");
|
||||
assertThat(captured.get().getFirst(CorrelationContext.TRACE_PARENT_HEADER))
|
||||
.matches("00-4bf92f3577b34da6a3ce929d0e0e4736-[0-9a-f]{16}-01");
|
||||
}
|
||||
|
||||
@Test
|
||||
void missingOrInvalidMdcSafelyCreatesNewStandardHeaders() throws Exception {
|
||||
MDC.put(CorrelationContext.TRACE_ID, "business-order-123");
|
||||
MockClientHttpRequest request = new MockClientHttpRequest();
|
||||
|
||||
interceptor.intercept(request, new byte[0], (outbound, body) ->
|
||||
new MockClientHttpResponse(new byte[0], org.springframework.http.HttpStatus.OK));
|
||||
|
||||
assertThat(request.getHeaders().getFirst(CorrelationContext.REQUEST_ID_HEADER))
|
||||
.matches("[0-9a-f-]{36}");
|
||||
assertThat(request.getHeaders().getFirst(CorrelationContext.TRACE_ID_HEADER))
|
||||
.matches("[0-9a-f]{32}").isNotEqualTo("business-order-123");
|
||||
assertThat(request.getHeaders().getFirst(CorrelationContext.TRACE_PARENT_HEADER))
|
||||
.matches("00-[0-9a-f]{32}-[0-9a-f]{16}-01");
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.baiyue.common.web;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.web.client.RestClientCustomizer;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
class RestClientTracePropagationAutoConfigurationTest {
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(RestClientTracePropagationAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void registersInterceptorAndIndependentCustomizer() {
|
||||
contextRunner.run(context -> {
|
||||
assertThat(context).hasSingleBean(RestClientTraceInterceptor.class);
|
||||
assertThat(context).hasBean("baiyueTraceRestClientCustomizer");
|
||||
assertThat(context.getBeansOfType(RestClientCustomizer.class)).hasSize(1);
|
||||
RestClientTraceCustomizer customizer = context.getBean(RestClientTraceCustomizer.class);
|
||||
assertThat(customizer.getOrder()).isEqualTo(Ordered.LOWEST_PRECEDENCE);
|
||||
RestClient.Builder builder = mock(RestClient.Builder.class);
|
||||
customizer.customize(builder);
|
||||
verify(builder).requestInterceptor(context.getBean(RestClientTraceInterceptor.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void reusesApplicationProvidedTraceInterceptor() {
|
||||
contextRunner.withBean(RestClientTraceInterceptor.class, RestClientTraceInterceptor::new)
|
||||
.run(context -> assertThat(context).hasSingleBean(RestClientTraceInterceptor.class));
|
||||
}
|
||||
}
|
||||
@@ -51,4 +51,12 @@ class TraceParentTest {
|
||||
assertThat(child.value()).matches(
|
||||
"00-4bf92f3577b34da6a3ce929d0e0e4736-[0-9a-f]{16}-01");
|
||||
}
|
||||
|
||||
@Test
|
||||
void trustedPersistedUuidNormalizationDoesNotBroadenHttpParsing() {
|
||||
assertThat(TraceParent.normalizeTrustedTraceId("550E8400-E29B-41D4-A716-446655440000"))
|
||||
.contains("550e8400e29b41d4a716446655440000");
|
||||
assertThat(TraceParent.parse(
|
||||
"00-550E8400E29B41D4A716446655440000-00f067aa0ba902b7-01")).isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user