diff --git a/api/src/main/java/io/opentelemetry/correlationcontext/CorrelationsContextUtils.java b/api/src/main/java/io/opentelemetry/correlationcontext/CorrelationsContextUtils.java new file mode 100644 index 00000000000..38e9ae45c52 --- /dev/null +++ b/api/src/main/java/io/opentelemetry/correlationcontext/CorrelationsContextUtils.java @@ -0,0 +1,99 @@ +/* + * Copyright 2019, OpenTelemetry 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.opentelemetry.correlationcontext; + +import io.grpc.Context; +import io.opentelemetry.context.ContextUtils; +import io.opentelemetry.context.Scope; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +/** + * Utility methods for accessing the {@link CorrelationContext} contained in the {@link + * io.grpc.Context}. + * + * @since 0.1.0 + */ +@Immutable +public final class CorrelationsContextUtils { + private static final Context.Key CORR_CONTEXT_KEY = + Context.key("opentelemetry-corr-context-key"); + + /** + * Creates a new {@code Context} with the given value set. + * + * @param corrContext the value to be set. + * @param context the parent {@code Context}. + * @return a new context with the given value set. + * @since 0.1.0 + */ + public static Context withCorrelationContext(CorrelationContext corrContext, Context context) { + return context.withValue(CORR_CONTEXT_KEY, corrContext); + } + + /** + * Returns the {@link CorrelationContext} from the current {@code Context}, falling back to an + * empty {@link CorrelationContext}. + * + * @return the {@link CorrelationContext} from the current {@code Context}. + * @since 0.3.0 + */ + public static CorrelationContext getCurrentCorrelationContext() { + return getCorrelationContext(Context.current()); + } + + /** + * Returns the {@link CorrelationContext} from the specified {@code Context}, falling back to an + * empty {@link CorrelationContext}. + * + * @param context the specified {@code Context}. + * @return the {@link CorrelationContext} from the specified {@code Context}. + * @since 0.3.0 + */ + public static CorrelationContext getCorrelationContext(Context context) { + CorrelationContext corrContext = CORR_CONTEXT_KEY.get(context); + return corrContext == null ? EmptyCorrelationContext.getInstance() : corrContext; + } + + /** + * Returns the {@link CorrelationContext} from the specified {@code Context}. If none is found, + * this method returns {code null}. + * + * @param context the specified {@code Context}. + * @return the {@link CorrelationContext} from the specified {@code Context}. + * @since 0.1.0 + */ + @Nullable + public static CorrelationContext getCorrelationContextWithoutDefault(Context context) { + return CORR_CONTEXT_KEY.get(context); + } + + /** + * Returns a new {@link Scope} encapsulating the provided {@link CorrelationContext} added to the + * current {@code Context}. + * + * @param corrContext the {@link CorrelationContext} to be added to the current {@code Context}. + * @return the {@link Scope} for the updated {@code Context}. + * @since 0.1.0 + */ + public static Scope withScopedCorrelationContext(CorrelationContext corrContext) { + Context context = withCorrelationContext(corrContext, Context.current()); + return ContextUtils.withScopedContext(context); + } + + private CorrelationsContextUtils() {} +} diff --git a/api/src/main/java/io/opentelemetry/correlationcontext/DefaultCorrelationContextManager.java b/api/src/main/java/io/opentelemetry/correlationcontext/DefaultCorrelationContextManager.java index 085495ef9be..1fefb8d9f74 100644 --- a/api/src/main/java/io/opentelemetry/correlationcontext/DefaultCorrelationContextManager.java +++ b/api/src/main/java/io/opentelemetry/correlationcontext/DefaultCorrelationContextManager.java @@ -18,7 +18,6 @@ import io.opentelemetry.context.Scope; import io.opentelemetry.context.propagation.HttpTextFormat; -import io.opentelemetry.correlationcontext.unsafe.ContextUtils; import io.opentelemetry.internal.Utils; import java.util.Collections; import java.util.List; @@ -50,7 +49,7 @@ public static CorrelationContextManager getInstance() { @Override public CorrelationContext getCurrentContext() { - return ContextUtils.getValue(); + return CorrelationsContextUtils.getCurrentCorrelationContext(); } @Override @@ -60,7 +59,7 @@ public CorrelationContext.Builder contextBuilder() { @Override public Scope withContext(CorrelationContext distContext) { - return ContextUtils.withCorrelationContext(distContext); + return CorrelationsContextUtils.withScopedCorrelationContext(distContext); } @Override diff --git a/api/src/main/java/io/opentelemetry/correlationcontext/unsafe/ContextUtils.java b/api/src/main/java/io/opentelemetry/correlationcontext/unsafe/ContextUtils.java deleted file mode 100644 index fadda36f641..00000000000 --- a/api/src/main/java/io/opentelemetry/correlationcontext/unsafe/ContextUtils.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2019, OpenTelemetry 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.opentelemetry.correlationcontext.unsafe; - -import io.grpc.Context; -import io.opentelemetry.context.Scope; -import io.opentelemetry.correlationcontext.CorrelationContext; -import io.opentelemetry.correlationcontext.EmptyCorrelationContext; -import javax.annotation.concurrent.Immutable; - -/** - * Utility methods for accessing the {@link CorrelationContext} contained in the {@link - * io.grpc.Context}. - * - *

Most code should interact with the current context via the public APIs in {@link - * CorrelationContext} and avoid accessing this class directly. - * - * @since 0.1.0 - */ -@Immutable -public final class ContextUtils { - private static final Context.Key DIST_CONTEXT_KEY = - Context.keyWithDefault( - "opentelemetry-dist-context-key", EmptyCorrelationContext.getInstance()); - - /** - * Creates a new {@code Context} with the given value set. - * - * @param distContext the value to be set. - * @return a new context with the given value set. - * @since 0.1.0 - */ - public static Context withValue(CorrelationContext distContext) { - return Context.current().withValue(DIST_CONTEXT_KEY, distContext); - } - - /** - * Creates a new {@code Context} with the given value set. - * - * @param distContext the value to be set. - * @param context the parent {@code Context}. - * @return a new context with the given value set. - * @since 0.1.0 - */ - public static Context withValue(CorrelationContext distContext, Context context) { - return context.withValue(DIST_CONTEXT_KEY, distContext); - } - - /** - * Returns the value from the current {@code Context}. - * - * @return the value from the specified {@code Context}. - * @since 0.1.0 - */ - public static CorrelationContext getValue() { - return DIST_CONTEXT_KEY.get(); - } - - /** - * Returns the value from the specified {@code Context}. - * - * @param context the specified {@code Context}. - * @return the value from the specified {@code Context}. - * @since 0.1.0 - */ - public static CorrelationContext getValue(Context context) { - return DIST_CONTEXT_KEY.get(context); - } - - /** - * Returns a new {@link Scope} encapsulating the provided {@code CorrelationContext} added to the - * current {@code Context}. - * - * @param distContext the {@code CorrelationContext} to be added to the current {@code Context}. - * @return the {@link Scope} for the updated {@code Context}. - * @since 0.1.0 - */ - public static Scope withCorrelationContext(CorrelationContext distContext) { - return CorrelationContextInScope.create(distContext); - } - - private ContextUtils() {} -} diff --git a/api/src/main/java/io/opentelemetry/correlationcontext/unsafe/CorrelationContextInScope.java b/api/src/main/java/io/opentelemetry/correlationcontext/unsafe/CorrelationContextInScope.java deleted file mode 100644 index 054623bfcea..00000000000 --- a/api/src/main/java/io/opentelemetry/correlationcontext/unsafe/CorrelationContextInScope.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2019, OpenTelemetry 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.opentelemetry.correlationcontext.unsafe; - -import io.grpc.Context; -import io.opentelemetry.context.Scope; -import io.opentelemetry.correlationcontext.CorrelationContext; -import javax.annotation.concurrent.NotThreadSafe; - -/** - * A scope that manages the {@link Context} for a {@link CorrelationContext}. - * - * @since 0.1.0 - */ -@NotThreadSafe -final class CorrelationContextInScope implements Scope { - private final Context orig; - - private CorrelationContextInScope(CorrelationContext distContext) { - orig = ContextUtils.withValue(distContext).attach(); - } - - /** - * Constructs a new {@link CorrelationContextInScope}. - * - * @param distContext the {@code CorrelationContext} to be added to the current {@code Context}. - * @since 0.1.0 - */ - static CorrelationContextInScope create(CorrelationContext distContext) { - return new CorrelationContextInScope(distContext); - } - - @Override - public void close() { - Context.current().detach(orig); - } -} diff --git a/api/src/main/java/io/opentelemetry/trace/DefaultTracer.java b/api/src/main/java/io/opentelemetry/trace/DefaultTracer.java index 295b2a27287..dea6128a3a0 100644 --- a/api/src/main/java/io/opentelemetry/trace/DefaultTracer.java +++ b/api/src/main/java/io/opentelemetry/trace/DefaultTracer.java @@ -20,7 +20,6 @@ import io.opentelemetry.context.propagation.HttpTextFormat; import io.opentelemetry.internal.Utils; import io.opentelemetry.trace.propagation.HttpTraceContext; -import io.opentelemetry.trace.unsafe.ContextUtils; import java.util.Map; import javax.annotation.concurrent.ThreadSafe; @@ -46,12 +45,12 @@ public static Tracer getInstance() { @Override public Span getCurrentSpan() { - return ContextUtils.getValue(); + return TracingContextUtils.getCurrentSpan(); } @Override public Scope withSpan(Span span) { - return ContextUtils.withSpan(span); + return TracingContextUtils.withScopedSpan(span); } @Override diff --git a/api/src/main/java/io/opentelemetry/trace/TracingContextUtils.java b/api/src/main/java/io/opentelemetry/trace/TracingContextUtils.java new file mode 100644 index 00000000000..9300b42340e --- /dev/null +++ b/api/src/main/java/io/opentelemetry/trace/TracingContextUtils.java @@ -0,0 +1,97 @@ +/* + * Copyright 2019, OpenTelemetry 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.opentelemetry.trace; + +import io.grpc.Context; +import io.opentelemetry.context.ContextUtils; +import io.opentelemetry.context.Scope; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +/** + * Util methods/functionality to interact with the {@link io.grpc.Context}. + * + * @since 0.1.0 + */ +@Immutable +public final class TracingContextUtils { + private static final Context.Key CONTEXT_SPAN_KEY = + Context.key("opentelemetry-trace-span-key"); + + /** + * Creates a new {@code Context} with the given {@link Span} set. + * + * @param span the value to be set. + * @param context the parent {@code Context}. + * @return a new context with the given value set. + * @since 0.1.0 + */ + public static Context withSpan(Span span, Context context) { + return context.withValue(CONTEXT_SPAN_KEY, span); + } + + /** + * Returns the {@link Span} from the current {@code Context}, falling back to a default, no-op + * {@link Span}. + * + * @return the {@link Span} from the current {@code Context}. + * @since 0.3.0 + */ + public static Span getCurrentSpan() { + return getSpan(Context.current()); + } + + /** + * Returns the {@link Span} from the specified {@code Context}, falling back to a default, no-op + * {@link Span}. + * + * @param context the specified {@code Context}. + * @return the {@link Span} from the specified {@code Context}. + * @since 0.3.0 + */ + public static Span getSpan(Context context) { + Span span = CONTEXT_SPAN_KEY.get(context); + return span == null ? DefaultSpan.getInvalid() : span; + } + + /** + * Returns the {@link Span} from the specified {@code Context}. If none is found, this method + * returns {code null}. + * + * @param context the specified {@code Context}. + * @return the {@link Span} from the specified {@code Context}. + * @since 0.1.0 + */ + @Nullable + public static Span getSpanWithoutDefault(Context context) { + return CONTEXT_SPAN_KEY.get(context); + } + + /** + * Returns a new {@link Scope} encapsulating the provided {@link Span} added to the current {@code + * Context}. + * + * @param span the {@link Span} to be added to the current {@code Context}. + * @return the {@link Scope} for the updated {@code Context}. + * @since 0.1.0 + */ + public static Scope withScopedSpan(Span span) { + return ContextUtils.withScopedContext(withSpan(span, Context.current())); + } + + private TracingContextUtils() {} +} diff --git a/api/src/main/java/io/opentelemetry/trace/unsafe/ContextUtils.java b/api/src/main/java/io/opentelemetry/trace/unsafe/ContextUtils.java deleted file mode 100644 index 61dd089b77c..00000000000 --- a/api/src/main/java/io/opentelemetry/trace/unsafe/ContextUtils.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2019, OpenTelemetry 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.opentelemetry.trace.unsafe; - -import io.grpc.Context; -import io.opentelemetry.context.Scope; -import io.opentelemetry.trace.DefaultSpan; -import io.opentelemetry.trace.Span; -import io.opentelemetry.trace.Tracer; -import javax.annotation.concurrent.Immutable; - -/** - * Util methods/functionality to interact with the {@link io.grpc.Context}. - * - *

Users must interact with the current Context via the public APIs in {@link Tracer} and avoid - * accessing this class directly. - * - * @since 0.1.0 - */ -@Immutable -public final class ContextUtils { - private static final Context.Key CONTEXT_SPAN_KEY = - Context.keyWithDefault("opentelemetry-trace-span-key", DefaultSpan.getInvalid()); - - /** - * Creates a new {@code Context} with the given value set. - * - * @param span the value to be set. - * @return a new context with the given value set. - * @since 0.1.0 - */ - public static Context withValue(Span span) { - return Context.current().withValue(CONTEXT_SPAN_KEY, span); - } - - /** - * Creates a new {@code Context} with the given value set. - * - * @param span the value to be set. - * @param context the parent {@code Context}. - * @return a new context with the given value set. - * @since 0.1.0 - */ - public static Context withValue(Span span, Context context) { - return context.withValue(CONTEXT_SPAN_KEY, span); - } - - /** - * Returns the value from the current {@code Context}. - * - * @return the value from the specified {@code Context}. - * @since 0.1.0 - */ - public static Span getValue() { - return CONTEXT_SPAN_KEY.get(); - } - - /** - * Returns the value from the specified {@code Context}. - * - * @param context the specified {@code Context}. - * @return the value from the specified {@code Context}. - * @since 0.1.0 - */ - public static Span getValue(Context context) { - return CONTEXT_SPAN_KEY.get(context); - } - - /** - * Returns a new {@link Scope} encapsulating the provided {@code Span} added to the current {@code - * Context}. - * - * @param span the {@code Span} to be added to the current {@code Context}. - * @return the {@link Scope} for the updated {@code Context}. - * @since 0.1.0 - */ - public static Scope withSpan(Span span) { - return SpanInScope.create(span); - } - - private ContextUtils() {} -} diff --git a/api/src/main/java/io/opentelemetry/trace/unsafe/SpanInScope.java b/api/src/main/java/io/opentelemetry/trace/unsafe/SpanInScope.java deleted file mode 100644 index 518b0b9fcc0..00000000000 --- a/api/src/main/java/io/opentelemetry/trace/unsafe/SpanInScope.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2019, OpenTelemetry 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.opentelemetry.trace.unsafe; - -import io.grpc.Context; -import io.opentelemetry.context.Scope; -import io.opentelemetry.trace.Span; -import javax.annotation.concurrent.NotThreadSafe; - -/** - * A scope that manages the {@link Context} for a {@link Span}. - * - * @since 0.1.0 - */ -@NotThreadSafe -final class SpanInScope implements Scope { - private final Context previous; - private final Context current; - - private SpanInScope(Span span) { - current = ContextUtils.withValue(span); - previous = current.attach(); - } - - /** - * Constructs a new {@link SpanInScope}. - * - * @param span the {@code Span} to be added to the current {@code Context}. - * @since 0.1.0 - */ - static SpanInScope create(Span span) { - return new SpanInScope(span); - } - - @Override - public void close() { - current.detach(previous); - } -} diff --git a/api/src/test/java/io/opentelemetry/correlationcontext/CorrelationsContextUtilsTest.java b/api/src/test/java/io/opentelemetry/correlationcontext/CorrelationsContextUtilsTest.java new file mode 100644 index 00000000000..13b8b0c8168 --- /dev/null +++ b/api/src/test/java/io/opentelemetry/correlationcontext/CorrelationsContextUtilsTest.java @@ -0,0 +1,83 @@ +/* + * Copyright 2019, OpenTelemetry 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.opentelemetry.correlationcontext; + +import static com.google.common.truth.Truth.assertThat; + +import io.grpc.Context; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link CorrelationsContextUtils}. */ +@RunWith(JUnit4.class) +public final class CorrelationsContextUtilsTest { + + @Test + public void testGetCurrentCorrelationContext_Default() { + CorrelationContext corrContext = CorrelationsContextUtils.getCurrentCorrelationContext(); + assertThat(corrContext).isSameInstanceAs(EmptyCorrelationContext.getInstance()); + } + + @Test + public void testGetCurrentCorrelationContext_SetCorrContext() { + CorrelationContext corrContext = + DefaultCorrelationContextManager.getInstance().contextBuilder().build(); + Context orig = + CorrelationsContextUtils.withCorrelationContext(corrContext, Context.current()).attach(); + try { + assertThat(CorrelationsContextUtils.getCurrentCorrelationContext()) + .isSameInstanceAs(corrContext); + } finally { + Context.current().detach(orig); + } + } + + @Test + public void testGetCorrelationContext_DefaultContext() { + CorrelationContext corrContext = + CorrelationsContextUtils.getCorrelationContext(Context.current()); + assertThat(corrContext).isSameInstanceAs(EmptyCorrelationContext.getInstance()); + } + + @Test + public void testGetCorrelationContext_ExplicitContext() { + CorrelationContext corrContext = + DefaultCorrelationContextManager.getInstance().contextBuilder().build(); + Context context = + CorrelationsContextUtils.withCorrelationContext(corrContext, Context.current()); + assertThat(CorrelationsContextUtils.getCorrelationContext(context)) + .isSameInstanceAs(corrContext); + } + + @Test + public void testGetCorrelationContextWithoutDefault_DefaultContext() { + CorrelationContext corrContext = + CorrelationsContextUtils.getCorrelationContextWithoutDefault(Context.current()); + assertThat(corrContext).isNull(); + } + + @Test + public void testGetCorrelationContextWithoutDefault_ExplicitContext() { + CorrelationContext corrContext = + DefaultCorrelationContextManager.getInstance().contextBuilder().build(); + Context context = + CorrelationsContextUtils.withCorrelationContext(corrContext, Context.current()); + assertThat(CorrelationsContextUtils.getCorrelationContext(context)) + .isSameInstanceAs(corrContext); + } +} diff --git a/api/src/test/java/io/opentelemetry/correlationcontext/DefaultCorrelationContextManagerTest.java b/api/src/test/java/io/opentelemetry/correlationcontext/DefaultCorrelationContextManagerTest.java index e357d008220..7f567c6c4af 100644 --- a/api/src/test/java/io/opentelemetry/correlationcontext/DefaultCorrelationContextManagerTest.java +++ b/api/src/test/java/io/opentelemetry/correlationcontext/DefaultCorrelationContextManagerTest.java @@ -20,7 +20,6 @@ import io.grpc.Context; import io.opentelemetry.context.Scope; -import io.opentelemetry.correlationcontext.unsafe.ContextUtils; import java.util.Arrays; import java.util.Collection; import javax.annotation.Nullable; @@ -68,7 +67,8 @@ public void getCurrentContext_DefaultContext() { @Test public void getCurrentContext_ContextSetToNull() { - Context orig = ContextUtils.withValue(null).attach(); + Context orig = + CorrelationsContextUtils.withCorrelationContext(null, Context.current()).attach(); try { CorrelationContext distContext = defaultCorrelationContextManager.getCurrentContext(); assertThat(distContext).isNotNull(); diff --git a/api/src/test/java/io/opentelemetry/correlationcontext/unsafe/ContextUtilsTest.java b/api/src/test/java/io/opentelemetry/correlationcontext/unsafe/ContextUtilsTest.java deleted file mode 100644 index 3cdce893f34..00000000000 --- a/api/src/test/java/io/opentelemetry/correlationcontext/unsafe/ContextUtilsTest.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2019, OpenTelemetry 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.opentelemetry.correlationcontext.unsafe; - -import static com.google.common.truth.Truth.assertThat; - -import io.grpc.Context; -import io.opentelemetry.correlationcontext.CorrelationContext; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Unit tests for {@link ContextUtils}. */ -@RunWith(JUnit4.class) -public final class ContextUtilsTest { - @Test - public void testGetCurrentCorrelationContex_DefaultContext() { - CorrelationContext distContext = ContextUtils.getValue(Context.current()); - assertThat(distContext).isNotNull(); - assertThat(distContext.getEntries()).isEmpty(); - } - - @Test - public void testGetCurrentCorrelationContex_DefaultContext_WithoutExplicitContext() { - CorrelationContext distContext = ContextUtils.getValue(); - assertThat(distContext).isNotNull(); - assertThat(distContext.getEntries()).isEmpty(); - } - - @Test - public void testGetCurrentCorrelationContex_ContextSetToNull() { - Context orig = ContextUtils.withValue(null, Context.current()).attach(); - try { - CorrelationContext distContext = ContextUtils.getValue(Context.current()); - assertThat(distContext).isNotNull(); - assertThat(distContext.getEntries()).isEmpty(); - } finally { - Context.current().detach(orig); - } - } - - @Test - public void testGetCurrentCorrelationContex_ContextSetToNull_WithoutExplicitContext() { - Context orig = ContextUtils.withValue(null).attach(); - try { - CorrelationContext distContext = ContextUtils.getValue(); - assertThat(distContext).isNotNull(); - assertThat(distContext.getEntries()).isEmpty(); - } finally { - Context.current().detach(orig); - } - } -} diff --git a/api/src/test/java/io/opentelemetry/trace/TracingContextUtilsTest.java b/api/src/test/java/io/opentelemetry/trace/TracingContextUtilsTest.java new file mode 100644 index 00000000000..422a6b002c8 --- /dev/null +++ b/api/src/test/java/io/opentelemetry/trace/TracingContextUtilsTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2019, OpenTelemetry 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.opentelemetry.trace; + +import static com.google.common.truth.Truth.assertThat; + +import io.grpc.Context; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link TracingContextUtils}. */ +@RunWith(JUnit4.class) +public final class TracingContextUtilsTest { + + @Test + public void testGetCurrentSpan_Default() { + Span span = TracingContextUtils.getCurrentSpan(); + assertThat(span).isSameInstanceAs(DefaultSpan.getInvalid()); + } + + @Test + public void testGetCurrentSpan_SetSpan() { + Span span = DefaultSpan.create(SpanContext.getInvalid()); + Context orig = TracingContextUtils.withSpan(span, Context.current()).attach(); + try { + assertThat(TracingContextUtils.getCurrentSpan()).isSameInstanceAs(span); + } finally { + Context.current().detach(orig); + } + } + + @Test + public void testGetSpan_DefaultContext() { + Span span = TracingContextUtils.getSpan(Context.current()); + assertThat(span).isSameInstanceAs(DefaultSpan.getInvalid()); + } + + @Test + public void testGetSpan_ExplicitContext() { + Span span = DefaultSpan.create(SpanContext.getInvalid()); + Context context = TracingContextUtils.withSpan(span, Context.current()); + assertThat(TracingContextUtils.getSpan(context)).isSameInstanceAs(span); + } + + @Test + public void testGetSpanWithoutDefault_DefaultContext() { + Span span = TracingContextUtils.getSpanWithoutDefault(Context.current()); + assertThat(span).isNull(); + } + + @Test + public void testGetSpanWithoutDefault_ExplicitContext() { + Span span = DefaultSpan.create(SpanContext.getInvalid()); + Context context = TracingContextUtils.withSpan(span, Context.current()); + assertThat(TracingContextUtils.getSpanWithoutDefault(context)).isSameInstanceAs(span); + } +} diff --git a/api/src/test/java/io/opentelemetry/trace/unsafe/ContextUtilsTest.java b/api/src/test/java/io/opentelemetry/trace/unsafe/ContextUtilsTest.java deleted file mode 100644 index e751586a935..00000000000 --- a/api/src/test/java/io/opentelemetry/trace/unsafe/ContextUtilsTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2019, OpenTelemetry 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.opentelemetry.trace.unsafe; - -import static com.google.common.truth.Truth.assertThat; - -import io.grpc.Context; -import io.opentelemetry.trace.DefaultSpan; -import io.opentelemetry.trace.Span; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Unit tests for {@link ContextUtils}. */ -@RunWith(JUnit4.class) -public final class ContextUtilsTest { - @Test - public void testGetCurrentSpan_DefaultContext() { - Span span = ContextUtils.getValue(Context.current()); - assertThat(span).isNotNull(); - assertThat(span).isInstanceOf(DefaultSpan.class); - } - - @Test - public void testGetCurrentSpan_DefaultContext_WithoutExplicitContext() { - Span span = ContextUtils.getValue(); - assertThat(span).isNotNull(); - assertThat(span).isInstanceOf(DefaultSpan.class); - } - - @Test - public void testGetCurrentSpan_ContextSetToNull() { - Context orig = ContextUtils.withValue(null, Context.current()).attach(); - try { - Span span = ContextUtils.getValue(Context.current()); - assertThat(span).isNotNull(); - assertThat(span).isInstanceOf(DefaultSpan.class); - } finally { - Context.current().detach(orig); - } - } - - @Test - public void testGetCurrentSpan_ContextSetToNull_WithoutExplicitContext() { - Context orig = ContextUtils.withValue(null).attach(); - try { - Span span = ContextUtils.getValue(Context.current()); - assertThat(span).isNotNull(); - assertThat(span).isInstanceOf(DefaultSpan.class); - } finally { - Context.current().detach(orig); - } - } -} diff --git a/context_prop/src/main/java/io/opentelemetry/context/ContextUtils.java b/context_prop/src/main/java/io/opentelemetry/context/ContextUtils.java new file mode 100644 index 00000000000..aedce36d750 --- /dev/null +++ b/context_prop/src/main/java/io/opentelemetry/context/ContextUtils.java @@ -0,0 +1,61 @@ +/* + * Copyright 2019, OpenTelemetry 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.opentelemetry.context; + +import io.grpc.Context; +import javax.annotation.concurrent.Immutable; + +/** + * Util methods/functionality to interact with the {@link io.grpc.Context}. + * + * @since 0.1.0 + */ +@Immutable +public final class ContextUtils { + /** + * Sets the specified {@code Context} as {@code Context.current()}, returning a {@link Scope} to + * end its active state and restore the previous active {@code Context}. + * + * @param context the {@code Context} to be set as {@code Context.current()}. + * @return the {@link Scope} for the updated {@code Context}. + * @since 0.1.0 + */ + public static Scope withScopedContext(Context context) { + if (context == null) { + throw new NullPointerException("context"); + } + + return new ContextInScope(context); + } + + private static final class ContextInScope implements Scope { + private final Context context; + private final Context previous; + + public ContextInScope(Context context) { + this.context = context; + this.previous = context.attach(); + } + + @Override + public void close() { + context.detach(previous); + } + } + + private ContextUtils() {} +} diff --git a/context_prop/src/test/java/io/opentelemetry/context/ContextUtilsTest.java b/context_prop/src/test/java/io/opentelemetry/context/ContextUtilsTest.java new file mode 100644 index 00000000000..c3b511a7459 --- /dev/null +++ b/context_prop/src/test/java/io/opentelemetry/context/ContextUtilsTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2020, OpenTelemetry 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.opentelemetry.context; + +import static com.google.common.truth.Truth.assertThat; + +import io.grpc.Context; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link DefaultContextPropagators}. */ +@RunWith(JUnit4.class) +public class ContextUtilsTest { + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + private static final Context.Key SIMPLE_KEY = Context.key("simple"); + + @Test + public void withScopedContextNull() { + thrown.expect(NullPointerException.class); + ContextUtils.withScopedContext(null); + } + + @Test + public void withScopedContext() { + Context prevCtx = Context.current(); + Context ctx = Context.current().withValue(SIMPLE_KEY, "value1"); + Scope scope = ContextUtils.withScopedContext(ctx); + try { + assertThat(scope).isNotNull(); + assertThat(Context.current()).isEqualTo(ctx); + + Context ctx2 = Context.current().withValue(SIMPLE_KEY, "value2"); + Scope scope2 = ContextUtils.withScopedContext(ctx2); + try { + assertThat(scope2).isNotNull(); + assertThat(Context.current()).isEqualTo(ctx2); + } finally { + scope2.close(); + } + assertThat(Context.current()).isEqualTo(ctx); + } finally { + scope.close(); + } + assertThat(Context.current()).isEqualTo(prevCtx); + } +} diff --git a/contrib/trace_utils/src/main/java/io/opentelemetry/contrib/trace/CurrentSpanUtils.java b/contrib/trace_utils/src/main/java/io/opentelemetry/contrib/trace/CurrentSpanUtils.java index 52754b26ea2..374fd943f14 100644 --- a/contrib/trace_utils/src/main/java/io/opentelemetry/contrib/trace/CurrentSpanUtils.java +++ b/contrib/trace_utils/src/main/java/io/opentelemetry/contrib/trace/CurrentSpanUtils.java @@ -19,7 +19,7 @@ import io.grpc.Context; import io.opentelemetry.trace.Span; import io.opentelemetry.trace.Status; -import io.opentelemetry.trace.unsafe.ContextUtils; +import io.opentelemetry.trace.TracingContextUtils; import java.util.concurrent.Callable; /** Util methods/functionality to interact with the {@link Span} in the {@link io.grpc.Context}. */ @@ -65,7 +65,7 @@ private RunnableInSpan(Span span, Runnable runnable, boolean endSpan) { @Override public void run() { - Context origContext = ContextUtils.withValue(span).attach(); + Context origContext = TracingContextUtils.withSpan(span, Context.current()).attach(); try { runnable.run(); } catch (Throwable t) { @@ -98,7 +98,7 @@ private CallableInSpan(Span span, Callable callable, boolean endSpan) { @Override public V call() throws Exception { - Context origContext = ContextUtils.withValue(span).attach(); + Context origContext = TracingContextUtils.withSpan(span, Context.current()).attach(); try { return callable.call(); } catch (Exception e) { diff --git a/contrib/trace_utils/src/test/java/io/opentelemetry/contrib/trace/CurrentSpanUtilsTest.java b/contrib/trace_utils/src/test/java/io/opentelemetry/contrib/trace/CurrentSpanUtilsTest.java index ffbd78b3569..f6cf250610f 100644 --- a/contrib/trace_utils/src/test/java/io/opentelemetry/contrib/trace/CurrentSpanUtilsTest.java +++ b/contrib/trace_utils/src/test/java/io/opentelemetry/contrib/trace/CurrentSpanUtilsTest.java @@ -20,11 +20,10 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; -import io.grpc.Context; import io.opentelemetry.trace.DefaultSpan; import io.opentelemetry.trace.Span; import io.opentelemetry.trace.Status; -import io.opentelemetry.trace.unsafe.ContextUtils; +import io.opentelemetry.trace.TracingContextUtils; import java.util.concurrent.Callable; import org.junit.Before; import org.junit.Test; @@ -250,6 +249,6 @@ public Object call() throws Exception { } private static Span getCurrentSpan() { - return ContextUtils.getValue(Context.current()); + return TracingContextUtils.getCurrentSpan(); } } diff --git a/sdk/src/main/java/io/opentelemetry/sdk/correlationcontext/CorrelationContextManagerSdk.java b/sdk/src/main/java/io/opentelemetry/sdk/correlationcontext/CorrelationContextManagerSdk.java index e80737bbd0b..e3c2e01c9c3 100644 --- a/sdk/src/main/java/io/opentelemetry/sdk/correlationcontext/CorrelationContextManagerSdk.java +++ b/sdk/src/main/java/io/opentelemetry/sdk/correlationcontext/CorrelationContextManagerSdk.java @@ -20,8 +20,8 @@ import io.opentelemetry.context.propagation.HttpTextFormat; import io.opentelemetry.correlationcontext.CorrelationContext; import io.opentelemetry.correlationcontext.CorrelationContextManager; +import io.opentelemetry.correlationcontext.CorrelationsContextUtils; import io.opentelemetry.correlationcontext.DefaultCorrelationContextManager; -import io.opentelemetry.correlationcontext.unsafe.ContextUtils; /** * {@link CorrelationContextManagerSdk} is SDK implementation of {@link CorrelationContextManager}. @@ -30,7 +30,7 @@ public class CorrelationContextManagerSdk implements CorrelationContextManager { @Override public CorrelationContext getCurrentContext() { - return ContextUtils.getValue(); + return CorrelationsContextUtils.getCurrentCorrelationContext(); } @Override @@ -40,7 +40,7 @@ public CorrelationContext.Builder contextBuilder() { @Override public Scope withContext(CorrelationContext distContext) { - return ContextUtils.withCorrelationContext(distContext); + return CorrelationsContextUtils.withScopedCorrelationContext(distContext); } @Override diff --git a/sdk/src/main/java/io/opentelemetry/sdk/trace/SpanBuilderSdk.java b/sdk/src/main/java/io/opentelemetry/sdk/trace/SpanBuilderSdk.java index 67c6d5e7563..bd6d73d4889 100644 --- a/sdk/src/main/java/io/opentelemetry/sdk/trace/SpanBuilderSdk.java +++ b/sdk/src/main/java/io/opentelemetry/sdk/trace/SpanBuilderSdk.java @@ -36,7 +36,7 @@ import io.opentelemetry.trace.TraceFlags; import io.opentelemetry.trace.TraceId; import io.opentelemetry.trace.TraceState; -import io.opentelemetry.trace.unsafe.ContextUtils; +import io.opentelemetry.trace.TracingContextUtils; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -248,7 +248,7 @@ private static Clock getClock(Span parent, Clock clock) { @Nullable private static SpanContext parent( ParentType parentType, Span explicitParent, SpanContext remoteParent) { - Span currentSpan = ContextUtils.getValue(); + Span currentSpan = TracingContextUtils.getCurrentSpan(); switch (parentType) { case NO_PARENT: return null; @@ -266,7 +266,7 @@ private static SpanContext parent( private static Span parentSpan(ParentType parentType, Span explicitParent) { switch (parentType) { case CURRENT_SPAN: - return ContextUtils.getValue(); + return TracingContextUtils.getCurrentSpan(); case EXPLICIT_PARENT: return explicitParent; default: diff --git a/sdk/src/main/java/io/opentelemetry/sdk/trace/TracerSdk.java b/sdk/src/main/java/io/opentelemetry/sdk/trace/TracerSdk.java index c4495118f4d..5f3be362bbf 100644 --- a/sdk/src/main/java/io/opentelemetry/sdk/trace/TracerSdk.java +++ b/sdk/src/main/java/io/opentelemetry/sdk/trace/TracerSdk.java @@ -23,8 +23,8 @@ import io.opentelemetry.trace.Span; import io.opentelemetry.trace.SpanContext; import io.opentelemetry.trace.Tracer; +import io.opentelemetry.trace.TracingContextUtils; import io.opentelemetry.trace.propagation.HttpTraceContext; -import io.opentelemetry.trace.unsafe.ContextUtils; /** {@link TracerSdk} is SDK implementation of {@link Tracer}. */ public final class TracerSdk implements Tracer { @@ -39,12 +39,12 @@ public final class TracerSdk implements Tracer { @Override public Span getCurrentSpan() { - return ContextUtils.getValue(); + return TracingContextUtils.getCurrentSpan(); } @Override public Scope withSpan(Span span) { - return ContextUtils.withSpan(span); + return TracingContextUtils.withScopedSpan(span); } @Override diff --git a/sdk/src/test/java/io/opentelemetry/sdk/correlationcontext/CorrelationContextManagerSdkTest.java b/sdk/src/test/java/io/opentelemetry/sdk/correlationcontext/CorrelationContextManagerSdkTest.java index b81a8daa636..7adf692d994 100644 --- a/sdk/src/test/java/io/opentelemetry/sdk/correlationcontext/CorrelationContextManagerSdkTest.java +++ b/sdk/src/test/java/io/opentelemetry/sdk/correlationcontext/CorrelationContextManagerSdkTest.java @@ -21,8 +21,8 @@ import io.grpc.Context; import io.opentelemetry.context.Scope; import io.opentelemetry.correlationcontext.CorrelationContext; +import io.opentelemetry.correlationcontext.CorrelationsContextUtils; import io.opentelemetry.correlationcontext.EmptyCorrelationContext; -import io.opentelemetry.correlationcontext.unsafe.ContextUtils; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -52,7 +52,8 @@ public void testGetCurrentContext_DefaultContext() { @Test public void testGetCurrentContext_ContextSetToNull() { - Context orig = ContextUtils.withValue(null).attach(); + Context orig = + CorrelationsContextUtils.withCorrelationContext(null, Context.current()).attach(); try { CorrelationContext distContext = contextManager.getCurrentContext(); assertThat(distContext).isNotNull(); diff --git a/sdk/src/test/java/io/opentelemetry/sdk/trace/TracerSdkTest.java b/sdk/src/test/java/io/opentelemetry/sdk/trace/TracerSdkTest.java index aae3c14340d..f51f4f885c7 100644 --- a/sdk/src/test/java/io/opentelemetry/sdk/trace/TracerSdkTest.java +++ b/sdk/src/test/java/io/opentelemetry/sdk/trace/TracerSdkTest.java @@ -23,8 +23,8 @@ import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.trace.DefaultSpan; import io.opentelemetry.trace.Span; +import io.opentelemetry.trace.TracingContextUtils; import io.opentelemetry.trace.propagation.HttpTraceContext; -import io.opentelemetry.trace.unsafe.ContextUtils; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -74,7 +74,7 @@ public void defaultHttpTextFormat() { @Test public void getCurrentSpan() { assertThat(tracer.getCurrentSpan()).isInstanceOf(DefaultSpan.class); - Context origContext = ContextUtils.withValue(span).attach(); + Context origContext = TracingContextUtils.withSpan(span, Context.current()).attach(); // Make sure context is detached even if test fails. try { assertThat(tracer.getCurrentSpan()).isSameInstanceAs(span);