Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

Add SELF reference #212

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions opentracing-api/src/main/java/io/opentracing/References.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,9 @@ private References(){}
* See http://opentracing.io/spec/#causal-span-references for more information about FOLLOWS_FROM references
*/
public static final String FOLLOWS_FROM = "follows_from";

/**
* The self reference class can be used to construct a {@link Span} instance with a specific {@link SpanContext}.
*/
public static final String SELF = "self";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tedsuo should this go through Specification RFC first?

If we are making this a new required reference type, there needs to be more details about the expected tracer behavior and/or description of the use case. For example, what happens to startTime field in this case?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, just seeing this! Yes, @felixbarny an RFC would be appreciated, you can find the template here: https://github.com/opentracing/specification/blob/master/rfc_template.md

}
28 changes: 22 additions & 6 deletions opentracing-mock/src/main/java/io/opentracing/mock/MockSpan.java
Original file line number Diff line number Diff line change
Expand Up @@ -285,27 +285,43 @@ public int hashCode() {
this.references = new ArrayList<>(refs);
}
MockContext parent = findPreferredParentRef(this.references);
MockContext self = findFirstReference(this.references, References.SELF);
if (parent == null) {
// We're a root Span.
this.context = new MockContext(nextId(), nextId(), new HashMap<String, String>());
this.context = new MockContext(self != null ? self.traceId : nextId(), self != null ? self.spanId : nextId(),
new HashMap<String, String>());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't baggage come from self as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

this.parentId = 0;
} else {
// We're a child Span.
this.context = new MockContext(parent.traceId, nextId(), mergeBaggages(this.references));
this.context = new MockContext(self != null ? self.traceId : parent.traceId, self != null ? self.spanId : nextId(),
mergeBaggages(this.references));
this.parentId = parent.spanId;
}
}

private static MockContext findPreferredParentRef(List<Reference> references) {
if(references.isEmpty()) {
return null;
MockContext firstChildOf = findFirstReference(references, References.CHILD_OF);
if (firstChildOf == null) {
// return first non self reference
// self references can never be a parent reference
for (Reference reference : references) {
if (!References.SELF.equals(reference.getReferenceType())) {
return reference.getContext();
}
}
} else {
return firstChildOf;
}
return null;
}

private static MockContext findFirstReference(List<Reference> references, String referenceToFind) {
for (Reference reference : references) {
if (References.CHILD_OF.equals(reference.getReferenceType())) {
if (referenceToFind.equals(reference.getReferenceType())) {
return reference.getContext();
}
}
return references.get(0).getContext();
return null;
}

private static Map<String, String> mergeBaggages(List<Reference> references) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,12 @@ public <C> MockSpan.MockContext extract(Format<C> format, C carrier) {
}
};

Propagator TEXT_MAP = new Propagator() {
public static final String SPAN_ID_KEY = "spanid";
public static final String TRACE_ID_KEY = "traceid";
public static final String BAGGAGE_KEY_PREFIX = "baggage-";
Propagator TEXT_MAP = new TextMapPropagator();

class TextMapPropagator implements Propagator {
static final String SPAN_ID_KEY = "spanid";
static final String TRACE_ID_KEY = "traceid";
static final String BAGGAGE_KEY_PREFIX = "baggage-";

@Override
public <C> void inject(MockSpan.MockContext ctx, Format<C> format, C carrier) {
Expand Down Expand Up @@ -159,7 +161,7 @@ public <C> MockSpan.MockContext extract(Format<C> format, C carrier) {

return null;
}
};
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
*/
package io.opentracing.mock;

import static io.opentracing.mock.MockTracer.Propagator.TextMapPropagator.SPAN_ID_KEY;
import static io.opentracing.mock.MockTracer.Propagator.TextMapPropagator.TRACE_ID_KEY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
Expand Down Expand Up @@ -201,7 +203,7 @@ public void testTextMapPropagatorHttpHeaders() {
Assert.assertEquals(finishedSpans.get(0).context().traceId(), finishedSpans.get(1).context().traceId());
Assert.assertEquals(finishedSpans.get(0).context().spanId(), finishedSpans.get(1).parentId());
}

@Test
public void testActiveSpan() {
MockTracer mockTracer = new MockTracer();
Expand Down Expand Up @@ -319,4 +321,46 @@ public void testChildOfWithNullParentDoesNotThrowException() {
Span span = tracer.buildSpan("foo").asChildOf(parent).start();
span.finish();
}

@Test
public void testSelfReferenceWithParent() {
MockTracer mockTracer = new MockTracer(MockTracer.Propagator.TEXT_MAP);

final HashMap<String, String> selfIds = new HashMap<>();
selfIds.put(TRACE_ID_KEY, "40");
selfIds.put(SPAN_ID_KEY, "42");
final HashMap<String, String> parentSpanId = new HashMap<>();
parentSpanId.put(TRACE_ID_KEY, "40");
parentSpanId.put(SPAN_ID_KEY, "41");

mockTracer.buildSpan("foo")
.addReference(References.SELF, mockTracer.extract(Format.Builtin.TEXT_MAP, new TextMapExtractAdapter(selfIds)))
.addReference(References.CHILD_OF, mockTracer.extract(Format.Builtin.TEXT_MAP, new TextMapExtractAdapter(parentSpanId)))
.startManual()
.finish();

assertEquals(1, mockTracer.finishedSpans().size());
assertEquals(40, mockTracer.finishedSpans().get(0).context().traceId());
assertEquals(42, mockTracer.finishedSpans().get(0).context().spanId());
assertEquals(41, mockTracer.finishedSpans().get(0).parentId());
}

@Test
public void testSelfReferenceWithoutParent() {
MockTracer mockTracer = new MockTracer(MockTracer.Propagator.TEXT_MAP);

final HashMap<String, String> selfIds = new HashMap<>();
selfIds.put(TRACE_ID_KEY, "40");
selfIds.put(SPAN_ID_KEY, "42");

mockTracer.buildSpan("foo")
.addReference(References.SELF, mockTracer.extract(Format.Builtin.TEXT_MAP, new TextMapExtractAdapter(selfIds)))
.startManual()
.finish();

assertEquals(1, mockTracer.finishedSpans().size());
assertEquals(40, mockTracer.finishedSpans().get(0).context().traceId());
assertEquals(42, mockTracer.finishedSpans().get(0).context().spanId());
assertEquals(0, mockTracer.finishedSpans().get(0).parentId());
}
}