Updated the implementation to contain all b3 propagation mechanism; fixes gh-1077

This commit is contained in:
Marcin Grzejszczak
2018-09-11 14:14:05 +02:00
parent b7302a61f6
commit bef30d698b
11 changed files with 504 additions and 70 deletions

View File

@@ -0,0 +1,145 @@
/*
* Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.sleuth;
import java.util.List;
import java.util.Map;
import org.springframework.util.StringUtils;
/**
* Utility class to retrieve tracing ids from headers
*
* @author Marcin Grzejszczak
* @since 1.3.5
*/
public final class B3Utils {
/**
* Tries to retrieve trace id from b3 header. Falls back to standard header
* if there's nothing there in b3 header
*/
public static String toB3String(Span span) {
String traceId = span.traceIdString();
String spanId = Span.idToHex(span.getSpanId());
boolean sampled = span.isExportable();
List<Long> parents = span.getParents();
StringBuilder b3 = new StringBuilder()
.append(traceId).append("-")
.append(spanId).append("-")
.append(sampled ? Span.SPAN_SAMPLED : Span.SPAN_NOT_SAMPLED);
if (parents != null && !parents.isEmpty()) {
b3 = b3.append("-").append(Span.idToHex(parents.get(0)));
}
return b3.toString();
}
/**
* Tries to retrieve trace id from b3 header. Falls back to standard header
* if there's nothing there in b3 header
*/
public static String traceId(String b3HeaderName,
String fallbackHeaderName, Map<String, String> carrier) {
String b3 = carrier.get(b3HeaderName);
if (StringUtils.hasText(b3)) {
String[] split = b3.split("-");
if (split.length > 1) {
return split[0];
}
}
return carrier.get(fallbackHeaderName);
}
/**
* Tries to retrieve span id from b3 header. Falls back to standard header
* if there's nothing there in b3 header
*/
public static String spanId(String b3HeaderName,
String fallbackHeaderName, Map<String, String> carrier) {
String b3 = carrier.get(b3HeaderName);
if (StringUtils.hasText(b3)) {
String[] split = b3.split("-");
if (split.length > 1) {
return split[1];
}
}
return carrier.get(fallbackHeaderName);
}
/**
* Tries to retrieve parent span id from b3 header. Falls back to standard header
* if there's nothing there in b3 header
*/
public static String parentSpanId(String b3HeaderName,
String fallbackHeaderName, Map<String, String> carrier) {
String b3 = carrier.get(b3HeaderName);
if (StringUtils.hasText(b3)) {
String[] split = b3.split("-");
if (split.length == 4) {
return split[3];
}
}
return carrier.get(fallbackHeaderName);
}
/**
* Tries to retrieve sample flag from b3 header. Falls back to standard span flag header
* and sampled header, if there's nothing there in b3 header
*/
public static Sampled sampled(String b3HeaderName,
String fallbackSampledHeaderName, String fallbackFlagsHeaderName,
Map<String, String> carrier) {
String b3 = carrier.get(b3HeaderName);
if (StringUtils.hasText(b3)) {
String[] split = b3.split("-");
if (split.length > 2) {
return Sampled.from(split[2]);
}
}
String fallbackFlag = carrier.get(fallbackFlagsHeaderName);
if (Span.SPAN_SAMPLED.equals(fallbackFlag)) {
return Sampled.DEBUG;
}
return Sampled.from(carrier.get(fallbackSampledHeaderName));
}
public enum Sampled {
SAMPLED('1'), NOT_SAMPLED('0'), DEBUG('d');
final char sampledChar;
Sampled(char sampledChar) {
this.sampledChar = sampledChar;
}
static Sampled from(String value) {
if (StringUtils.hasText(value)) {
switch (value) {
case "1" : return SAMPLED;
case "0" : return NOT_SAMPLED;
case "d" : return DEBUG;
}
}
return null;
}
@Override public String toString() {
return String.valueOf(this.sampledChar);
}
}
}

View File

