implementing add reference to work with opentracing-spring-cloud-starter
MODIFY
dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java
dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java
@@ -17,6 +17,7 @@ import datadog.trace.common.sampling.Sampler;
import datadog.trace.common.writer.DDAgentWriter;
import datadog.trace.common.writer.DDApi;
import datadog.trace.common.writer.Writer;
+import io.opentracing.References;
import io.opentracing.Scope;
import io.opentracing.ScopeManager;
import io.opentracing.Span;
@@ -496,7 +497,21 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
@Override
public DDSpanBuilder addReference(final String referenceType, final SpanContext spanContext) {
- log.debug("`addReference` method is not implemented. Doing nothing");
+ if (spanContext == null) {
+ return this;
+ }
+ if (!(spanContext instanceof ExtractedContext) && !(spanContext instanceof DDSpanContext)) {
+ log.debug(
+ "Expected to have a DDSpanContext or ExtractedContext but got "
+ + spanContext.getClass().getName());
+ return this;
+ }
+ if (References.CHILD_OF.equals(referenceType)
+ || References.FOLLOWS_FROM.equals(referenceType)) {
+ return asChildOf(spanContext);
+ } else {
+ log.debug("Only support reference type of CHILD_OF and FOLLOWS_FROM");
+ }
return this;
}

MODIFY
dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanBuilderTest.groovy
dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanBuilderTest.groovy
@@ -225,6 +225,130 @@ class DDSpanBuilderTest extends Specification {
span.context().getSpanType() == expectedChildType
}
+
+ def "should inherit the DD parent attributes addReference CHILD_OF"() {
+ setup:
+ def expectedName = "fakeName"
+ def expectedParentServiceName = "fakeServiceName"
+ def expectedParentResourceName = "fakeResourceName"
+ def expectedParentType = "fakeType"
+ def expectedChildServiceName = "fakeServiceName-child"
+ def expectedChildResourceName = "fakeResourceName-child"
+ def expectedChildType = "fakeType-child"
+ def expectedBaggageItemKey = "fakeKey"
+ def expectedBaggageItemValue = "fakeValue"
+
+ final DDSpan parent =
+ tracer
+ .buildSpan(expectedName)
+ .withServiceName("foo")
+ .withResourceName(expectedParentResourceName)
+ .withSpanType(expectedParentType)
+ .start()
+
+ parent.setBaggageItem(expectedBaggageItemKey, expectedBaggageItemValue)
+
+ // ServiceName and SpanType are always set by the parent if they are not present in the child
+ DDSpan span =
+ tracer
+ .buildSpan(expectedName)
+ .withServiceName(expectedParentServiceName)
+ .addReference("child_of", parent.context())
+ .start()
+
+ println span.getBaggageItem(expectedBaggageItemKey)
+ println expectedBaggageItemValue
+ println span.context().getSpanType()
+ println expectedParentType
+
+ expect:
+ span.getOperationName() == expectedName
+ span.getBaggageItem(expectedBaggageItemKey) == expectedBaggageItemValue
+ span.context().getServiceName() == expectedParentServiceName
+ span.context().getResourceName() == expectedName
+ span.context().getSpanType() == expectedParentType
+
+ when:
+ // ServiceName and SpanType are always overwritten by the child if they are present
+ span =
+ tracer
+ .buildSpan(expectedName)
+ .withServiceName(expectedChildServiceName)
+ .withResourceName(expectedChildResourceName)
+ .withSpanType(expectedChildType)
+ .addReference("child_of", parent.context())
+ .start()
+
+ then:
+ span.getOperationName() == expectedName
+ span.getBaggageItem(expectedBaggageItemKey) == expectedBaggageItemValue
+ span.context().getServiceName() == expectedChildServiceName
+ span.context().getResourceName() == expectedChildResourceName
+ span.context().getSpanType() == expectedChildType
+ }
+
+
+ def "should inherit the DD parent attributes add reference FOLLOWS_FROM"() {
+ setup:
+ def expectedName = "fakeName"
+ def expectedParentServiceName = "fakeServiceName"
+ def expectedParentResourceName = "fakeResourceName"
+ def expectedParentType = "fakeType"
+ def expectedChildServiceName = "fakeServiceName-child"
+ def expectedChildResourceName = "fakeResourceName-child"
+ def expectedChildType = "fakeType-child"
+ def expectedBaggageItemKey = "fakeKey"
+ def expectedBaggageItemValue = "fakeValue"
+
+ final DDSpan parent =
+ tracer
+ .buildSpan(expectedName)
+ .withServiceName("foo")
+ .withResourceName(expectedParentResourceName)
+ .withSpanType(expectedParentType)
+ .start()
+
+ parent.setBaggageItem(expectedBaggageItemKey, expectedBaggageItemValue)
+
+ // ServiceName and SpanType are always set by the parent if they are not present in the child
+ DDSpan span =
+ tracer
+ .buildSpan(expectedName)
+ .withServiceName(expectedParentServiceName)
+ .addReference("follows_from", parent.context())
+ .start()
+
+ println span.getBaggageItem(expectedBaggageItemKey)
+ println expectedBaggageItemValue
+ println span.context().getSpanType()
+ println expectedParentType
+
+ expect:
+ span.getOperationName() == expectedName
+ span.getBaggageItem(expectedBaggageItemKey) == expectedBaggageItemValue
+ span.context().getServiceName() == expectedParentServiceName
+ span.context().getResourceName() == expectedName
+ span.context().getSpanType() == expectedParentType
+
+ when:
+ // ServiceName and SpanType are always overwritten by the child if they are present
+ span =
+ tracer
+ .buildSpan(expectedName)
+ .withServiceName(expectedChildServiceName)
+ .withResourceName(expectedChildResourceName)
+ .withSpanType(expectedChildType)
+ .addReference("follows_from", parent.context())
+ .start()
+
+ then:
+ span.getOperationName() == expectedName
+ span.getBaggageItem(expectedBaggageItemKey) == expectedBaggageItemValue
+ span.context().getServiceName() == expectedChildServiceName
+ span.context().getResourceName() == expectedChildResourceName
+ span.context().getSpanType() == expectedChildType
+ }
+
def "should track all spans in trace"() {
setup:
List<DDSpan> spans = []

implementing add reference to work with opentracing-spring-cloud-starter