From 8cab661e5681afb3117a72864ae3733b27a1bc77 Mon Sep 17 00:00:00 2001 From: Anuraag Agrawal Date: Fri, 30 Oct 2020 14:32:42 +0900 Subject: [PATCH 1/4] Split SpanContext into interface / impl --- .../api/trace/ImmutableSpanContext.java | 76 +++++++++++++++++++ .../opentelemetry/api/trace/SpanContext.java | 69 ++++++----------- 2 files changed, 98 insertions(+), 47 deletions(-) create mode 100644 api/src/main/java/io/opentelemetry/api/trace/ImmutableSpanContext.java diff --git a/api/src/main/java/io/opentelemetry/api/trace/ImmutableSpanContext.java b/api/src/main/java/io/opentelemetry/api/trace/ImmutableSpanContext.java new file mode 100644 index 00000000000..c18d2b0adc1 --- /dev/null +++ b/api/src/main/java/io/opentelemetry/api/trace/ImmutableSpanContext.java @@ -0,0 +1,76 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.trace; + +import com.google.auto.value.AutoValue; +import com.google.auto.value.extension.memoized.Memoized; +import javax.annotation.concurrent.Immutable; + +/** + * A class that represents a span context. A span context contains the state that must propagate to + * child {@link Span}s and across process boundaries. It contains the identifiers (a {@link TraceId + * trace_id} and {@link SpanId span_id}) associated with the {@link Span} and a set of options + * (currently only whether the context is sampled or not), as well as the {@link TraceState + * traceState} and the {@link boolean remote} flag. + */ +@Immutable +@AutoValue +abstract class ImmutableSpanContext implements SpanContext { + + private static final SpanContext INVALID = + create( + TraceId.getInvalid(), + SpanId.getInvalid(), + TraceFlags.getDefault(), + TraceState.getDefault(), + /* remote= */ false); + + /** + * Returns the invalid {@code SpanContext} that can be used for no-op operations. + * + * @return the invalid {@code SpanContext}. + */ + static SpanContext getInvalid() { + return INVALID; + } + + static SpanContext create( + String traceIdHex, String spanIdHex, byte traceFlags, TraceState traceState, boolean remote) { + return new AutoValue_ImmutableSpanContext( + traceIdHex, spanIdHex, traceFlags, traceState, remote); + } + + /** + * Returns the byte[] representation of the trace identifier associated with this {@link + * SpanContext}. + */ + @Override + @Memoized + public byte[] getTraceIdBytes() { + return SpanContext.super.getTraceIdBytes(); + } + + /** + * Returns the byte[] representation of the span identifier associated with this {@link + * SpanContext}. + */ + @Override + @Memoized + public byte[] getSpanIdBytes() { + return SpanContext.super.getSpanIdBytes(); + } + + /** + * Returns {@code true} if this {@code SpanContext} is valid. + * + * @return {@code true} if this {@code SpanContext} is valid. + */ + @Override + @Memoized + public boolean isValid() { + return SpanContext.super.isValid(); + } +} diff --git a/api/src/main/java/io/opentelemetry/api/trace/SpanContext.java b/api/src/main/java/io/opentelemetry/api/trace/SpanContext.java index 030cc300a84..b99bb16203a 100644 --- a/api/src/main/java/io/opentelemetry/api/trace/SpanContext.java +++ b/api/src/main/java/io/opentelemetry/api/trace/SpanContext.java @@ -5,8 +5,6 @@ package io.opentelemetry.api.trace; -import com.google.auto.value.AutoValue; -import com.google.auto.value.extension.memoized.Memoized; import javax.annotation.concurrent.Immutable; /** @@ -17,23 +15,15 @@ * traceState} and the {@link boolean remote} flag. */ @Immutable -@AutoValue -public abstract class SpanContext { - - private static final SpanContext INVALID = - create( - TraceId.getInvalid(), - SpanId.getInvalid(), - TraceFlags.getDefault(), - TraceState.getDefault()); +public interface SpanContext { /** * Returns the invalid {@code SpanContext} that can be used for no-op operations. * * @return the invalid {@code SpanContext}. */ - public static SpanContext getInvalid() { - return INVALID; + static SpanContext getInvalid() { + return ImmutableSpanContext.getInvalid(); } /** @@ -45,15 +35,10 @@ public static SpanContext getInvalid() { * @param traceState the trace state for the span context. * @return a new {@code SpanContext} with the given identifiers and options. */ - public static SpanContext create( + static SpanContext create( String traceIdHex, String spanIdHex, byte traceFlags, TraceState traceState) { - return create(traceIdHex, spanIdHex, traceFlags, traceState, /* remote=*/ false); - } - - private static SpanContext create( - String traceIdHex, String spanIdHex, byte traceFlags, TraceState traceState, boolean remote) { - return new AutoValue_SpanContext( - traceIdHex, spanIdHex, traceFlags, traceState, /* remote$=*/ remote); + return ImmutableSpanContext.create( + traceIdHex, spanIdHex, traceFlags, traceState, /* remote=*/ false); } /** @@ -66,31 +51,25 @@ private static SpanContext create( * @param traceState the trace state for the span context. * @return a new {@code SpanContext} with the given identifiers and options. */ - public static SpanContext createFromRemoteParent( + static SpanContext createFromRemoteParent( String traceIdHex, String spanIdHex, byte traceFlags, TraceState traceState) { - return create(traceIdHex, spanIdHex, traceFlags, traceState, /* remote=*/ true); + return ImmutableSpanContext.create( + traceIdHex, spanIdHex, traceFlags, traceState, /* remote=*/ true); } - abstract String getTraceIdHex(); - - abstract String getSpanIdHex(); - /** * Returns the trace identifier associated with this {@code SpanContext}. * * @return the trace identifier associated with this {@code SpanContext}. */ - public String getTraceIdAsHexString() { - return getTraceIdHex(); - } + String getTraceIdAsHexString(); /** * Returns the byte[] representation of the trace identifier associated with this {@link * SpanContext}. */ - @Memoized - public byte[] getTraceIdBytes() { - return TraceId.bytesFromHex(getTraceIdHex(), 0); + default byte[] getTraceIdBytes() { + return TraceId.bytesFromHex(getTraceIdAsHexString(), 0); } /** @@ -98,28 +77,25 @@ public byte[] getTraceIdBytes() { * * @return the span identifier associated with this {@code SpanContext}. */ - public String getSpanIdAsHexString() { - return getSpanIdHex(); - } + String getSpanIdAsHexString(); /** * Returns the byte[] representation of the span identifier associated with this {@link * SpanContext}. */ - @Memoized - public byte[] getSpanIdBytes() { - return SpanId.bytesFromHex(getSpanIdHex(), 0); + default byte[] getSpanIdBytes() { + return SpanId.bytesFromHex(getSpanIdAsHexString(), 0); } /** Whether the span in this context is sampled. */ - public boolean isSampled() { + default boolean isSampled() { return (getTraceFlags() & 1) == 1; } /** The byte-representation of {@link TraceFlags}. */ - public abstract byte getTraceFlags(); + byte getTraceFlags(); - public void copyTraceFlagsHexTo(char[] dest, int destOffset) { + default void copyTraceFlagsHexTo(char[] dest, int destOffset) { BigendianEncoding.byteToBase16String(getTraceFlags(), dest, destOffset); } @@ -128,16 +104,15 @@ public void copyTraceFlagsHexTo(char[] dest, int destOffset) { * * @return the {@code TraceState} associated with this {@code SpanContext}. */ - public abstract TraceState getTraceState(); + TraceState getTraceState(); /** * Returns {@code true} if this {@code SpanContext} is valid. * * @return {@code true} if this {@code SpanContext} is valid. */ - @Memoized - public boolean isValid() { - return TraceId.isValid(getTraceIdHex()) && SpanId.isValid(getSpanIdHex()); + default boolean isValid() { + return TraceId.isValid(getTraceIdAsHexString()) && SpanId.isValid(getSpanIdAsHexString()); } /** @@ -145,5 +120,5 @@ public boolean isValid() { * * @return {@code true} if the {@code SpanContext} was propagated from a remote parent. */ - public abstract boolean isRemote(); + boolean isRemote(); } From 8c2b64317feacd0d4c27d4f0c1701e5d5ba2fe81 Mon Sep 17 00:00:00 2001 From: Anuraag Agrawal Date: Fri, 30 Oct 2020 14:34:45 +0900 Subject: [PATCH 2/4] Remove javadoc from impl to reduce drift change. --- .../api/trace/ImmutableSpanContext.java | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/api/src/main/java/io/opentelemetry/api/trace/ImmutableSpanContext.java b/api/src/main/java/io/opentelemetry/api/trace/ImmutableSpanContext.java index c18d2b0adc1..b77a41a2d42 100644 --- a/api/src/main/java/io/opentelemetry/api/trace/ImmutableSpanContext.java +++ b/api/src/main/java/io/opentelemetry/api/trace/ImmutableSpanContext.java @@ -9,13 +9,6 @@ import com.google.auto.value.extension.memoized.Memoized; import javax.annotation.concurrent.Immutable; -/** - * A class that represents a span context. A span context contains the state that must propagate to - * child {@link Span}s and across process boundaries. It contains the identifiers (a {@link TraceId - * trace_id} and {@link SpanId span_id}) associated with the {@link Span} and a set of options - * (currently only whether the context is sampled or not), as well as the {@link TraceState - * traceState} and the {@link boolean remote} flag. - */ @Immutable @AutoValue abstract class ImmutableSpanContext implements SpanContext { @@ -28,11 +21,6 @@ abstract class ImmutableSpanContext implements SpanContext { TraceState.getDefault(), /* remote= */ false); - /** - * Returns the invalid {@code SpanContext} that can be used for no-op operations. - * - * @return the invalid {@code SpanContext}. - */ static SpanContext getInvalid() { return INVALID; } @@ -43,31 +31,18 @@ static SpanContext create( traceIdHex, spanIdHex, traceFlags, traceState, remote); } - /** - * Returns the byte[] representation of the trace identifier associated with this {@link - * SpanContext}. - */ @Override @Memoized public byte[] getTraceIdBytes() { return SpanContext.super.getTraceIdBytes(); } - /** - * Returns the byte[] representation of the span identifier associated with this {@link - * SpanContext}. - */ @Override @Memoized public byte[] getSpanIdBytes() { return SpanContext.super.getSpanIdBytes(); } - /** - * Returns {@code true} if this {@code SpanContext} is valid. - * - * @return {@code true} if this {@code SpanContext} is valid. - */ @Override @Memoized public boolean isValid() { From 3109e68c99b9bf426d439806af0cc2dc3197ebea Mon Sep 17 00:00:00 2001 From: Anuraag Agrawal Date: Tue, 1 Dec 2020 17:56:48 +0900 Subject: [PATCH 3/4] Add warning --- api/src/main/java/io/opentelemetry/api/trace/SpanContext.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/src/main/java/io/opentelemetry/api/trace/SpanContext.java b/api/src/main/java/io/opentelemetry/api/trace/SpanContext.java index b99bb16203a..a36d6bb06c6 100644 --- a/api/src/main/java/io/opentelemetry/api/trace/SpanContext.java +++ b/api/src/main/java/io/opentelemetry/api/trace/SpanContext.java @@ -13,6 +13,10 @@ * trace_id} and {@link SpanId span_id}) associated with the {@link Span} and a set of options * (currently only whether the context is sampled or not), as well as the {@link TraceState * traceState} and the {@link boolean remote} flag. + * + *

Implementations of this interface *must* be immutable and have well-defined value-based + * equals/hashCode implementations. If an implementation does not strictly conform to these + * requirements, behavior of the OpenTelemetry APIs and default SDK cannot be guaranteed. */ @Immutable public interface SpanContext { From 09df67d11a16326edc160519232804695c3b4872 Mon Sep 17 00:00:00 2001 From: Anuraag Agrawal Date: Tue, 1 Dec 2020 17:57:31 +0900 Subject: [PATCH 4/4] More --- .../main/java/io/opentelemetry/api/trace/SpanContext.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/io/opentelemetry/api/trace/SpanContext.java b/api/src/main/java/io/opentelemetry/api/trace/SpanContext.java index a36d6bb06c6..0f61ce91a09 100644 --- a/api/src/main/java/io/opentelemetry/api/trace/SpanContext.java +++ b/api/src/main/java/io/opentelemetry/api/trace/SpanContext.java @@ -16,7 +16,10 @@ * *

Implementations of this interface *must* be immutable and have well-defined value-based * equals/hashCode implementations. If an implementation does not strictly conform to these - * requirements, behavior of the OpenTelemetry APIs and default SDK cannot be guaranteed. + * requirements, behavior of the OpenTelemetry APIs and default SDK cannot be guaranteed. It is + * strongly suggested that you use the implementation that is provided here via {@link + * #create(String, String, byte, TraceState)} or {@link #createFromRemoteParent(String, String, + * byte, TraceState)}. */ @Immutable public interface SpanContext {