Hide default context propagators implementation behind interface. (#2089)

* Hide default context propagators implementation behind interface.

* Deprecate

* Revamp
This commit is contained in:
Anuraag Agrawal 2020-11-20 10:58:34 +09:00 committed by GitHub
parent d940947e53
commit 0e013e5c73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 187 additions and 131 deletions

View File

@ -10,7 +10,6 @@ import static java.util.Objects.requireNonNull;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.api.trace.TracerProvider;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.context.propagation.DefaultContextPropagators;
import io.opentelemetry.spi.OpenTelemetryFactory;
import io.opentelemetry.spi.metrics.MeterProviderFactory;
import io.opentelemetry.spi.trace.TracerProviderFactory;
@ -124,7 +123,7 @@ public class DefaultOpenTelemetry implements OpenTelemetry {
}
protected static class Builder implements OpenTelemetryBuilder<Builder> {
protected ContextPropagators propagators = DefaultContextPropagators.builder().build();
protected ContextPropagators propagators = ContextPropagators.noop();
protected TracerProvider tracerProvider;
protected MeterProvider meterProvider;

View File

@ -27,7 +27,6 @@ import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.TracerProvider;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.context.propagation.DefaultContextPropagators;
import io.opentelemetry.spi.metrics.MeterProviderFactory;
import io.opentelemetry.spi.trace.TracerProviderFactory;
import java.io.File;
@ -64,7 +63,6 @@ class OpenTelemetryTest {
.isEqualTo("DefaultMeterProvider");
assertThat(OpenTelemetry.getGlobalMeterProvider())
.isSameAs(OpenTelemetry.getGlobalMeterProvider());
assertThat(OpenTelemetry.getGlobalPropagators()).isInstanceOf(DefaultContextPropagators.class);
assertThat(OpenTelemetry.getGlobalPropagators()).isSameAs(OpenTelemetry.getGlobalPropagators());
}
@ -156,14 +154,14 @@ class OpenTelemetryTest {
@Test
void testGlobalPropagatorsSet() {
ContextPropagators propagators = DefaultContextPropagators.builder().build();
ContextPropagators propagators = ContextPropagators.noop();
OpenTelemetry.setGlobalPropagators(propagators);
assertThat(OpenTelemetry.getGlobalPropagators()).isEqualTo(propagators);
}
@Test
void testPropagatorsSet() {
ContextPropagators propagators = DefaultContextPropagators.builder().build();
ContextPropagators propagators = ContextPropagators.noop();
OpenTelemetry instance = DefaultOpenTelemetry.builder().build();
instance.setPropagators(propagators);
assertThat(instance.getPropagators()).isEqualTo(propagators);

View File

@ -5,6 +5,8 @@
package io.opentelemetry.context.propagation;
import static java.util.Objects.requireNonNull;
import javax.annotation.concurrent.ThreadSafe;
/**
@ -70,6 +72,32 @@ import javax.annotation.concurrent.ThreadSafe;
@ThreadSafe
public interface ContextPropagators {
/**
* Returns a {@link ContextPropagators} which can be used to extract and inject context in text
* payloads with the given {@link TextMapPropagator}. Use {@link
* TextMapPropagator#composite(TextMapPropagator...)} to register multiple propagators, which will
* all be executed when extracting or injecting.
*
* <pre>{@code
* ContextPropagators propagators = ContextPropagators.create(
* TextMapPropagator.composite(
* HttpTraceContext.getInstance(),
* W3CBaggagePropagator.getInstance(),
* new MyCustomContextPropagator()));
* }</pre>
*/
@SuppressWarnings("deprecation")
static ContextPropagators create(TextMapPropagator textPropagator) {
requireNonNull(textPropagator, "textPropagator");
return new DefaultContextPropagators(textPropagator);
}
/** Returns a {@link ContextPropagators} which performs no injection or extraction. */
@SuppressWarnings("deprecation")
static ContextPropagators noop() {
return DefaultContextPropagators.noop();
}
/**
* Returns a {@link TextMapPropagator} propagator.
*

View File

@ -5,13 +5,8 @@
package io.opentelemetry.context.propagation;
import io.opentelemetry.context.Context;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
/**
* {@code DefaultContextPropagators} is the default, built-in implementation of {@link
@ -21,8 +16,19 @@ import javax.annotation.Nullable;
* synchronically upon injection and extraction.
*
* <p>The propagation fields retrieved from all registered propagators are de-duplicated.
*
* @deprecated Use {@link ContextPropagators#create(TextMapPropagator)}
*/
@Deprecated
public final class DefaultContextPropagators implements ContextPropagators {
private static final ContextPropagators NOOP =
new DefaultContextPropagators(NoopTextMapPropagator.getInstance());
static ContextPropagators noop() {
return NOOP;
}
private final TextMapPropagator textMapPropagator;
@Override
@ -35,45 +41,32 @@ public final class DefaultContextPropagators implements ContextPropagators {
* object.
*
* @return a {@link DefaultContextPropagators.Builder}.
* @deprecated Use {@link ContextPropagators#create(TextMapPropagator)}
*/
@Deprecated
public static Builder builder() {
return new Builder();
}
private DefaultContextPropagators(TextMapPropagator textMapPropagator) {
DefaultContextPropagators(TextMapPropagator textMapPropagator) {
this.textMapPropagator = textMapPropagator;
}
/**
* {@link Builder} is used to construct a new {@code ContextPropagators} object with the specified
* propagators.
* A builder of {@link DefaultContextPropagators}.
*
* <p>Invocation order of {@code TextMapPropagator#inject()} and {@code
* TextMapPropagator#extract()} for registered trace propagators is undefined.
*
* <p>This is a example of a {@code ContextPropagators} object being created:
*
* <pre>{@code
* ContextPropagators propagators = DefaultContextPropagators.builder()
* .addTextMapPropagator(new HttpTraceContext())
* .addTextMapPropagator(new HttpBaggage())
* .addTextMapPropagator(new MyCustomContextPropagator())
* .build();
* }</pre>
* @deprecated Use {@link ContextPropagators#create(TextMapPropagator)}
*/
@Deprecated
public static final class Builder {
List<TextMapPropagator> textPropagators = new ArrayList<>();
/**
* Adds a {@link TextMapPropagator} propagator.
* Add a {@link TextMapPropagator}.
*
* <p>One propagator per concern (traces, correlations, etc) should be added if this format is
* supported.
*
* @param textMapPropagator the propagator to be added.
* @return this.
* @throws NullPointerException if {@code textMapPropagator} is {@code null}.
* @deprecated Use {@link ContextPropagators#create(TextMapPropagator)}
*/
@Deprecated
public Builder addTextMapPropagator(TextMapPropagator textMapPropagator) {
if (textMapPropagator == null) {
throw new NullPointerException("textMapPropagator");
@ -84,73 +77,13 @@ public final class DefaultContextPropagators implements ContextPropagators {
}
/**
* Builds a new {@code ContextPropagators} with the specified propagators.
* Returns a {@link ContextPropagators}.
*
* @return the newly created {@code ContextPropagators} instance.
* @deprecated Use {@link ContextPropagators#create(TextMapPropagator)}
*/
@Deprecated
public ContextPropagators build() {
if (textPropagators.isEmpty()) {
return new DefaultContextPropagators(NoopTextMapPropagator.INSTANCE);
}
return new DefaultContextPropagators(new MultiTextMapPropagator(textPropagators));
}
}
private static final class MultiTextMapPropagator implements TextMapPropagator {
private final TextMapPropagator[] textPropagators;
private final List<String> allFields;
private MultiTextMapPropagator(List<TextMapPropagator> textPropagators) {
this.textPropagators = new TextMapPropagator[textPropagators.size()];
textPropagators.toArray(this.textPropagators);
this.allFields = Collections.unmodifiableList(getAllFields(this.textPropagators));
}
@Override
public List<String> fields() {
return allFields;
}
private static List<String> getAllFields(TextMapPropagator[] textPropagators) {
Set<String> fields = new LinkedHashSet<>();
for (int i = 0; i < textPropagators.length; i++) {
fields.addAll(textPropagators[i].fields());
}
return new ArrayList<>(fields);
}
@Override
public <C> void inject(Context context, @Nullable C carrier, Setter<C> setter) {
for (int i = 0; i < textPropagators.length; i++) {
textPropagators[i].inject(context, carrier, setter);
}
}
@Override
public <C> Context extract(Context context, @Nullable C carrier, Getter<C> getter) {
for (int i = 0; i < textPropagators.length; i++) {
context = textPropagators[i].extract(context, carrier, getter);
}
return context;
}
}
private static final class NoopTextMapPropagator implements TextMapPropagator {
private static final NoopTextMapPropagator INSTANCE = new NoopTextMapPropagator();
@Override
public List<String> fields() {
return Collections.emptyList();
}
@Override
public <C> void inject(Context context, @Nullable C carrier, Setter<C> setter) {}
@Override
public <C> Context extract(Context context, @Nullable C carrier, Getter<C> getter) {
return context;
return ContextPropagators.create(TextMapPropagator.composite(textPropagators));
}
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.context.propagation;
import io.opentelemetry.context.Context;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
final class MultiTextMapPropagator implements TextMapPropagator {
private final TextMapPropagator[] textPropagators;
private final List<String> allFields;
MultiTextMapPropagator(List<TextMapPropagator> textPropagators) {
this.textPropagators = new TextMapPropagator[textPropagators.size()];
textPropagators.toArray(this.textPropagators);
this.allFields = Collections.unmodifiableList(getAllFields(this.textPropagators));
}
@Override
public List<String> fields() {
return allFields;
}
private static List<String> getAllFields(TextMapPropagator[] textPropagators) {
Set<String> fields = new LinkedHashSet<>();
for (int i = 0; i < textPropagators.length; i++) {
fields.addAll(textPropagators[i].fields());
}
return new ArrayList<>(fields);
}
@Override
public <C> void inject(Context context, @Nullable C carrier, Setter<C> setter) {
for (int i = 0; i < textPropagators.length; i++) {
textPropagators[i].inject(context, carrier, setter);
}
}
@Override
public <C> Context extract(Context context, @Nullable C carrier, Getter<C> getter) {
for (int i = 0; i < textPropagators.length; i++) {
context = textPropagators[i].extract(context, carrier, getter);
}
return context;
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.context.propagation;
import io.opentelemetry.context.Context;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
final class NoopTextMapPropagator implements TextMapPropagator {
private static final NoopTextMapPropagator INSTANCE = new NoopTextMapPropagator();
static TextMapPropagator getInstance() {
return INSTANCE;
}
@Override
public List<String> fields() {
return Collections.emptyList();
}
@Override
public <C> void inject(Context context, @Nullable C carrier, Setter<C> setter) {}
@Override
public <C> Context extract(Context context, @Nullable C carrier, Getter<C> getter) {
return context;
}
}

View File

@ -6,6 +6,8 @@
package io.opentelemetry.context.propagation;
import io.opentelemetry.context.Context;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
@ -39,6 +41,39 @@ import javax.annotation.concurrent.ThreadSafe;
*/
@ThreadSafe
public interface TextMapPropagator {
/**
* Returns a {@link TextMapPropagator} which simply delegates injection and extraction to the
* provided propagators.
*
* <p>Invocation order of {@code TextMapPropagator#inject()} and {@code
* TextMapPropagator#extract()} for registered trace propagators is undefined.
*/
static TextMapPropagator composite(TextMapPropagator... propagators) {
return composite(Arrays.asList(propagators));
}
/**
* Returns a {@link TextMapPropagator} which simply delegates injection and extraction to the
* provided propagators.
*
* <p>Invocation order of {@code TextMapPropagator#inject()} and {@code
* TextMapPropagator#extract()} for registered trace propagators is undefined.
*/
static TextMapPropagator composite(Iterable<TextMapPropagator> propagators) {
List<TextMapPropagator> propagatorsList = new ArrayList<>();
for (TextMapPropagator propagator : propagators) {
propagatorsList.add(propagator);
}
if (propagatorsList.isEmpty()) {
return NoopTextMapPropagator.getInstance();
}
if (propagatorsList.size() == 1) {
return propagatorsList.get(0);
}
return new MultiTextMapPropagator(propagatorsList);
}
/**
* The propagation fields defined. If your carrier is reused, you should delete the fields here
* before calling {@link #inject(Context, Object, Setter)} )}.

View File

@ -21,9 +21,7 @@ class DefaultPropagatorsTest {
@Test
void addTextMapPropagatorNull() {
assertThrows(
NullPointerException.class,
() -> DefaultContextPropagators.builder().addTextMapPropagator(null));
assertThrows(NullPointerException.class, () -> ContextPropagators.create(null));
}
@Test
@ -31,10 +29,7 @@ class DefaultPropagatorsTest {
CustomTextMapPropagator propagator1 = new CustomTextMapPropagator("prop1");
CustomTextMapPropagator propagator2 = new CustomTextMapPropagator("prop2");
ContextPropagators propagators =
DefaultContextPropagators.builder()
.addTextMapPropagator(propagator1)
.addTextMapPropagator(propagator2)
.build();
ContextPropagators.create(TextMapPropagator.composite(propagator1, propagator2));
Context context = Context.current();
context = context.with(propagator1.getKey(), "value1");
@ -52,10 +47,7 @@ class DefaultPropagatorsTest {
CustomTextMapPropagator propagator2 = new CustomTextMapPropagator("prop2");
CustomTextMapPropagator propagator3 = new CustomTextMapPropagator("prop3");
ContextPropagators propagators =
DefaultContextPropagators.builder()
.addTextMapPropagator(propagator1)
.addTextMapPropagator(propagator2)
.build();
ContextPropagators.create(TextMapPropagator.composite(propagator1, propagator2));
// Put values for propagators 1 and 2 only.
Map<String, String> map = new HashMap<>();
@ -76,12 +68,8 @@ class DefaultPropagatorsTest {
CustomTextMapPropagator propagator3 = new CustomTextMapPropagator("prop1");
CustomTextMapPropagator propagator4 = new CustomTextMapPropagator("prop2");
ContextPropagators propagators =
DefaultContextPropagators.builder()
.addTextMapPropagator(propagator1)
.addTextMapPropagator(propagator2)
.addTextMapPropagator(propagator3)
.addTextMapPropagator(propagator4)
.build();
ContextPropagators.create(
TextMapPropagator.composite(propagator1, propagator2, propagator3, propagator4));
List<String> fields = propagators.getTextMapPropagator().fields();
assertThat(fields).containsExactly("prop1", "prop2");
@ -89,7 +77,7 @@ class DefaultPropagatorsTest {
@Test
void noopPropagator() {
ContextPropagators propagators = DefaultContextPropagators.builder().build();
ContextPropagators propagators = ContextPropagators.noop();
Context context = Context.current();
Map<String, String> map = new HashMap<>();

View File

@ -11,7 +11,6 @@ import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.propagation.HttpTraceContext;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.context.propagation.DefaultContextPropagators;
import io.opentelemetry.context.propagation.TextMapPropagator.Getter;
import io.opentelemetry.context.propagation.TextMapPropagator.Setter;
import java.util.ArrayList;
@ -34,11 +33,7 @@ public class Application {
private static final OpenTelemetry openTelemetry;
static {
ContextPropagators propagators =
DefaultContextPropagators.builder()
.addTextMapPropagator(HttpTraceContext.getInstance())
.build();
OpenTelemetry.setGlobalPropagators(propagators);
OpenTelemetry.setGlobalPropagators(ContextPropagators.create(HttpTraceContext.getInstance()));
openTelemetry = OpenTelemetry.get();
}

View File

@ -7,7 +7,7 @@ package io.opentelemetry.sdk.testing.junit4;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.propagation.HttpTraceContext;
import io.opentelemetry.context.propagation.DefaultContextPropagators;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter;
import io.opentelemetry.sdk.trace.TracerSdkManagement;
@ -55,10 +55,7 @@ public class OpenTelemetryRule extends ExternalResource {
OpenTelemetrySdk openTelemetry =
OpenTelemetrySdk.builder()
.setPropagators(
DefaultContextPropagators.builder()
.addTextMapPropagator(HttpTraceContext.getInstance())
.build())
.setPropagators(ContextPropagators.create(HttpTraceContext.getInstance()))
.setTracerProvider(tracerProvider)
.build();

View File

@ -9,7 +9,7 @@ import static io.opentelemetry.sdk.testing.assertj.TracesAssert.assertThat;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.propagation.HttpTraceContext;
import io.opentelemetry.context.propagation.DefaultContextPropagators;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.testing.assertj.TracesAssert;
import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter;
@ -61,10 +61,7 @@ public class OpenTelemetryExtension
OpenTelemetrySdk openTelemetry =
OpenTelemetrySdk.builder()
.setPropagators(
DefaultContextPropagators.builder()
.addTextMapPropagator(HttpTraceContext.getInstance())
.build())
.setPropagators(ContextPropagators.create(HttpTraceContext.getInstance()))
.setTracerProvider(tracerProvider)
.build();