@@ -3,10 +3,10 @@ package org.springframework.cloud.sleuth.instrument.messaging;
import java.util.Map;
import java.util.Random;
import org.springframework.cloud.sleuth.B3Utils;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.SpanTextMap;
import org.springframework.cloud.sleuth.util.TextMapUtil;
import org.springframework.util.StringUtils;
/**
* Default implementation for messaging
@@ -62,9 +62,9 @@ public class HeaderBasedMessagingExtractor implements MessagingSpanTextMapExtrac
.traceIdHigh(traceId.length() == 32 ? Span.hexToId(traceId, 0) : 0)
.traceId(Span.hexToId(traceId))
.spanId(Span.hexToId(spanId(carrier)));
String flags = carrier.get(TraceMessageHeaders.SPAN_FLAGS_NAME);
boolean debug = Span.SPAN_SAMPLED.equals(flags);
boolean spanSampled = Span.SPAN_SAMPLED.equals(sampled(carrier));
B3Utils.Sampled sampled = sampled(carrier);
boolean debug = sampled == B3Utils.Sampled.DEBUG;
boolean spanSampled = sampled == B3Utils.Sampled.SAMPLED;
if (debug) {
spanBuilder.exportable(true);
} else {
@@ -90,36 +90,19 @@ public class HeaderBasedMessagingExtractor implements MessagingSpanTextMapExtrac
}
private String traceId(Map<String, String> carrier) {
String b3 = carrier.get(TraceMessageHeaders.B3_NAME);
if (StringUtils.hasText(b3)) {
String[] split = b3.split("-");
if (split.length == 3) {
return split[0];
}
}
return carrier.get(TraceMessageHeaders.TRACE_ID_NAME);
return B3Utils.traceId(TraceMessageHeaders.B3_NAME,
TraceMessageHeaders.TRACE_ID_NAME, carrier);
}
private String spanId(Map<String, String> carrier) {
String b3 = carrier.get(TraceMessageHeaders.B3_NAME);
if (StringUtils.hasText(b3)) {
String[] split = b3.split("-");
if (split.length == 3) {
return split[1];
}
}
return carrier.get(TraceMessageHeaders.SPAN_ID_NAME);
return B3Utils.spanId(TraceMessageHeaders.B3_NAME,
TraceMessageHeaders.SPAN_ID_NAME, carrier);
}
private String sampled(Map<String, String> carrier) {
String b3 = carrier.get(TraceMessageHeaders.B3_NAME);
if (StringUtils.hasText(b3)) {
String[] split = b3.split("-");
if (split.length == 3) {
return split[2];
}
}
return carrier.get(TraceMessageHeaders.SAMPLED_NAME);
private B3Utils.Sampled sampled(Map<String, String> carrier) {
return B3Utils.sampled(TraceMessageHeaders.B3_NAME,
TraceMessageHeaders.SAMPLED_NAME,
TraceMessageHeaders.SPAN_FLAGS_NAME, carrier);
}
boolean hasHeader(Map<String, String> message, String name) {
@@ -128,7 +111,7 @@ public class HeaderBasedMessagingExtractor implements MessagingSpanTextMapExtrac
private void setParentIdIfApplicable(Map<String, String> carrier, Span.SpanBuilder spanBuilder,
String spanParentIdHeader) {
String parentId = carrier.get(spanParentIdHeader);
String parentId = B3Utils.parentSpanId(TraceMessageHeaders.B3_NAME, spanParentIdHeader, carrier);
if (parentId != null) {
spanBuilder.parent(Span.hexToId(parentId));
}

View File

@@ -3,6 +3,7 @@ package org.springframework.cloud.sleuth.instrument.messaging;
import java.util.List;
import java.util.Map;
import org.springframework.cloud.sleuth.B3Utils;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.SpanTextMap;
import org.springframework.cloud.sleuth.TraceKeys;
@@ -43,8 +44,7 @@ public class HeaderBasedMessagingInjector implements MessagingSpanTextMapInjecto
private void addHeaders(Map<String, String> map, Span span, SpanTextMap textMap) {
addHeader(map, textMap, TraceMessageHeaders.TRACE_ID_NAME, span.traceIdString());
addHeader(map, textMap, TraceMessageHeaders.SPAN_ID_NAME, Span.idToHex(span.getSpanId()));
addHeader(map, textMap, TraceMessageHeaders.B3_NAME, span.traceIdString() + "-" +
Span.idToHex(span.getSpanId()) + "-" + (span.isExportable() ? Span.SPAN_SAMPLED : Span.SPAN_NOT_SAMPLED));
addHeader(map, textMap, TraceMessageHeaders.B3_NAME, B3Utils.toB3String(span));
if (span.isExportable()) {
addAnnotations(this.traceKeys, textMap, span);
Long parentId = getFirst(span.getParents());

View File

@@ -6,6 +6,7 @@ import java.util.Random;
import java.util.regex.Pattern;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.sleuth.B3Utils;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.SpanTextMap;
import org.springframework.util.StringUtils;
@@ -82,36 +83,16 @@ public class ZipkinHttpSpanExtractor implements HttpSpanExtractor {
}
private String traceId(Map<String, String> carrier) {
String b3 = carrier.get(Span.B3_NAME);
if (StringUtils.hasText(b3)) {
String[] split = b3.split("-");
if (split.length == 3) {
return split[0];
}
}
return carrier.get(Span.TRACE_ID_NAME);
return B3Utils.traceId(Span.B3_NAME, Span.TRACE_ID_NAME, carrier);
}
private String spanId(Map<String, String> carrier) {
String b3 = carrier.get(Span.B3_NAME);
if (StringUtils.hasText(b3)) {
String[] split = b3.split("-");
if (split.length == 3) {
return split[1];
}
}
return carrier.get(Span.SPAN_ID_NAME);
return B3Utils.spanId(Span.B3_NAME, Span.SPAN_ID_NAME, carrier);
}
private String sampled(Map<String, String> carrier) {
String b3 = carrier.get(Span.B3_NAME);
if (StringUtils.hasText(b3)) {
String[] split = b3.split("-");
if (split.length == 3) {
return split[2];
}
}
return carrier.get(Span.SAMPLED_NAME);
private B3Utils.Sampled sampled(Map<String, String> carrier) {
return B3Utils.sampled(Span.B3_NAME,
Span.SAMPLED_NAME, Span.SPAN_FLAGS, carrier);
}
private String traceIdOrDefaut(Map<String, String> carrier) {
@@ -139,18 +120,18 @@ public class ZipkinHttpSpanExtractor implements HttpSpanExtractor {
if (StringUtils.hasText(processId)) {
span.processId(processId);
}
String parentId = carrier.get(Span.PARENT_ID_NAME);
String parentId = B3Utils.parentSpanId(Span.B3_NAME, Span.PARENT_ID_NAME, carrier);
if (parentId != null) {
span.parent(Span.hexToId(parentId));
}
span.remote(true);
B3Utils.Sampled sampled = sampled(carrier);
boolean skip = this.skipPattern
.matcher(carrier.get(ZipkinHttpSpanMapper.URI_HEADER)).matches()
|| Span.SPAN_NOT_SAMPLED.equals(sampled(carrier));
|| sampled == B3Utils.Sampled.NOT_SAMPLED;
// trace, span id were retrieved from the headers and span is sampled
span.shared(!(skip || idToBeGenerated));
boolean debug = Span.SPAN_SAMPLED.equals(carrier.get(Span.SPAN_FLAGS));
boolean debug = sampled == B3Utils.Sampled.DEBUG;
if (debug) {
span.exportable(true);
} else if (skip) {

View File

@@ -2,6 +2,7 @@ package org.springframework.cloud.sleuth.instrument.web;
import java.util.Map;
import org.springframework.cloud.sleuth.B3Utils;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.SpanTextMap;
import org.springframework.util.StringUtils;
@@ -19,7 +20,7 @@ public class ZipkinHttpSpanInjector implements HttpSpanInjector {
@Override
public void inject(Span span, SpanTextMap map) {
Map<String, String> carrier = SPAN_CARRIER_MAPPER.convert(map);
setHeader(map, carrier, Span.B3_NAME, b3(span));
setHeader(map, carrier, Span.B3_NAME, B3Utils.toB3String(span));
setHeader(map, carrier, Span.TRACE_ID_NAME, span.traceIdString());
setIdHeader(map, carrier, Span.SPAN_ID_NAME, span.getSpanId());
setHeader(map, carrier, Span.SAMPLED_NAME, span.isExportable() ? Span.SPAN_SAMPLED : Span.SPAN_NOT_SAMPLED);
@@ -31,11 +32,6 @@ public class ZipkinHttpSpanInjector implements HttpSpanInjector {
}
}
private String b3(Span span) {
return span.traceIdString() + "-" + Span.idToHex(span.getSpanId()) + "-" +
(span.isExportable() ? Span.SPAN_SAMPLED : Span.SPAN_NOT_SAMPLED);
}
private String prefixedKey(String key) {
if (key.startsWith(Span.SPAN_BAGGAGE_HEADER_PREFIX
+ ZipkinHttpSpanMapper.HEADER_DELIMITER)) {

View File

@@ -0,0 +1,177 @@
/*
* Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.sleuth;
import java.util.HashMap;
import java.util.Map;
import org.assertj.core.api.BDDAssertions;
import org.junit.Test;
/**
* @author Marcin Grzejszczak
*/
public class B3UtilsTest {
@Test public void should_build_a_b3_string_without_parent_span() {
Span span = Span.builder()
.traceId(1L)
.spanId(2L)
.exportable(true).build();
String b3String = B3Utils.toB3String(span);
BDDAssertions.then(b3String).isEqualTo("0000000000000001-0000000000000002-1");
}
@Test public void should_build_a_b3_string_without_parent_span_for_unsampled() {
Span span = Span.builder()
.traceId(1L)
.spanId(2L)
.exportable(false).build();
String b3String = B3Utils.toB3String(span);
BDDAssertions.then(b3String).isEqualTo("0000000000000001-0000000000000002-0");
}
@Test public void should_build_a_b3_string_with_parent_span() {
Span span = Span.builder()
.traceId(1L)
.spanId(2L)
.parent(3L)
.exportable(true).build();
String b3String = B3Utils.toB3String(span);
BDDAssertions.then(b3String).isEqualTo("0000000000000001-0000000000000002-1-0000000000000003");
}
@Test public void should_read_trace_id_from_b3_string() {
Map<String, String> map = new HashMap<>();
map.put("b3", "0000000000000001-0000000000000002-1-0000000000000003");
String id = B3Utils.traceId("b3", "fallback", map);
BDDAssertions.then(id).isEqualTo("0000000000000001");
}
@Test public void should_read_trace_id_from_fallback() {
Map<String, String> map = new HashMap<>();
map.put("fallback", "0000000000000001");
String id = B3Utils.traceId("b3", "fallback", map);
BDDAssertions.then(id).isEqualTo("0000000000000001");
}
@Test public void should_read_span_id_from_b3_string() {
Map<String, String> map = new HashMap<>();
map.put("b3", "0000000000000001-0000000000000002-1-0000000000000003");
String id = B3Utils.spanId("b3", "fallback", map);
BDDAssertions.then(id).isEqualTo("0000000000000002");
}
@Test public void should_read_span_id_from_fallback() {
Map<String, String> map = new HashMap<>();
map.put("fallback", "0000000000000002");
String id = B3Utils.spanId("b3", "fallback", map);
BDDAssertions.then(id).isEqualTo("0000000000000002");
}
@Test public void should_read_parent_id_from_b3_string() {
Map<String, String> map = new HashMap<>();
map.put("b3", "0000000000000001-0000000000000002-1-0000000000000003");
String id = B3Utils.parentSpanId("b3", "fallback", map);
BDDAssertions.then(id).isEqualTo("0000000000000003");
}
@Test public void should_read_parent_id_from_fallback() {
Map<String, String> map = new HashMap<>();
map.put("fallback", "0000000000000003");
String id = B3Utils.parentSpanId("b3", "fallback", map);
BDDAssertions.then(id).isEqualTo("0000000000000003");
}
@Test public void should_read_sampled_id_from_b3_string() {
Map<String, String> map = new HashMap<>();
map.put("b3", "0000000000000001-0000000000000002-1-0000000000000003");
B3Utils.Sampled sampled = B3Utils.sampled("b3", "fallbackSampled",
"fallbackFlags", map);
BDDAssertions.then(sampled).isEqualTo(B3Utils.Sampled.SAMPLED);
}
@Test public void should_read_not_sampled_id_from_b3_string() {
Map<String, String> map = new HashMap<>();
map.put("b3", "0000000000000001-0000000000000002-0-0000000000000003");
B3Utils.Sampled sampled = B3Utils.sampled("b3", "fallbackSampled",
"fallbackFlags", map);
BDDAssertions.then(sampled).isEqualTo(B3Utils.Sampled.NOT_SAMPLED);
}
@Test public void should_read_debug_sampled_id_from_b3_string() {
Map<String, String> map = new HashMap<>();
map.put("b3", "0000000000000001-0000000000000002-d-0000000000000003");
B3Utils.Sampled sampled = B3Utils.sampled("b3", "fallbackSampled",
"fallbackFlags", map);
BDDAssertions.then(sampled).isEqualTo(B3Utils.Sampled.DEBUG);
}
@Test public void should_read_sampled_id_from_fallback() {
Map<String, String> map = new HashMap<>();
map.put("fallbackSampled", "1");
B3Utils.Sampled sampled = B3Utils.sampled("b3", "fallbackSampled",
"fallbackFlags", map);
BDDAssertions.then(sampled).isEqualTo(B3Utils.Sampled.SAMPLED);
}
@Test public void should_read_not_sampled_id_from_fallback() {
Map<String, String> map = new HashMap<>();
map.put("fallbackSampled", "0");
B3Utils.Sampled sampled = B3Utils.sampled("b3", "fallbackSampled",
"fallbackFlags", map);
BDDAssertions.then(sampled).isEqualTo(B3Utils.Sampled.NOT_SAMPLED);
}
@Test public void should_read_debug_id_from_fallback() {
Map<String, String> map = new HashMap<>();
map.put("fallbackFlags", "1");
B3Utils.Sampled sampled = B3Utils.sampled("b3", "fallbackSampled",
"fallbackFlags", map);
BDDAssertions.then(sampled).isEqualTo(B3Utils.Sampled.DEBUG);
}
}

