优化
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package com.baiyue.common.web;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
|
||||
@@ -16,6 +18,8 @@ class CommonWebAutoConfigurationTest {
|
||||
contextRunner.run(context -> {
|
||||
assertThat(context).hasSingleBean(GlobalExceptionHandler.class);
|
||||
assertThat(context).hasSingleBean(CorrelationIdFilter.class);
|
||||
assertThat(CorrelationIdFilter.class.getAnnotation(Order.class).value())
|
||||
.isEqualTo(Ordered.HIGHEST_PRECEDENCE);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ import org.springframework.mock.web.MockFilterChain;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@DisplayName("请求链路标识过滤功能")
|
||||
@@ -13,27 +15,85 @@ class CorrelationIdFilterTest {
|
||||
private final CorrelationIdFilter filter = new CorrelationIdFilter();
|
||||
|
||||
@Test
|
||||
void preservesSafeIncomingIds() throws Exception {
|
||||
void validTraceParentWinsAndMapsToLegacyTraceIdAndMdc() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader(CorrelationContext.REQUEST_ID_HEADER, "req-123");
|
||||
request.addHeader(CorrelationContext.TRACE_ID_HEADER, "trace-123");
|
||||
request.addHeader(CorrelationContext.TRACE_ID_HEADER, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
request.addHeader(CorrelationContext.TRACE_PARENT_HEADER,
|
||||
"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
filter.doFilter(request, response, new MockFilterChain());
|
||||
CapturingFilterChain chain = new CapturingFilterChain();
|
||||
filter.doFilter(request, response, chain);
|
||||
|
||||
assertThat(response.getHeader(CorrelationContext.REQUEST_ID_HEADER)).isEqualTo("req-123");
|
||||
assertThat(request.getAttribute(CorrelationContext.TRACE_ID)).isEqualTo("trace-123");
|
||||
assertThat(response.getHeader(CorrelationContext.TRACE_ID_HEADER))
|
||||
.isEqualTo("4bf92f3577b34da6a3ce929d0e0e4736");
|
||||
assertThat(response.getHeader(CorrelationContext.TRACE_PARENT_HEADER))
|
||||
.matches("00-4bf92f3577b34da6a3ce929d0e0e4736-[0-9a-f]{16}-01");
|
||||
assertThat(chain.traceId).isEqualTo("4bf92f3577b34da6a3ce929d0e0e4736");
|
||||
assertThat(chain.spanId).matches("[0-9a-f]{16}").isNotEqualTo("0000000000000000");
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacesUnsafeIncomingIds() throws Exception {
|
||||
void fallsBackToValidLegacyTraceIdOnlyWhenTraceParentIsMissing() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader(CorrelationContext.REQUEST_ID_HEADER, "invalid value\n");
|
||||
request.addHeader(CorrelationContext.TRACE_ID_HEADER, "ABCDEF0123456789ABCDEF0123456789");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
filter.doFilter(request, response, new MockFilterChain());
|
||||
|
||||
assertThat(response.getHeader(CorrelationContext.TRACE_ID_HEADER))
|
||||
.isEqualTo("abcdef0123456789abcdef0123456789");
|
||||
assertThat(response.getHeader(CorrelationContext.TRACE_PARENT_HEADER))
|
||||
.matches("00-abcdef0123456789abcdef0123456789-[0-9a-f]{16}-00");
|
||||
}
|
||||
|
||||
@Test
|
||||
void invalidTraceParentStartsNewTraceWithoutTrustingLegacyTraceId() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader(CorrelationContext.TRACE_PARENT_HEADER,
|
||||
"00-00000000000000000000000000000000-00f067aa0ba902b7-01");
|
||||
request.addHeader(CorrelationContext.TRACE_ID_HEADER, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
filter.doFilter(request, response, new MockFilterChain());
|
||||
|
||||
assertThat(response.getHeader(CorrelationContext.TRACE_ID_HEADER))
|
||||
.matches("[0-9a-f]{32}")
|
||||
.isNotEqualTo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
|
||||
.isNotEqualTo("00000000000000000000000000000000");
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsDuplicateAndOversizedHeaders() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader(CorrelationContext.REQUEST_ID_HEADER, "a".repeat(129));
|
||||
request.addHeader(CorrelationContext.TRACE_PARENT_HEADER,
|
||||
"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01");
|
||||
request.addHeader(CorrelationContext.TRACE_PARENT_HEADER,
|
||||
"00-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bbbbbbbbbbbbbbbb-00");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
filter.doFilter(request, response, new MockFilterChain());
|
||||
|
||||
assertThat(response.getHeader(CorrelationContext.REQUEST_ID_HEADER))
|
||||
.matches("[0-9a-f-]{36}");
|
||||
assertThat(response.getHeader(CorrelationContext.TRACE_ID_HEADER))
|
||||
.matches("[0-9a-f]{32}");
|
||||
.matches("[0-9a-f]{32}")
|
||||
.isNotEqualTo("4bf92f3577b34da6a3ce929d0e0e4736")
|
||||
.isNotEqualTo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
}
|
||||
|
||||
private static final class CapturingFilterChain extends MockFilterChain {
|
||||
private String traceId;
|
||||
private String spanId;
|
||||
|
||||
@Override
|
||||
public void doFilter(jakarta.servlet.ServletRequest request,
|
||||
jakarta.servlet.ServletResponse response) throws IOException {
|
||||
traceId = org.slf4j.MDC.get(CorrelationContext.TRACE_ID);
|
||||
spanId = org.slf4j.MDC.get(CorrelationContext.SPAN_ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.baiyue.common.web;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class TraceParentTest {
|
||||
|
||||
@Test
|
||||
void parsesCanonicalVersion00AndCreatesLocalChild() {
|
||||
TraceParent remote = TraceParent.parse(
|
||||
"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01").orElseThrow();
|
||||
|
||||
TraceParent local = TraceParent.childOf(remote);
|
||||
|
||||
assertThat(local.traceId()).isEqualTo(remote.traceId());
|
||||
assertThat(local.parentId()).matches("[0-9a-f]{16}")
|
||||
.isNotEqualTo(remote.parentId())
|
||||
.isNotEqualTo("0000000000000000");
|
||||
assertThat(local.traceFlags()).isEqualTo("01");
|
||||
assertThat(local.value()).hasSize(TraceParent.HEADER_LENGTH);
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsNonCanonicalUnsupportedAndZeroIdentifiers() {
|
||||
assertThat(TraceParent.parse(
|
||||
"00-4BF92F3577B34DA6A3CE929D0E0E4736-00f067aa0ba902b7-01")).isEmpty();
|
||||
assertThat(TraceParent.parse(
|
||||
"01-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01")).isEmpty();
|
||||
assertThat(TraceParent.parse(
|
||||
"00-00000000000000000000000000000000-00f067aa0ba902b7-01")).isEmpty();
|
||||
assertThat(TraceParent.parse(
|
||||
"00-4bf92f3577b34da6a3ce929d0e0e4736-0000000000000000-01")).isEmpty();
|
||||
assertThat(TraceParent.parse("x".repeat(10_000))).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void createsCanonicalNonZeroRootAndNormalizesLegacyHex() {
|
||||
TraceParent root = TraceParent.newRoot("ABCDEF0123456789ABCDEF0123456789");
|
||||
|
||||
assertThat(root.traceId()).isEqualTo("abcdef0123456789abcdef0123456789");
|
||||
assertThat(root.parentId()).matches("[0-9a-f]{16}").isNotEqualTo("0000000000000000");
|
||||
assertThat(root.value()).matches(
|
||||
"00-abcdef0123456789abcdef0123456789-[0-9a-f]{16}-00");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user