Add isRemote to the SpanContext (#626)

Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com>
This commit is contained in:
Bogdan Drutu 2019-10-24 08:22:55 -07:00 committed by GitHub
parent c24e4a9636
commit 0b21928db5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 91 additions and 27 deletions

View File

@ -36,12 +36,14 @@ public final class SpanContext {
TraceId.getInvalid(),
SpanId.getInvalid(),
TraceFlags.getDefault(),
Tracestate.getDefault());
Tracestate.getDefault(),
/* isRemote= */ false);
private final TraceId traceId;
private final SpanId spanId;
private final TraceFlags traceFlags;
private final Tracestate tracestate;
private final boolean isRemote;
/**
* Returns the invalid {@code SpanContext} that can be used for no-op operations.
@ -64,7 +66,23 @@ public final class SpanContext {
*/
public static SpanContext create(
TraceId traceId, SpanId spanId, TraceFlags traceFlags, Tracestate tracestate) {
return new SpanContext(traceId, spanId, traceFlags, tracestate);
return new SpanContext(traceId, spanId, traceFlags, tracestate, /* isRemote= */ false);
}
/**
* Creates a new {@code SpanContext} that was propagated from a remote parent, with the given
* identifiers and options.
*
* @param traceId the trace identifier of the span context.
* @param spanId the span identifier of the span context.
* @param traceFlags the trace options for the span context.
* @param tracestate the trace state for the span context.
* @return a new {@code SpanContext} with the given identifiers and options.
* @since 0.1.0
*/
public static SpanContext createFromRemoteParent(
TraceId traceId, SpanId spanId, TraceFlags traceFlags, Tracestate tracestate) {
return new SpanContext(traceId, spanId, traceFlags, tracestate, /* isRemote= */ true);
}
/**
@ -108,15 +126,25 @@ public final class SpanContext {
}
/**
* Returns true if this {@code SpanContext} is valid.
* Returns {@code true} if this {@code SpanContext} is valid.
*
* @return true if this {@code SpanContext} is valid.
* @return {@code true} if this {@code SpanContext} is valid.
* @since 0.1.0
*/
public boolean isValid() {
return traceId.isValid() && spanId.isValid();
}
/**
* Returns {@code true} if the {@code SpanContext} was propagated from a remote parent.
*
* @return {@code true} if the {@code SpanContext} was propagated from a remote parent.
* @since 0.1.0
*/
public boolean isRemote() {
return isRemote;
}
@Override
public boolean equals(@Nullable Object obj) {
if (obj == this) {
@ -130,7 +158,8 @@ public final class SpanContext {
SpanContext that = (SpanContext) obj;
return traceId.equals(that.traceId)
&& spanId.equals(that.spanId)
&& traceFlags.equals(that.traceFlags);
&& traceFlags.equals(that.traceFlags)
&& isRemote == that.isRemote;
}
@Override
@ -146,14 +175,21 @@ public final class SpanContext {
+ spanId
+ ", traceFlags="
+ traceFlags
+ ", isRemote="
+ isRemote
+ "}";
}
private SpanContext(
TraceId traceId, SpanId spanId, TraceFlags traceFlags, Tracestate tracestate) {
TraceId traceId,
SpanId spanId,
TraceFlags traceFlags,
Tracestate tracestate,
boolean isRemote) {
this.traceId = traceId;
this.spanId = spanId;
this.traceFlags = traceFlags;
this.tracestate = tracestate;
this.isRemote = isRemote;
}
}

View File

@ -146,6 +146,6 @@ public final class BinaryTraceContext implements BinaryFormat<SpanContext> {
}
traceFlags = TraceFlags.fromByte(bytes[pos + ID_SIZE]);
}
return SpanContext.create(traceId, spanId, traceFlags, TRACESTATE_DEFAULT);
return SpanContext.createFromRemoteParent(traceId, spanId, traceFlags, TRACESTATE_DEFAULT);
}
}

View File

