Remove codec for inject/extract
In preparation for OT 0.32 support.
This commit is contained in:
parent
7a430647a0
commit
326577d7df
|
@ -2,9 +2,8 @@ package datadog.opentracing;
|
|||
|
||||
import datadog.opentracing.decorators.AbstractDecorator;
|
||||
import datadog.opentracing.decorators.DDDecoratorsFactory;
|
||||
import datadog.opentracing.propagation.Codec;
|
||||
import datadog.opentracing.propagation.DatadogHttpCodec;
|
||||
import datadog.opentracing.propagation.ExtractedContext;
|
||||
import datadog.opentracing.propagation.HTTPCodec;
|
||||
import datadog.opentracing.propagation.TagContext;
|
||||
import datadog.opentracing.scopemanager.ContextualScopeManager;
|
||||
import datadog.opentracing.scopemanager.ScopeContext;
|
||||
|
@ -24,6 +23,7 @@ import io.opentracing.ScopeManager;
|
|||
import io.opentracing.Span;
|
||||
import io.opentracing.SpanContext;
|
||||
import io.opentracing.propagation.Format;
|
||||
import io.opentracing.propagation.TextMap;
|
||||
import java.io.Closeable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -84,7 +84,9 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
|||
return Integer.compare(o1.priority(), o2.priority());
|
||||
}
|
||||
});
|
||||
private final CodecRegistry registry;
|
||||
|
||||
private final DatadogHttpCodec.Injector injector;
|
||||
private final DatadogHttpCodec.Extractor extractor;
|
||||
|
||||
private final AtomicInteger traceCount;
|
||||
|
||||
|
@ -238,9 +240,9 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
|||
// The JVM is already shutting down.
|
||||
}
|
||||
|
||||
registry = new CodecRegistry();
|
||||
registry.register(Format.Builtin.HTTP_HEADERS, new HTTPCodec(taggedHeaders));
|
||||
registry.register(Format.Builtin.TEXT_MAP, new HTTPCodec(taggedHeaders));
|
||||
injector = new DatadogHttpCodec.Injector();
|
||||
extractor = new DatadogHttpCodec.Extractor(taggedHeaders);
|
||||
|
||||
if (this.writer instanceof DDAgentWriter) {
|
||||
final DDApi api = ((DDAgentWriter) this.writer).getApi();
|
||||
traceCount = api.getTraceCounter();
|
||||
|
@ -332,24 +334,21 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
|||
|
||||
@Override
|
||||
public <T> void inject(final SpanContext spanContext, final Format<T> format, final T carrier) {
|
||||
|
||||
final Codec<T> codec = registry.get(format);
|
||||
if (codec == null) {
|
||||
if (!(carrier instanceof TextMap)) {
|
||||
log.debug("Unsupported format for propagation - {}", format.getClass().getName());
|
||||
} else {
|
||||
codec.inject((DDSpanContext) spanContext, carrier);
|
||||
injector.inject((DDSpanContext) spanContext, (TextMap) carrier);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> SpanContext extract(final Format<T> format, final T carrier) {
|
||||
final Codec<T> codec = registry.get(format);
|
||||
if (codec == null) {
|
||||
if (!(carrier instanceof TextMap)) {
|
||||
log.debug("Unsupported format for propagation - {}", format.getClass().getName());
|
||||
return null;
|
||||
} else {
|
||||
return codec.extract(carrier);
|
||||
return extractor.extract((TextMap) carrier);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -452,19 +451,6 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
|||
return Config.get().getPartialFlushMinSpans();
|
||||
}
|
||||
|
||||
private static class CodecRegistry {
|
||||
|
||||
private final Map<Format<?>, Codec<?>> codecs = new HashMap<>();
|
||||
|
||||
<T> Codec<T> get(final Format<T> format) {
|
||||
return (Codec<T>) codecs.get(format);
|
||||
}
|
||||
|
||||
public <T> void register(final Format<T> format, final Codec<T> codec) {
|
||||
codecs.put(format, codec);
|
||||
}
|
||||
}
|
||||
|
||||
/** Spans are built using this builder */
|
||||
public class DDSpanBuilder implements SpanBuilder {
|
||||
private final ScopeManager scopeManager;
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Uber Technologies, Inc
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package datadog.opentracing.propagation;
|
||||
|
||||
import datadog.opentracing.DDSpanContext;
|
||||
import io.opentracing.SpanContext;
|
||||
|
||||
/** A codec is a simple object that can encode and decode a span context through a carrier */
|
||||
public interface Codec<T> {
|
||||
|
||||
/**
|
||||
* Serialize the span context using the provided carrier
|
||||
*
|
||||
* @param context
|
||||
* @param carrier
|
||||
*/
|
||||
void inject(DDSpanContext context, T carrier);
|
||||
|
||||
/**
|
||||
* Given a carrier, retrieve (rebuild) a span context. This context built will be use as the
|
||||
* parent
|
||||
*
|
||||
* @param carrier
|
||||
* @return the span context
|
||||
*/
|
||||
SpanContext extract(T carrier);
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
package datadog.opentracing.propagation;
|
||||
|
||||
import datadog.opentracing.DDSpanContext;
|
||||
import datadog.trace.api.sampling.PrioritySampling;
|
||||
import io.opentracing.SpanContext;
|
||||
import io.opentracing.propagation.TextMap;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/** A codec designed for HTTP transport via headers */
|
||||
@Slf4j
|
||||
public class DatadogHttpCodec {
|
||||
|
||||
// uint 64 bits max value, 2^64 - 1
|
||||
static final BigInteger BIG_INTEGER_UINT64_MAX =
|
||||
new BigInteger("2").pow(64).subtract(BigInteger.ONE);
|
||||
|
||||
private static final String OT_BAGGAGE_PREFIX = "ot-baggage-";
|
||||
private static final String TRACE_ID_KEY = "x-datadog-trace-id";
|
||||
private static final String SPAN_ID_KEY = "x-datadog-parent-id";
|
||||
private static final String SAMPLING_PRIORITY_KEY = "x-datadog-sampling-priority";
|
||||
|
||||
public static class Injector {
|
||||
|
||||
public void inject(final DDSpanContext context, final TextMap carrier) {
|
||||
carrier.put(TRACE_ID_KEY, String.valueOf(context.getTraceId()));
|
||||
carrier.put(SPAN_ID_KEY, String.valueOf(context.getSpanId()));
|
||||
if (context.lockSamplingPriority()) {
|
||||
carrier.put(SAMPLING_PRIORITY_KEY, String.valueOf(context.getSamplingPriority()));
|
||||
}
|
||||
|
||||
for (final Map.Entry<String, String> entry : context.baggageItems()) {
|
||||
carrier.put(OT_BAGGAGE_PREFIX + entry.getKey(), encode(entry.getValue()));
|
||||
}
|
||||
log.debug("{} - Parent context injected", context.getTraceId());
|
||||
}
|
||||
|
||||
private String encode(final String value) {
|
||||
String encoded = value;
|
||||
try {
|
||||
encoded = URLEncoder.encode(value, "UTF-8");
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
log.info("Failed to encode value - {}", value);
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Extractor {
|
||||
private final Map<String, String> taggedHeaders;
|
||||
|
||||
public Extractor(final Map<String, String> taggedHeaders) {
|
||||
this.taggedHeaders = new HashMap<>();
|
||||
for (final Map.Entry<String, String> mapping : taggedHeaders.entrySet()) {
|
||||
this.taggedHeaders.put(mapping.getKey().trim().toLowerCase(), mapping.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public SpanContext extract(final TextMap carrier) {
|
||||
|
||||
Map<String, String> baggage = Collections.emptyMap();
|
||||
Map<String, String> tags = Collections.emptyMap();
|
||||
String traceId = "0";
|
||||
String spanId = "0";
|
||||
int samplingPriority = PrioritySampling.UNSET;
|
||||
|
||||
for (final Map.Entry<String, String> entry : carrier) {
|
||||
final String key = entry.getKey().toLowerCase();
|
||||
final String val = entry.getValue();
|
||||
|
||||
if (val == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TRACE_ID_KEY.equalsIgnoreCase(key)) {
|
||||
traceId = validateUInt64BitsID(val);
|
||||
} else if (SPAN_ID_KEY.equalsIgnoreCase(key)) {
|
||||
spanId = validateUInt64BitsID(val);
|
||||
} else if (key.startsWith(OT_BAGGAGE_PREFIX)) {
|
||||
if (baggage.isEmpty()) {
|
||||
baggage = new HashMap<>();
|
||||
}
|
||||
baggage.put(key.replace(OT_BAGGAGE_PREFIX, ""), decode(val));
|
||||
} else if (SAMPLING_PRIORITY_KEY.equalsIgnoreCase(key)) {
|
||||
samplingPriority = Integer.parseInt(val);
|
||||
}
|
||||
|
||||
if (taggedHeaders.containsKey(key)) {
|
||||
if (tags.isEmpty()) {
|
||||
tags = new HashMap<>();
|
||||
}
|
||||
tags.put(taggedHeaders.get(key), decode(val));
|
||||
}
|
||||
}
|
||||
|
||||
SpanContext context = null;
|
||||
if (!"0".equals(traceId)) {
|
||||
final ExtractedContext ctx =
|
||||
new ExtractedContext(traceId, spanId, samplingPriority, baggage, tags);
|
||||
ctx.lockSamplingPriority();
|
||||
|
||||
log.debug("{} - Parent context extracted", ctx.getTraceId());
|
||||
context = ctx;
|
||||
} else if (!tags.isEmpty()) {
|
||||
context = new TagContext(tags);
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
private String decode(final String value) {
|
||||
String decoded = value;
|
||||
try {
|
||||
decoded = URLDecoder.decode(value, "UTF-8");
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
log.info("Failed to decode value - {}", value);
|
||||
}
|
||||
return decoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to validate an ID String to verify that it is an unsigned 64 bits number and is
|
||||
* within range.
|
||||
*
|
||||
* @param val the String that contains the ID
|
||||
* @return the ID in String format if it passes validations
|
||||
* @throws IllegalArgumentException if val is not a number or if the number is out of range
|
||||
*/
|
||||
private String validateUInt64BitsID(final String val) throws IllegalArgumentException {
|
||||
try {
|
||||
final BigInteger validate = new BigInteger(val);
|
||||
if (validate.compareTo(BigInteger.ZERO) == -1
|
||||
|| validate.compareTo(BIG_INTEGER_UINT64_MAX) == 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"ID out of range, must be between 0 and 2^64-1, got: " + val);
|
||||
}
|
||||
return val;
|
||||
} catch (final NumberFormatException nfe) {
|
||||
throw new IllegalArgumentException(
|
||||
"Expecting a number for trace ID or span ID, but got: " + val, nfe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,147 +0,0 @@
|
|||
package datadog.opentracing.propagation;
|
||||
|
||||
import datadog.opentracing.DDSpanContext;
|
||||
import datadog.trace.api.sampling.PrioritySampling;
|
||||
import io.opentracing.SpanContext;
|
||||
import io.opentracing.propagation.TextMap;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/** A codec designed for HTTP transport via headers */
|
||||
@Slf4j
|
||||
public class HTTPCodec implements Codec<TextMap> {
|
||||
|
||||
// uint 64 bits max value, 2^64 - 1
|
||||
static final BigInteger BIG_INTEGER_UINT64_MAX =
|
||||
new BigInteger("2").pow(64).subtract(BigInteger.ONE);
|
||||
|
||||
private static final String OT_BAGGAGE_PREFIX = "ot-baggage-";
|
||||
private static final String TRACE_ID_KEY = "x-datadog-trace-id";
|
||||
private static final String SPAN_ID_KEY = "x-datadog-parent-id";
|
||||
private static final String SAMPLING_PRIORITY_KEY = "x-datadog-sampling-priority";
|
||||
|
||||
private final Map<String, String> taggedHeaders;
|
||||
|
||||
public HTTPCodec(final Map<String, String> taggedHeaders) {
|
||||
this.taggedHeaders = new HashMap<>();
|
||||
for (final Map.Entry<String, String> mapping : taggedHeaders.entrySet()) {
|
||||
this.taggedHeaders.put(mapping.getKey().trim().toLowerCase(), mapping.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject(final DDSpanContext context, final TextMap carrier) {
|
||||
carrier.put(TRACE_ID_KEY, String.valueOf(context.getTraceId()));
|
||||
carrier.put(SPAN_ID_KEY, String.valueOf(context.getSpanId()));
|
||||
if (context.lockSamplingPriority()) {
|
||||
carrier.put(SAMPLING_PRIORITY_KEY, String.valueOf(context.getSamplingPriority()));
|
||||
}
|
||||
|
||||
for (final Map.Entry<String, String> entry : context.baggageItems()) {
|
||||
carrier.put(OT_BAGGAGE_PREFIX + entry.getKey(), encode(entry.getValue()));
|
||||
}
|
||||
log.debug("{} - Parent context injected", context.getTraceId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpanContext extract(final TextMap carrier) {
|
||||
|
||||
Map<String, String> baggage = Collections.emptyMap();
|
||||
Map<String, String> tags = Collections.emptyMap();
|
||||
String traceId = "0";
|
||||
String spanId = "0";
|
||||
int samplingPriority = PrioritySampling.UNSET;
|
||||
|
||||
for (final Map.Entry<String, String> entry : carrier) {
|
||||
final String key = entry.getKey().toLowerCase();
|
||||
final String val = entry.getValue();
|
||||
|
||||
if (val == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TRACE_ID_KEY.equalsIgnoreCase(key)) {
|
||||
traceId = validateUInt64BitsID(val);
|
||||
} else if (SPAN_ID_KEY.equalsIgnoreCase(key)) {
|
||||
spanId = validateUInt64BitsID(val);
|
||||
} else if (key.startsWith(OT_BAGGAGE_PREFIX)) {
|
||||
if (baggage.isEmpty()) {
|
||||
baggage = new HashMap<>();
|
||||
}
|
||||
baggage.put(key.replace(OT_BAGGAGE_PREFIX, ""), decode(val));
|
||||
} else if (SAMPLING_PRIORITY_KEY.equalsIgnoreCase(key)) {
|
||||
samplingPriority = Integer.parseInt(val);
|
||||
}
|
||||
|
||||
if (taggedHeaders.containsKey(key)) {
|
||||
if (tags.isEmpty()) {
|
||||
tags = new HashMap<>();
|
||||
}
|
||||
tags.put(taggedHeaders.get(key), decode(val));
|
||||
}
|
||||
}
|
||||
|
||||
SpanContext context = null;
|
||||
if (!"0".equals(traceId)) {
|
||||
final ExtractedContext ctx =
|
||||
new ExtractedContext(traceId, spanId, samplingPriority, baggage, tags);
|
||||
ctx.lockSamplingPriority();
|
||||
|
||||
log.debug("{} - Parent context extracted", ctx.getTraceId());
|
||||
context = ctx;
|
||||
} else if (!tags.isEmpty()) {
|
||||
context = new TagContext(tags);
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
private String encode(final String value) {
|
||||
String encoded = value;
|
||||
try {
|
||||
encoded = URLEncoder.encode(value, "UTF-8");
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
log.info("Failed to encode value - {}", value);
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
private String decode(final String value) {
|
||||
String decoded = value;
|
||||
try {
|
||||
decoded = URLDecoder.decode(value, "UTF-8");
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
log.info("Failed to decode value - {}", value);
|
||||
}
|
||||
return decoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to validate an ID String to verify that it is an unsigned 64 bits number and is
|
||||
* within range.
|
||||
*
|
||||
* @param val the String that contains the ID
|
||||
* @return the ID in String format if it passes validations
|
||||
* @throws IllegalArgumentException if val is not a number or if the number is out of range
|
||||
*/
|
||||
private String validateUInt64BitsID(final String val) throws IllegalArgumentException {
|
||||
try {
|
||||
final BigInteger validate = new BigInteger(val);
|
||||
if (validate.compareTo(BigInteger.ZERO) == -1
|
||||
|| validate.compareTo(BIG_INTEGER_UINT64_MAX) == 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"ID out of range, must be between 0 and 2^64-1, got: " + val);
|
||||
}
|
||||
return val;
|
||||
} catch (final NumberFormatException nfe) {
|
||||
throw new IllegalArgumentException(
|
||||
"Expecting a number for trace ID or span ID, but got: " + val, nfe);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,160 +1,18 @@
|
|||
package datadog.opentracing.propagation
|
||||
|
||||
import datadog.opentracing.DDSpanContext
|
||||
import datadog.opentracing.DDTracer
|
||||
import datadog.opentracing.PendingTrace
|
||||
import datadog.trace.api.sampling.PrioritySampling
|
||||
import datadog.trace.common.writer.ListWriter
|
||||
import io.opentracing.propagation.TextMapExtractAdapter
|
||||
import io.opentracing.propagation.TextMapInjectAdapter
|
||||
import spock.lang.Shared
|
||||
import spock.lang.Specification
|
||||
|
||||
import static datadog.opentracing.propagation.HTTPCodec.BIG_INTEGER_UINT64_MAX
|
||||
import static datadog.opentracing.propagation.DatadogHttpCodec.BIG_INTEGER_UINT64_MAX
|
||||
import static datadog.opentracing.propagation.DatadogHttpCodec.OT_BAGGAGE_PREFIX
|
||||
import static datadog.opentracing.propagation.DatadogHttpCodec.SAMPLING_PRIORITY_KEY
|
||||
import static datadog.opentracing.propagation.DatadogHttpCodec.SPAN_ID_KEY
|
||||
import static datadog.opentracing.propagation.DatadogHttpCodec.TRACE_ID_KEY
|
||||
|
||||
class HTTPCodecTest extends Specification {
|
||||
@Shared
|
||||
private static final String OT_BAGGAGE_PREFIX = "ot-baggage-"
|
||||
@Shared
|
||||
private static final String TRACE_ID_KEY = "x-datadog-trace-id"
|
||||
@Shared
|
||||
private static final String SPAN_ID_KEY = "x-datadog-parent-id"
|
||||
@Shared
|
||||
private static final String SAMPLING_PRIORITY_KEY = "x-datadog-sampling-priority"
|
||||
class DatadogHttpExtractorTest extends Specification {
|
||||
|
||||
HTTPCodec codec = new HTTPCodec(["SOME_HEADER": "some-tag"])
|
||||
|
||||
def "inject http headers"() {
|
||||
setup:
|
||||
def writer = new ListWriter()
|
||||
def tracer = new DDTracer(writer)
|
||||
final DDSpanContext mockedContext =
|
||||
new DDSpanContext(
|
||||
"1",
|
||||
"2",
|
||||
"0",
|
||||
"fakeService",
|
||||
"fakeOperation",
|
||||
"fakeResource",
|
||||
samplingPriority,
|
||||
new HashMap<String, String>() {
|
||||
{
|
||||
put("k1", "v1")
|
||||
put("k2", "v2")
|
||||
}
|
||||
},
|
||||
false,
|
||||
"fakeType",
|
||||
null,
|
||||
new PendingTrace(tracer, "1", [:]),
|
||||
tracer)
|
||||
|
||||
final Map<String, String> carrier = new HashMap<>()
|
||||
|
||||
codec.inject(mockedContext, new TextMapInjectAdapter(carrier))
|
||||
|
||||
expect:
|
||||
carrier.get(TRACE_ID_KEY) == "1"
|
||||
carrier.get(SPAN_ID_KEY) == "2"
|
||||
carrier.get(SAMPLING_PRIORITY_KEY) == (samplingPriority == PrioritySampling.UNSET ? null : String.valueOf(samplingPriority))
|
||||
carrier.get(OT_BAGGAGE_PREFIX + "k1") == "v1"
|
||||
carrier.get(OT_BAGGAGE_PREFIX + "k2") == "v2"
|
||||
|
||||
where:
|
||||
samplingPriority | _
|
||||
PrioritySampling.UNSET | _
|
||||
PrioritySampling.SAMPLER_KEEP | _
|
||||
}
|
||||
|
||||
def "inject http headers with larger than Java long IDs"() {
|
||||
String largeTraceId = "9523372036854775807"
|
||||
String largeSpanId = "15815582334751494918"
|
||||
String largeParentId = "15815582334751494914"
|
||||
setup:
|
||||
def writer = new ListWriter()
|
||||
def tracer = new DDTracer(writer)
|
||||
final DDSpanContext mockedContext =
|
||||
new DDSpanContext(
|
||||
largeTraceId,
|
||||
largeSpanId,
|
||||
largeParentId,
|
||||
"fakeService",
|
||||
"fakeOperation",
|
||||
"fakeResource",
|
||||
samplingPriority,
|
||||
new HashMap<String, String>() {
|
||||
{
|
||||
put("k1", "v1")
|
||||
put("k2", "v2")
|
||||
}
|
||||
},
|
||||
false,
|
||||
"fakeType",
|
||||
null,
|
||||
new PendingTrace(tracer, largeTraceId, [:]),
|
||||
tracer)
|
||||
|
||||
final Map<String, String> carrier = new HashMap<>()
|
||||
|
||||
codec.inject(mockedContext, new TextMapInjectAdapter(carrier))
|
||||
|
||||
expect:
|
||||
carrier.get(TRACE_ID_KEY) == largeTraceId
|
||||
carrier.get(SPAN_ID_KEY) == largeSpanId
|
||||
carrier.get(SAMPLING_PRIORITY_KEY) == (samplingPriority == PrioritySampling.UNSET ? null : String.valueOf(samplingPriority))
|
||||
carrier.get(OT_BAGGAGE_PREFIX + "k1") == "v1"
|
||||
carrier.get(OT_BAGGAGE_PREFIX + "k2") == "v2"
|
||||
|
||||
where:
|
||||
samplingPriority | _
|
||||
PrioritySampling.UNSET | _
|
||||
PrioritySampling.SAMPLER_KEEP | _
|
||||
}
|
||||
|
||||
def "inject http headers with uint 64 max IDs"() {
|
||||
String largeTraceId = "18446744073709551615"
|
||||
String largeSpanId = "18446744073709551614"
|
||||
String largeParentId = "18446744073709551613"
|
||||
setup:
|
||||
def writer = new ListWriter()
|
||||
def tracer = new DDTracer(writer)
|
||||
final DDSpanContext mockedContext =
|
||||
new DDSpanContext(
|
||||
largeTraceId,
|
||||
largeSpanId,
|
||||
largeParentId,
|
||||
"fakeService",
|
||||
"fakeOperation",
|
||||
"fakeResource",
|
||||
samplingPriority,
|
||||
new HashMap<String, String>() {
|
||||
{
|
||||
put("k1", "v1")
|
||||
put("k2", "v2")
|
||||
}
|
||||
},
|
||||
false,
|
||||
"fakeType",
|
||||
null,
|
||||
new PendingTrace(tracer, largeTraceId, [:]),
|
||||
tracer)
|
||||
|
||||
final Map<String, String> carrier = new HashMap<>()
|
||||
|
||||
codec.inject(mockedContext, new TextMapInjectAdapter(carrier))
|
||||
|
||||
expect:
|
||||
carrier.get(TRACE_ID_KEY) == largeTraceId
|
||||
carrier.get(SPAN_ID_KEY) == largeSpanId
|
||||
carrier.get(SAMPLING_PRIORITY_KEY) == (samplingPriority == PrioritySampling.UNSET ? null : String.valueOf(samplingPriority))
|
||||
carrier.get(OT_BAGGAGE_PREFIX + "k1") == "v1"
|
||||
carrier.get(OT_BAGGAGE_PREFIX + "k2") == "v2"
|
||||
|
||||
where:
|
||||
samplingPriority | _
|
||||
PrioritySampling.UNSET | _
|
||||
PrioritySampling.SAMPLER_KEEP | _
|
||||
}
|
||||
DatadogHttpCodec.Extractor extractor = new DatadogHttpCodec.Extractor(["SOME_HEADER": "some-tag"])
|
||||
|
||||
def "extract http headers"() {
|
||||
setup:
|
||||
|
@ -170,7 +28,7 @@ class HTTPCodecTest extends Specification {
|
|||
actual.put(SAMPLING_PRIORITY_KEY, String.valueOf(samplingPriority))
|
||||
}
|
||||
|
||||
final ExtractedContext context = codec.extract(new TextMapExtractAdapter(actual))
|
||||
final ExtractedContext context = extractor.extract(new TextMapExtractAdapter(actual))
|
||||
|
||||
expect:
|
||||
context.getTraceId() == "1"
|
||||
|
@ -192,7 +50,7 @@ class HTTPCodecTest extends Specification {
|
|||
SOME_HEADER: "my-interesting-info",
|
||||
]
|
||||
|
||||
TagContext context = codec.extract(new TextMapExtractAdapter(actual))
|
||||
TagContext context = extractor.extract(new TextMapExtractAdapter(actual))
|
||||
|
||||
expect:
|
||||
!(context instanceof ExtractedContext)
|
||||
|
@ -201,7 +59,7 @@ class HTTPCodecTest extends Specification {
|
|||
|
||||
def "extract empty headers returns null"() {
|
||||
expect:
|
||||
codec.extract(new TextMapExtractAdapter(["ignored-header": "ignored-value"])) == null
|
||||
extractor.extract(new TextMapExtractAdapter(["ignored-header": "ignored-value"])) == null
|
||||
}
|
||||
|
||||
def "extract http headers with larger than Java long IDs"() {
|
||||
|
@ -220,7 +78,7 @@ class HTTPCodecTest extends Specification {
|
|||
actual.put(SAMPLING_PRIORITY_KEY, String.valueOf(samplingPriority))
|
||||
}
|
||||
|
||||
final ExtractedContext context = codec.extract(new TextMapExtractAdapter(actual))
|
||||
final ExtractedContext context = extractor.extract(new TextMapExtractAdapter(actual))
|
||||
|
||||
expect:
|
||||
context.getTraceId() == largeTraceId
|
||||
|
@ -251,7 +109,7 @@ class HTTPCodecTest extends Specification {
|
|||
actual.put(SAMPLING_PRIORITY_KEY, String.valueOf(samplingPriority))
|
||||
}
|
||||
|
||||
final ExtractedContext context = codec.extract(new TextMapExtractAdapter(actual))
|
||||
final ExtractedContext context = extractor.extract(new TextMapExtractAdapter(actual))
|
||||
|
||||
expect:
|
||||
context.getTraceId() == BIG_INTEGER_UINT64_MAX.toString()
|
||||
|
@ -282,7 +140,7 @@ class HTTPCodecTest extends Specification {
|
|||
}
|
||||
|
||||
when:
|
||||
codec.extract(new TextMapExtractAdapter(actual))
|
||||
extractor.extract(new TextMapExtractAdapter(actual))
|
||||
|
||||
then:
|
||||
def iae = thrown(IllegalArgumentException)
|
||||
|
@ -310,7 +168,7 @@ class HTTPCodecTest extends Specification {
|
|||
}
|
||||
|
||||
when:
|
||||
codec.extract(new TextMapExtractAdapter(actual))
|
||||
extractor.extract(new TextMapExtractAdapter(actual))
|
||||
|
||||
then:
|
||||
thrown(IllegalArgumentException)
|
||||
|
@ -336,7 +194,7 @@ class HTTPCodecTest extends Specification {
|
|||
}
|
||||
|
||||
when:
|
||||
codec.extract(new TextMapExtractAdapter(actual))
|
||||
extractor.extract(new TextMapExtractAdapter(actual))
|
||||
|
||||
then:
|
||||
thrown(IllegalArgumentException)
|
|
@ -0,0 +1,151 @@
|
|||
package datadog.opentracing.propagation
|
||||
|
||||
import datadog.opentracing.DDSpanContext
|
||||
import datadog.opentracing.DDTracer
|
||||
import datadog.opentracing.PendingTrace
|
||||
import datadog.trace.api.sampling.PrioritySampling
|
||||
import datadog.trace.common.writer.ListWriter
|
||||
import io.opentracing.propagation.TextMapInjectAdapter
|
||||
import spock.lang.Specification
|
||||
|
||||
import static datadog.opentracing.propagation.DatadogHttpCodec.OT_BAGGAGE_PREFIX
|
||||
import static datadog.opentracing.propagation.DatadogHttpCodec.SAMPLING_PRIORITY_KEY
|
||||
import static datadog.opentracing.propagation.DatadogHttpCodec.SPAN_ID_KEY
|
||||
import static datadog.opentracing.propagation.DatadogHttpCodec.TRACE_ID_KEY
|
||||
|
||||
class DatadogHttpInjectorTest extends Specification {
|
||||
|
||||
DatadogHttpCodec.Injector injector = new DatadogHttpCodec.Injector()
|
||||
|
||||
def "inject http headers"() {
|
||||
setup:
|
||||
def writer = new ListWriter()
|
||||
def tracer = new DDTracer(writer)
|
||||
final DDSpanContext mockedContext =
|
||||
new DDSpanContext(
|
||||
"1",
|
||||
"2",
|
||||
"0",
|
||||
"fakeService",
|
||||
"fakeOperation",
|
||||
"fakeResource",
|
||||
samplingPriority,
|
||||
new HashMap<String, String>() {
|
||||
{
|
||||
put("k1", "v1")
|
||||
put("k2", "v2")
|
||||
}
|
||||
},
|
||||
false,
|
||||
"fakeType",
|
||||
null,
|
||||
new PendingTrace(tracer, "1", [:]),
|
||||
tracer)
|
||||
|
||||
final Map<String, String> carrier = new HashMap<>()
|
||||
|
||||
injector.inject(mockedContext, new TextMapInjectAdapter(carrier))
|
||||
|
||||
expect:
|
||||
carrier.get(TRACE_ID_KEY) == "1"
|
||||
carrier.get(SPAN_ID_KEY) == "2"
|
||||
carrier.get(SAMPLING_PRIORITY_KEY) == (samplingPriority == PrioritySampling.UNSET ? null : String.valueOf(samplingPriority))
|
||||
carrier.get(OT_BAGGAGE_PREFIX + "k1") == "v1"
|
||||
carrier.get(OT_BAGGAGE_PREFIX + "k2") == "v2"
|
||||
|
||||
where:
|
||||
samplingPriority | _
|
||||
PrioritySampling.UNSET | _
|
||||
PrioritySampling.SAMPLER_KEEP | _
|
||||
}
|
||||
|
||||
def "inject http headers with larger than Java long IDs"() {
|
||||
String largeTraceId = "9523372036854775807"
|
||||
String largeSpanId = "15815582334751494918"
|
||||
String largeParentId = "15815582334751494914"
|
||||
setup:
|
||||
def writer = new ListWriter()
|
||||
def tracer = new DDTracer(writer)
|
||||
final DDSpanContext mockedContext =
|
||||
new DDSpanContext(
|
||||
largeTraceId,
|
||||
largeSpanId,
|
||||
largeParentId,
|
||||
"fakeService",
|
||||
"fakeOperation",
|
||||
"fakeResource",
|
||||
samplingPriority,
|
||||
new HashMap<String, String>() {
|
||||
{
|
||||
put("k1", "v1")
|
||||
put("k2", "v2")
|
||||
}
|
||||
},
|
||||
false,
|
||||
"fakeType",
|
||||
null,
|
||||
new PendingTrace(tracer, largeTraceId, [:]),
|
||||
tracer)
|
||||
|
||||
final Map<String, String> carrier = new HashMap<>()
|
||||
|
||||
injector.inject(mockedContext, new TextMapInjectAdapter(carrier))
|
||||
|
||||
expect:
|
||||
carrier.get(TRACE_ID_KEY) == largeTraceId
|
||||
carrier.get(SPAN_ID_KEY) == largeSpanId
|
||||
carrier.get(SAMPLING_PRIORITY_KEY) == (samplingPriority == PrioritySampling.UNSET ? null : String.valueOf(samplingPriority))
|
||||
carrier.get(OT_BAGGAGE_PREFIX + "k1") == "v1"
|
||||
carrier.get(OT_BAGGAGE_PREFIX + "k2") == "v2"
|
||||
|
||||
where:
|
||||
samplingPriority | _
|
||||
PrioritySampling.UNSET | _
|
||||
PrioritySampling.SAMPLER_KEEP | _
|
||||
}
|
||||
|
||||
def "inject http headers with uint 64 max IDs"() {
|
||||
String largeTraceId = "18446744073709551615"
|
||||
String largeSpanId = "18446744073709551614"
|
||||
String largeParentId = "18446744073709551613"
|
||||
setup:
|
||||
def writer = new ListWriter()
|
||||
def tracer = new DDTracer(writer)
|
||||
final DDSpanContext mockedContext =
|
||||
new DDSpanContext(
|
||||
largeTraceId,
|
||||
largeSpanId,
|
||||
largeParentId,
|
||||
"fakeService",
|
||||
"fakeOperation",
|
||||
"fakeResource",
|
||||
samplingPriority,
|
||||
new HashMap<String, String>() {
|
||||
{
|
||||
put("k1", "v1")
|
||||
put("k2", "v2")
|
||||
}
|
||||
},
|
||||
false,
|
||||
"fakeType",
|
||||
null,
|
||||
new PendingTrace(tracer, largeTraceId, [:]),
|
||||
tracer)
|
||||
|
||||
final Map<String, String> carrier = new HashMap<>()
|
||||
|
||||
injector.inject(mockedContext, new TextMapInjectAdapter(carrier))
|
||||
|
||||
expect:
|
||||
carrier.get(TRACE_ID_KEY) == largeTraceId
|
||||
carrier.get(SPAN_ID_KEY) == largeSpanId
|
||||
carrier.get(SAMPLING_PRIORITY_KEY) == (samplingPriority == PrioritySampling.UNSET ? null : String.valueOf(samplingPriority))
|
||||
carrier.get(OT_BAGGAGE_PREFIX + "k1") == "v1"
|
||||
carrier.get(OT_BAGGAGE_PREFIX + "k2") == "v2"
|
||||
|
||||
where:
|
||||
samplingPriority | _
|
||||
PrioritySampling.UNSET | _
|
||||
PrioritySampling.SAMPLER_KEEP | _
|
||||
}
|
||||
}
|
|
@ -78,7 +78,7 @@ class DDTracerTest extends Specification {
|
|||
when:
|
||||
def config = new Config()
|
||||
def tracer = new DDTracer(config)
|
||||
def taggedHeaders = tracer.registry.codecs.values().first().taggedHeaders
|
||||
def taggedHeaders = tracer.extractor.taggedHeaders
|
||||
|
||||
then:
|
||||
tracer.defaultSpanTags == map
|
||||
|
|
Loading…
Reference in New Issue