diff options
author | Bogdan Drutu <bdrutu@google.com> | 2017-12-11 16:12:53 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-11 16:12:53 -0800 |
commit | 381e11c5168e5d31e09ec92840f908b42be647e6 (patch) | |
tree | b4d69bd3f2e5b1c7ef903278be6960420d3aa737 /impl_core/src/main/java/io/opencensus/implcore/trace/propagation | |
parent | e2664fb9a41ea54394d4b111052ef2c3ab0d7b0c (diff) | |
download | opencensus-java-381e11c5168e5d31e09ec92840f908b42be647e6.tar.gz |
Add initial support for b3-propagation headers. (#889)
* Add initial support for b3-propagation headers.
* Update tests and throw exception when missing span_id or trace_id.
* Cleanup and add more tests.
* Update comments. Update tests.
Diffstat (limited to 'impl_core/src/main/java/io/opencensus/implcore/trace/propagation')
-rw-r--r-- | impl_core/src/main/java/io/opencensus/implcore/trace/propagation/B3Format.java | 105 | ||||
-rw-r--r-- | impl_core/src/main/java/io/opencensus/implcore/trace/propagation/BinaryFormatImpl.java | 2 |
2 files changed, 106 insertions, 1 deletions
diff --git a/impl_core/src/main/java/io/opencensus/implcore/trace/propagation/B3Format.java b/impl_core/src/main/java/io/opencensus/implcore/trace/propagation/B3Format.java new file mode 100644 index 00000000..c27234db --- /dev/null +++ b/impl_core/src/main/java/io/opencensus/implcore/trace/propagation/B3Format.java @@ -0,0 +1,105 @@ +/* + * Copyright 2017, OpenCensus Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.implcore.trace.propagation; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.annotations.VisibleForTesting; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.TraceOptions; +import io.opencensus.trace.propagation.SpanContextParseException; +import io.opencensus.trace.propagation.TextFormat; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Implementation of the B3 propagation protocol. See <a + * href=https://github.com/openzipkin/b3-propagation>b3-propagation</a>. + */ +final class B3Format extends TextFormat { + @VisibleForTesting static final String X_B3_TRACE_ID = "X─B3─TraceId"; + @VisibleForTesting static final String X_B3_SPAN_ID = "X─B3─SpanId"; + @VisibleForTesting static final String X_B3_PARENT_SPAN_ID = "X─B3─ParentSpanId"; + @VisibleForTesting static final String X_B3_SAMPLED = "X─B3─Sampled"; + @VisibleForTesting static final String X_B3_FLAGS = "X-B3-Flags"; + private static final List<String> FIELDS = + Collections.unmodifiableList( + Arrays.asList( + X_B3_TRACE_ID, X_B3_SPAN_ID, X_B3_PARENT_SPAN_ID, X_B3_SAMPLED, X_B3_FLAGS)); + + // Used as the upper TraceId.SIZE hex characters of the traceID. B3-propagation used to send + // TraceId.SIZE hex characters (8-bytes traceId) in the past. + private static final String UPPER_TRACE_ID = "0000000000000000"; + // Sampled value via the X_B3_SAMPLED header. + private static final String SAMPLED_VALUE = "1"; + // "Debug" sampled value. + private static final String FLAGS_VALUE = "1"; + + @Override + public List<String> fields() { + return FIELDS; + } + + @Override + public <C> void inject(SpanContext spanContext, C carrier, Setter<C> setter) { + checkNotNull(spanContext, "spanContext"); + checkNotNull(setter, "setter"); + checkNotNull(carrier, "carrier"); + setter.put(carrier, X_B3_TRACE_ID, spanContext.getTraceId().toLowerBase16()); + setter.put(carrier, X_B3_SPAN_ID, spanContext.getSpanId().toLowerBase16()); + if (spanContext.getTraceOptions().isSampled()) { + setter.put(carrier, X_B3_SAMPLED, SAMPLED_VALUE); + } + } + + @Override + public <C> SpanContext extract(C carrier, Getter<C> getter) throws SpanContextParseException { + checkNotNull(carrier, "carrier"); + checkNotNull(getter, "getter"); + try { + TraceId traceId; + String traceIdStr = getter.get(carrier, X_B3_TRACE_ID); + if (traceIdStr != null) { + if (traceIdStr.length() == TraceId.SIZE) { + // This is an 8-byte traceID. + traceIdStr = UPPER_TRACE_ID + traceIdStr; + } + traceId = TraceId.fromLowerBase16(traceIdStr); + } else { + throw new SpanContextParseException("Missing X_B3_TRACE_ID."); + } + SpanId spanId; + String spanIdStr = getter.get(carrier, X_B3_SPAN_ID); + if (spanIdStr != null) { + spanId = SpanId.fromLowerBase16(spanIdStr); + } else { + throw new SpanContextParseException("Missing X_B3_SPAN_ID."); + } + TraceOptions traceOptions = TraceOptions.DEFAULT; + if (SAMPLED_VALUE.equals(getter.get(carrier, X_B3_SAMPLED)) + || FLAGS_VALUE.equals(getter.get(carrier, X_B3_FLAGS))) { + traceOptions = TraceOptions.builder().setIsSampled(true).build(); + } + return SpanContext.create(traceId, spanId, traceOptions); + } catch (IllegalArgumentException e) { + throw new SpanContextParseException("Invalid input.", e); + } + } +} diff --git a/impl_core/src/main/java/io/opencensus/implcore/trace/propagation/BinaryFormatImpl.java b/impl_core/src/main/java/io/opencensus/implcore/trace/propagation/BinaryFormatImpl.java index 6075c80b..8a4377d3 100644 --- a/impl_core/src/main/java/io/opencensus/implcore/trace/propagation/BinaryFormatImpl.java +++ b/impl_core/src/main/java/io/opencensus/implcore/trace/propagation/BinaryFormatImpl.java @@ -59,7 +59,7 @@ import io.opencensus.trace.propagation.SpanContextParseException; * </ul> * </ul> */ -public final class BinaryFormatImpl extends BinaryFormat { +final class BinaryFormatImpl extends BinaryFormat { private static final byte VERSION_ID = 0; private static final int VERSION_ID_OFFSET = 0; // The version_id/field_id size in bytes. |