@ -134,7 +134,7 @@ public class HttpTraceContext implements HttpTextFormat<SpanContext> {
String tracestate = getter.get(carrier, TRACESTATE);
try {
if (tracestate == null || tracestate.isEmpty()) {
return SpanContext.create(traceId, spanId, traceFlags, TRACESTATE_DEFAULT);
return SpanContext.createFromRemoteParent(traceId, spanId, traceFlags, TRACESTATE_DEFAULT);
}
Tracestate.Builder tracestateBuilder = Tracestate.builder();
String[] listMembers = TRACESTATE_ENTRY_DELIMITER_SPLIT_PATTERN.split(tracestate);
@ -148,7 +148,8 @@ public class HttpTraceContext implements HttpTextFormat<SpanContext> {
checkArgument(index != -1, "Invalid tracestate list-member format.");
tracestateBuilder.set(listMember.substring(0, index), listMember.substring(index + 1));
}
return SpanContext.create(traceId, spanId, traceFlags, tracestateBuilder.build());
return SpanContext.createFromRemoteParent(
traceId, spanId, traceFlags, tracestateBuilder.build());
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Invalid tracestate: " + tracestate, e);
}

View File

@ -47,6 +47,12 @@ public class SpanContextTest {
SpanId.fromBytes(secondSpanIdBytes, 0),
TraceFlags.builder().setIsSampled(true).build(),
secondTracestate);
private static final SpanContext remote =
SpanContext.createFromRemoteParent(
TraceId.fromBytes(secondTraceIdBytes, 0),
SpanId.fromBytes(secondSpanIdBytes, 0),
TraceFlags.builder().setIsSampled(true).build(),
emptyTracestate);
@Test
public void invalidSpanContext() {
@ -102,6 +108,13 @@ public class SpanContextTest {
assertThat(second.getTracestate()).isEqualTo(secondTracestate);
}
@Test
public void isRemote() {
assertThat(first.isRemote()).isFalse();
assertThat(second.isRemote()).isFalse();
assertThat(remote.isRemote()).isTrue();
}
@Test
public void spanContext_EqualsAndHashCode() {
EqualsTester tester = new EqualsTester();
@ -124,6 +137,13 @@ public class SpanContextTest {
SpanId.fromBytes(secondSpanIdBytes, 0),
TraceFlags.builder().setIsSampled(true).build(),
secondTracestate));
tester.addEqualityGroup(
remote,
SpanContext.createFromRemoteParent(
TraceId.fromBytes(secondTraceIdBytes, 0),
SpanId.fromBytes(secondSpanIdBytes, 0),
TraceFlags.builder().setIsSampled(true).build(),
emptyTracestate));
tester.testEquals();
}

View File

@ -17,7 +17,6 @@
package io.opentelemetry.trace.propagation;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import io.opentelemetry.context.propagation.BinaryFormat;
import io.opentelemetry.trace.DefaultSpan;
@ -48,8 +47,6 @@ public class BinaryTraceContextTest {
0, 0, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 1, 97, 98, 99, 100,
101, 102, 103, 104, 2, 1
};
private static final SpanContext EXAMPLE_SPAN_CONTEXT =
SpanContext.create(TRACE_ID, SPAN_ID, TRACE_OPTIONS, Tracestate.getDefault());
private static final SpanContext INVALID_SPAN_CONTEXT = DefaultSpan.getInvalid().getContext();
@Rule public ExpectedException expectedException = ExpectedException.none();
private final BinaryFormat<SpanContext> binaryFormat = new BinaryTraceContext();
@ -58,9 +55,9 @@ public class BinaryTraceContextTest {
SpanContext propagatedBinarySpanContext =
binaryFormat.fromByteArray(binaryFormat.toByteArray(spanContext));
assertWithMessage("BinaryFormat propagated context is not equal with the initial context.")
.that(propagatedBinarySpanContext)
.isEqualTo(spanContext);
assertThat(propagatedBinarySpanContext.getTraceId()).isEqualTo(spanContext.getTraceId());
assertThat(propagatedBinarySpanContext.getSpanId()).isEqualTo(spanContext.getSpanId());
assertThat(propagatedBinarySpanContext.getTraceFlags()).isEqualTo(spanContext.getTraceFlags());
}
@Test
@ -95,7 +92,10 @@ public class BinaryTraceContextTest {
@Test
public void fromBinaryValue_BinaryExampleValue() {
assertThat(binaryFormat.fromByteArray(EXAMPLE_BYTES)).isEqualTo(EXAMPLE_SPAN_CONTEXT);
assertThat(binaryFormat.fromByteArray(EXAMPLE_BYTES))
.isEqualTo(
SpanContext.createFromRemoteParent(
TRACE_ID, SPAN_ID, TRACE_OPTIONS, Tracestate.getDefault()));
}
@Test(expected = NullPointerException.class)

View File

@ -128,7 +128,8 @@ public class HttpTraceContextTest {
carrier.put(TRACEPARENT, TRACEPARENT_HEADER_SAMPLED);
assertThat(httpTraceContext.extract(carrier, getter))
.isEqualTo(
SpanContext.create(TRACE_ID, SPAN_ID, SAMPLED_TRACE_OPTIONS, TRACESTATE_DEFAULT));
SpanContext.createFromRemoteParent(
TRACE_ID, SPAN_ID, SAMPLED_TRACE_OPTIONS, TRACESTATE_DEFAULT));
}
@Test
@ -137,7 +138,8 @@ public class HttpTraceContextTest {
carrier.put(TRACEPARENT, TRACEPARENT_HEADER_NOT_SAMPLED);
assertThat(httpTraceContext.extract(carrier, getter))
.isEqualTo(
SpanContext.create(TRACE_ID, SPAN_ID, TraceFlags.getDefault(), TRACESTATE_DEFAULT));
SpanContext.createFromRemoteParent(
TRACE_ID, SPAN_ID, TraceFlags.getDefault(), TRACESTATE_DEFAULT));
}
@Test
@ -147,46 +149,51 @@ public class HttpTraceContextTest {
carrier.put(TRACESTATE, TRACESTATE_NOT_DEFAULT_ENCODING);
assertThat(httpTraceContext.extract(carrier, getter))
.isEqualTo(
SpanContext.create(TRACE_ID, SPAN_ID, SAMPLED_TRACE_OPTIONS, TRACESTATE_NOT_DEFAULT));
SpanContext.createFromRemoteParent(
TRACE_ID, SPAN_ID, SAMPLED_TRACE_OPTIONS, TRACESTATE_NOT_DEFAULT));
}
@Test
public void extract_NotSampledContext_WithTraceState() {
Map<String, String> carrier = new LinkedHashMap<String, String>();
Map<String, String> carrier = new LinkedHashMap<>();
carrier.put(TRACEPARENT, TRACEPARENT_HEADER_NOT_SAMPLED);
carrier.put(TRACESTATE, TRACESTATE_NOT_DEFAULT_ENCODING);
assertThat(httpTraceContext.extract(carrier, getter))
.isEqualTo(
SpanContext.create(TRACE_ID, SPAN_ID, TraceFlags.getDefault(), TRACESTATE_NOT_DEFAULT));
SpanContext.createFromRemoteParent(
TRACE_ID, SPAN_ID, TraceFlags.getDefault(), TRACESTATE_NOT_DEFAULT));
}
@Test
public void extract_NotSampledContext_NextVersion() {
Map<String, String> carrier = new LinkedHashMap<String, String>();
Map<String, String> carrier = new LinkedHashMap<>();
carrier.put(TRACEPARENT, "01-" + TRACE_ID_BASE16 + "-" + SPAN_ID_BASE16 + "-00-02");
assertThat(httpTraceContext.extract(carrier, getter))
.isEqualTo(
SpanContext.create(TRACE_ID, SPAN_ID, TraceFlags.getDefault(), TRACESTATE_DEFAULT));
SpanContext.createFromRemoteParent(
TRACE_ID, SPAN_ID, TraceFlags.getDefault(), TRACESTATE_DEFAULT));
}
@Test
public void extract_NotSampledContext_EmptyTraceState() {
Map<String, String> carrier = new LinkedHashMap<String, String>();
Map<String, String> carrier = new LinkedHashMap<>();
carrier.put(TRACEPARENT, TRACEPARENT_HEADER_NOT_SAMPLED);
carrier.put(TRACESTATE, "");
assertThat(httpTraceContext.extract(carrier, getter))
.isEqualTo(
SpanContext.create(TRACE_ID, SPAN_ID, TraceFlags.getDefault(), TRACESTATE_DEFAULT));
SpanContext.createFromRemoteParent(
TRACE_ID, SPAN_ID, TraceFlags.getDefault(), TRACESTATE_DEFAULT));
}
@Test
public void extract_NotSampledContext_TraceStateWithSpaces() {
Map<String, String> carrier = new LinkedHashMap<String, String>();
Map<String, String> carrier = new LinkedHashMap<>();
carrier.put(TRACEPARENT, TRACEPARENT_HEADER_NOT_SAMPLED);
carrier.put(TRACESTATE, "foo=bar , bar=baz");
assertThat(httpTraceContext.extract(carrier, getter))
.isEqualTo(
SpanContext.create(TRACE_ID, SPAN_ID, TraceFlags.getDefault(), TRACESTATE_NOT_DEFAULT));
SpanContext.createFromRemoteParent(
TRACE_ID, SPAN_ID, TraceFlags.getDefault(), TRACESTATE_NOT_DEFAULT));
}
@Test