View File

@@ -21,6 +21,7 @@ import java.util.Objects;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.Assertions;
import org.springframework.cloud.sleuth.Span;
public class SpanAssert extends AbstractAssert<SpanAssert, Span> {
@@ -45,6 +46,18 @@ public class SpanAssert extends AbstractAssert<SpanAssert, Span> {
return this;
}
public SpanAssert hasParentSpanIdEqualTo(Long spanId) {
isNotNull();
Assertions.assertThat(this.actual.getParents()).isNotEmpty();
Long parentSpanId = this.actual.getParents().get(0);
if (!Objects.equals(parentSpanId, spanId)) {
String message = String.format("Expected span's parent spanId to be <%s> but was <%s>", spanId, parentSpanId);
log.error(message);
failWithMessage(message);
}
return this;
}
public SpanAssert hasSpanIdEqualTo(Long spanId) {
isNotNull();
if (!Objects.equals(this.actual.getSpanId(), spanId)) {

View File

@@ -32,7 +32,25 @@ import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then;
public class HeaderBasedMessagingExtractorTests {
@Test
public void b3HeadersTakePrecedenceOverAnyOtherHeaders() {
public void simpleB3HeadersTakePrecedenceOverAnyOtherHeaders() {
HeaderBasedMessagingExtractor extractor = new HeaderBasedMessagingExtractor();
SpanTextMap spanTextMap = spanTextMap();
spanTextMap.put(TraceMessageHeaders.B3_NAME, "0000000000000005-0000000000000004");
spanTextMap.put(TraceMessageHeaders.SPAN_ID_NAME, Span.idToHex(20L));
spanTextMap.put(TraceMessageHeaders.TRACE_ID_NAME, Span.idToHex(30L));
spanTextMap.put(TraceMessageHeaders.SAMPLED_NAME, "1");
Span span = extractor.joinTrace(spanTextMap);
then(span)
.isNotNull()
.hasTraceIdEqualTo(5L)
.hasSpanIdEqualTo(4L)
.isExportable();
}
@Test
public void b3HeadersWithSampledTakePrecedenceOverAnyOtherHeaders() {
HeaderBasedMessagingExtractor extractor = new HeaderBasedMessagingExtractor();
SpanTextMap spanTextMap = spanTextMap();
spanTextMap.put(TraceMessageHeaders.B3_NAME, "0000000000000005-0000000000000004-1");
@@ -49,6 +67,45 @@ public class HeaderBasedMessagingExtractorTests {
.isExportable();
}
@Test
public void b3HeadersWithDebugSampledTakePrecedenceOverAnyOtherHeaders() {
HeaderBasedMessagingExtractor extractor = new HeaderBasedMessagingExtractor();
SpanTextMap spanTextMap = spanTextMap();
spanTextMap.put(TraceMessageHeaders.B3_NAME, "0000000000000005-0000000000000004-d");
spanTextMap.put(TraceMessageHeaders.SPAN_ID_NAME, Span.idToHex(20L));
spanTextMap.put(TraceMessageHeaders.TRACE_ID_NAME, Span.idToHex(30L));
spanTextMap.put(TraceMessageHeaders.SAMPLED_NAME, "0");
spanTextMap.put(TraceMessageHeaders.SPAN_FLAGS_NAME, "0");
Span span = extractor.joinTrace(spanTextMap);
then(span)
.isNotNull()
.hasTraceIdEqualTo(5L)
.hasSpanIdEqualTo(4L)
.isExportable();
}
@Test
public void b3HeadersWithParentSpanIdTakePrecedenceOverAnyOtherHeaders() {
HeaderBasedMessagingExtractor extractor = new HeaderBasedMessagingExtractor();
SpanTextMap spanTextMap = spanTextMap();
spanTextMap.put(TraceMessageHeaders.B3_NAME, "0000000000000005-0000000000000004-1-0000000000000003");
spanTextMap.put(TraceMessageHeaders.SPAN_ID_NAME, Span.idToHex(20L));
spanTextMap.put(TraceMessageHeaders.TRACE_ID_NAME, Span.idToHex(30L));
spanTextMap.put(TraceMessageHeaders.PARENT_ID_NAME, Span.idToHex(60L));
spanTextMap.put(TraceMessageHeaders.SAMPLED_NAME, "0");
Span span = extractor.joinTrace(spanTextMap);
then(span)
.isNotNull()
.hasTraceIdEqualTo(5L)
.hasSpanIdEqualTo(4L)
.hasParentSpanIdEqualTo(3L)
.isExportable();
}
@Test
public void legacyHeadersTakePrecedenceOverB3WhenB3IsInvalid() {
HeaderBasedMessagingExtractor extractor = new HeaderBasedMessagingExtractor();

View File

@@ -40,7 +40,7 @@ public class HeaderBasedMessagingInjectorTests {
injector.inject(span, map);
then(map)
.contains(new AbstractMap.SimpleEntry<String, String>(TraceMessageHeaders.B3_NAME, "0000000000000002-0000000000000001-1"))
.contains(new AbstractMap.SimpleEntry<String, String>(TraceMessageHeaders.B3_NAME, "0000000000000002-0000000000000001-1-0000000000000003"))
.contains(new AbstractMap.SimpleEntry<String, String>(TraceMessageHeaders.SPAN_ID_NAME, Span.idToHex(10L)))
.contains(new AbstractMap.SimpleEntry<String, String>(TraceMessageHeaders.TRACE_ID_NAME, Span.idToHex(20L)))
.contains(new AbstractMap.SimpleEntry<String, String>(TraceMessageHeaders.PARENT_ID_NAME, Span.idToHex(30L)))

View File

@@ -82,6 +82,60 @@ public class HttpServletRequestExtractorTests {
@Test
public void should_pick_values_from_b3_if_present() {
BDDMockito.given(this.request.getHeaderNames())
.willReturn(new Vector<>(Arrays.asList(Span.B3_NAME, Span.TRACE_ID_NAME,
Span.SPAN_ID_NAME, Span.PARENT_ID_NAME, Span.SAMPLED_NAME,
Span.SPAN_FLAGS)).elements());
BDDMockito.given(this.request.getHeader(Span.TRACE_ID_NAME))
.willReturn(Span.idToHex(10L));
BDDMockito.given(this.request.getHeader(Span.SPAN_ID_NAME))
.willReturn(Span.idToHex(20L));
BDDMockito.given(this.request.getHeader(Span.PARENT_ID_NAME))
.willReturn(Span.idToHex(30L));
BDDMockito.given(this.request.getHeader(Span.SAMPLED_NAME))
.willReturn(Span.SPAN_SAMPLED);
BDDMockito.given(this.request.getHeader(Span.B3_NAME))
.willReturn("0000000000000005-0000000000000004");
Span span = this.extractor.joinTrace(new HttpServletRequestTextMap(this.request));
then(span)
.isNotNull()
.hasTraceIdEqualTo(5L)
.hasSpanIdEqualTo(4L)
.hasParentSpanIdEqualTo(30L)
.isExportable();
}
@Test
public void should_pick_values_from_b3_with_debug_flag_if_present() {
BDDMockito.given(this.request.getHeaderNames())
.willReturn(new Vector<>(Arrays.asList(Span.B3_NAME, Span.TRACE_ID_NAME,
Span.SPAN_ID_NAME, Span.PARENT_ID_NAME, Span.SAMPLED_NAME,
Span.SPAN_FLAGS)).elements());
BDDMockito.given(this.request.getHeader(Span.TRACE_ID_NAME))
.willReturn(Span.idToHex(10L));
BDDMockito.given(this.request.getHeader(Span.SPAN_ID_NAME))
.willReturn(Span.idToHex(20L));
BDDMockito.given(this.request.getHeader(Span.PARENT_ID_NAME))
.willReturn(Span.idToHex(30L));
BDDMockito.given(this.request.getHeader(Span.SAMPLED_NAME))
.willReturn(Span.SPAN_NOT_SAMPLED);
BDDMockito.given(this.request.getHeader(Span.B3_NAME))
.willReturn("0000000000000005-0000000000000004-d");
Span span = this.extractor.joinTrace(new HttpServletRequestTextMap(this.request));
then(span)
.isNotNull()
.hasTraceIdEqualTo(5L)
.hasSpanIdEqualTo(4L)
.hasParentSpanIdEqualTo(30L)
.isExportable();
}
@Test
public void should_pick_values_from_b3_with_sampled_flag_if_present() {
BDDMockito.given(this.request.getHeaderNames())
.willReturn(new Vector<>(Arrays.asList(Span.B3_NAME, Span.TRACE_ID_NAME,
Span.SPAN_ID_NAME, Span.PARENT_ID_NAME, Span.SAMPLED_NAME,
@@ -103,6 +157,34 @@ public class HttpServletRequestExtractorTests {
.isNotNull()
.hasTraceIdEqualTo(5L)
.hasSpanIdEqualTo(4L)
.hasParentSpanIdEqualTo(30L)
.isExportable();
}
@Test
public void should_pick_values_from_b3_with_parent_id_if_present() {
BDDMockito.given(this.request.getHeaderNames())
.willReturn(new Vector<>(Arrays.asList(Span.B3_NAME, Span.TRACE_ID_NAME,
Span.SPAN_ID_NAME, Span.PARENT_ID_NAME, Span.SAMPLED_NAME,
Span.SPAN_FLAGS)).elements());
BDDMockito.given(this.request.getHeader(Span.TRACE_ID_NAME))
.willReturn(Span.idToHex(10L));
BDDMockito.given(this.request.getHeader(Span.SPAN_ID_NAME))
.willReturn(Span.idToHex(20L));
BDDMockito.given(this.request.getHeader(Span.PARENT_ID_NAME))
.willReturn(Span.idToHex(30L));
BDDMockito.given(this.request.getHeader(Span.SAMPLED_NAME))
.willReturn(Span.SPAN_NOT_SAMPLED);
BDDMockito.given(this.request.getHeader(Span.B3_NAME))
.willReturn("0000000000000005-0000000000000004-1-0000000000000006");
Span span = this.extractor.joinTrace(new HttpServletRequestTextMap(this.request));
then(span)
.isNotNull()
.hasTraceIdEqualTo(5L)
.hasSpanIdEqualTo(4L)
.hasParentSpanIdEqualTo(6L)
.isExportable();
}

View File

@@ -39,7 +39,7 @@ public class ZipkinHttpSpanInjectorTests {
then(map)
.contains(new AbstractMap.SimpleEntry<String, String>(Span.B3_NAME,
"0000000000000002-0000000000000001-1"))
"0000000000000002-0000000000000001-1-0000000000000003"))
.contains(new AbstractMap.SimpleEntry<String, String>(Span.SPAN_ID_NAME, Span.idToHex(10L)))
.contains(new AbstractMap.SimpleEntry<String, String>(Span.TRACE_ID_NAME, Span.idToHex(20L)))
.contains(new AbstractMap.SimpleEntry<String, String>(Span.PARENT_ID_NAME, Span.idToHex(30L)))