diff --git a/.gitignore b/.gitignore index 06915189a..b59b15b43 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ _site/ /spring-cloud-sleuth-core/nbactions.xml jmh-result.csv pom.xml.versionsBackup +.sts4-cache diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java index 2e6d240d1..447b515f4 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java @@ -16,6 +16,9 @@ package org.springframework.cloud.sleuth.instrument.web.client; +import java.util.List; +import java.util.Map; + import brave.Span; import brave.Tracer; import brave.http.HttpClientHandler; @@ -62,7 +65,11 @@ final class TraceRequestHttpHeadersFilter extends AbstractHttpHeadersFilter { exchange.getAttributes().put(SPAN_ATTRIBUTE, span); HttpHeaders headersWithInput = new HttpHeaders(); headersWithInput.addAll(input); - carrier.filteredHeaders.forEach(headersWithInput::put); + addHeadersWithInput(carrier.filteredHeaders, headersWithInput); + if (headersWithInput.containsKey("b3") || headersWithInput.containsKey("B3")) { + headersWithInput.keySet().remove("b3"); + headersWithInput.keySet().remove("B3"); + } return headersWithInput; } @@ -79,7 +86,18 @@ final class TraceRequestHttpHeadersFilter extends AbstractHttpHeadersFilter { if (currentSpan == null) { return this.handler.handleSend(this.injector, carrier); } - return this.handler.handleSend(this.injector, carrier, currentSpan); + Span clientSpan = this.tracer + .nextSpan(TraceContextOrSamplingFlags.create(currentSpan.context())); + return this.handler.handleSend(this.injector, carrier, clientSpan); + } + + private void addHeadersWithInput(HttpHeaders filteredHeaders, + HttpHeaders headersWithInput) { + for (Map.Entry> entry : filteredHeaders.entrySet()) { + String key = entry.getKey(); + List value = entry.getValue(); + headersWithInput.put(key, value); + } } @Override diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java index ae2e1ce73..f5459fcec 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java @@ -74,6 +74,38 @@ public class TraceRequestHttpHeadersFilterTests { .isNotNull(); } + @Test + public void should_override_span_tracing_headers_when_using_b3() { + HttpHeadersFilter filter = TraceRequestHttpHeadersFilter.create(this.httpTracing); + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.set("X-Hello", "World"); + httpHeaders.set("B3", "1111111111111111-1111111111111111"); + MockServerHttpRequest request = MockServerHttpRequest.post("foo/bar") + .headers(httpHeaders).build(); + MockServerWebExchange exchange = MockServerWebExchange.builder(request).build(); + + HttpHeaders filteredHeaders = filter.filter(requestHeaders(httpHeaders), + exchange); + + // we want to continue the trace + BDDAssertions.then(filteredHeaders.get("X-B3-TraceId")) + .isEqualTo(Collections.singletonList("1111111111111111")); + // but we want to have a new span id + BDDAssertions.then(filteredHeaders.get("X-B3-SpanId")) + .isNotEqualTo(Collections.singletonList("1111111111111111")); + // we don't want to propagate b3 + BDDAssertions.then(filteredHeaders.get("B3")).isNullOrEmpty(); + BDDAssertions.then(filteredHeaders.get("X-Hello")) + .isEqualTo(Collections.singletonList("World")); + BDDAssertions.then(filteredHeaders.get("X-Hello-Request")) + .isEqualTo(Collections.singletonList("Request World")); + BDDAssertions.then(filteredHeaders.get("X-Auth-User")).hasSize(1); + BDDAssertions + .then((Object) exchange + .getAttribute(TraceRequestHttpHeadersFilter.SPAN_ATTRIBUTE)) + .isNotNull(); + } + @Test public void should_set_tracing_headers() { HttpHeadersFilter filter = TraceRequestHttpHeadersFilter.create(this.httpTracing);