diff --git a/vertx-opentelemetry/src/main/asciidoc/index.adoc b/vertx-opentelemetry/src/main/asciidoc/index.adoc index d848cb6..66df7e3 100644 --- a/vertx-opentelemetry/src/main/asciidoc/index.adoc +++ b/vertx-opentelemetry/src/main/asciidoc/index.adoc @@ -23,6 +23,19 @@ which gives dummy values (all zeroes) for trace and span ids. The OpenTelemetry {@link examples.OpenTelemetryExamples#ex7} ---- +[NOTE] +==== +This project provides an OpenTelemetry `ContextStorageProvider` that uses the Vert.x {@link io.vertx.core.Context} when invoked on a Vert.x thread. +Otherwise, it fallbacks to the default storage. + +If several `ContextStorageProvider` implementations are present on the classpath, you can force OpenTelemetry to select the Vert.x one: + +[source] +---- +-Dio.opentelemetry.context.contextStorageProvider=io.vertx.tracing.opentelemetry.VertxContextStorageProvider +---- +==== + == Tracing policy The tracing policy defines the behavior of a component when tracing is enabled: diff --git a/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/OpenTelemetryOptions.java b/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/OpenTelemetryOptions.java index bd8dcf5..449c810 100644 --- a/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/OpenTelemetryOptions.java +++ b/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/OpenTelemetryOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2021 Contributors to the Eclipse Foundation + * Copyright (c) 2011-2023 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -12,8 +12,6 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.context.Scope; import io.vertx.codegen.annotations.DataObject; import io.vertx.core.json.JsonObject; import io.vertx.core.spi.tracing.VertxTracer; @@ -38,7 +36,7 @@ public OpenTelemetryOptions(JsonObject json) { this.setFactory(OpenTelemetryTracingFactory.INSTANCE); } - VertxTracer buildTracer() { + VertxTracer buildTracer() { if (openTelemetry != null) { return new OpenTelemetryTracer(openTelemetry); } else { diff --git a/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/OpenTelemetryTracer.java b/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/OpenTelemetryTracer.java index e30ddd1..168d1dd 100644 --- a/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/OpenTelemetryTracer.java +++ b/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/OpenTelemetryTracer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2021 Contributors to the Eclipse Foundation + * Copyright (c) 2011-2023 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -16,6 +16,7 @@ import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanBuilder; import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Scope; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.context.propagation.TextMapGetter; import io.opentelemetry.context.propagation.TextMapSetter; @@ -24,13 +25,12 @@ import io.vertx.core.spi.tracing.TagExtractor; import io.vertx.core.spi.tracing.VertxTracer; import io.vertx.core.tracing.TracingPolicy; +import io.vertx.tracing.opentelemetry.VertxContextStorageProvider.VertxContextStorage; import java.util.Map.Entry; import java.util.function.BiConsumer; -import static io.vertx.tracing.opentelemetry.VertxContextStorageProvider.ACTIVE_CONTEXT; - -class OpenTelemetryTracer implements VertxTracer { +class OpenTelemetryTracer implements VertxTracer { private static final TextMapGetter>> getter = new HeadersPropagatorGetter(); private static final TextMapSetter> setter = new HeadersPropagatorSetter(); @@ -44,7 +44,7 @@ class OpenTelemetryTracer implements VertxTracer { } @Override - public Span receiveRequest( + public Operation receiveRequest( final Context context, final SpanKind kind, final TracingPolicy policy, @@ -57,49 +57,61 @@ public Span receiveRequest( return null; } - io.opentelemetry.context.Context tracingContext = propagators.getTextMapPropagator().extract(io.opentelemetry.context.Context.current(), headers, getter); + io.opentelemetry.context.Context otelCtx; + if ((otelCtx = VertxContextStorage.INSTANCE.current()) == null) { + otelCtx = io.opentelemetry.context.Context.root(); + } + + otelCtx = propagators.getTextMapPropagator().extract(otelCtx, headers, getter); // If no span, and policy is PROPAGATE, then don't create the span - if (Span.fromContextOrNull(tracingContext) == null && TracingPolicy.PROPAGATE.equals(policy)) { + if (Span.fromContextOrNull(otelCtx) == null && TracingPolicy.PROPAGATE.equals(policy)) { return null; } - final Span span = reportTagsAndStart(tracer + io.opentelemetry.api.trace.SpanKind spanKind = SpanKind.RPC.equals(kind) ? io.opentelemetry.api.trace.SpanKind.SERVER : io.opentelemetry.api.trace.SpanKind.CONSUMER; + + SpanBuilder spanBuilder = tracer .spanBuilder(operation) - .setParent(tracingContext) - .setSpanKind(SpanKind.RPC.equals(kind) ? io.opentelemetry.api.trace.SpanKind.SERVER : io.opentelemetry.api.trace.SpanKind.CONSUMER), request, tagExtractor, false); + .setParent(otelCtx) + .setSpanKind(spanKind); - VertxContextStorageProvider.VertxContextStorage.INSTANCE.attach(context, tracingContext.with(span)); + Span span = reportTagsAndStart(spanBuilder, request, tagExtractor, false); + Scope scope = VertxContextStorage.INSTANCE.attach(context, span.storeInContext(otelCtx)); - return span; + return new Operation(span, scope); } @Override public void sendResponse( final Context context, final R response, - final Span span, + final Operation operation, final Throwable failure, final TagExtractor tagExtractor) { - if (span != null) { - context.remove(ACTIVE_CONTEXT); - end(span, response, tagExtractor, failure, false); + if (operation != null) { + end(operation, response, tagExtractor, failure, false); } } - private static void end(Span span, R response, TagExtractor tagExtractor, Throwable failure, boolean client) { - if (failure != null) { - span.recordException(failure); - } - if (response != null) { - Attributes attributes = processTags(response, tagExtractor, client); - span.setAllAttributes(attributes); + private static void end(Operation operation, R response, TagExtractor tagExtractor, Throwable failure, boolean client) { + Span span = operation.span(); + try { + if (failure != null) { + span.recordException(failure); + } + if (response != null) { + Attributes attributes = processTags(response, tagExtractor, client); + span.setAllAttributes(attributes); + } + span.end(); + } finally { + operation.scope().close(); } - span.end(); } @Override - public Span sendRequest( + public Operation sendRequest( final Context context, final SpanKind kind, final TracingPolicy policy, @@ -112,36 +124,38 @@ public Span sendRequest( return null; } - io.opentelemetry.context.Context tracingContext = context.getLocal(ACTIVE_CONTEXT); + io.opentelemetry.context.Context otelCtx = VertxContextStorage.INSTANCE.current(); - if (tracingContext == null && !TracingPolicy.ALWAYS.equals(policy)) { - return null; + if (otelCtx == null) { + if (!TracingPolicy.ALWAYS.equals(policy)) { + return null; + } + otelCtx = io.opentelemetry.context.Context.root(); } - if (tracingContext == null) { - tracingContext = io.opentelemetry.context.Context.root(); - } + io.opentelemetry.api.trace.SpanKind spanKind = SpanKind.RPC.equals(kind) ? io.opentelemetry.api.trace.SpanKind.CLIENT : io.opentelemetry.api.trace.SpanKind.PRODUCER; + + SpanBuilder spanBuilder = tracer.spanBuilder(operation) + .setParent(otelCtx) + .setSpanKind(spanKind); - final Span span = reportTagsAndStart(tracer.spanBuilder(operation) - .setParent(tracingContext) - .setSpanKind(SpanKind.RPC.equals(kind) ? io.opentelemetry.api.trace.SpanKind.CLIENT : io.opentelemetry.api.trace.SpanKind.PRODUCER) - , request, tagExtractor, true); + Span span = reportTagsAndStart(spanBuilder, request, tagExtractor, true); - tracingContext = tracingContext.with(span); - propagators.getTextMapPropagator().inject(tracingContext, headers, setter); + otelCtx = otelCtx.with(span); + propagators.getTextMapPropagator().inject(otelCtx, headers, setter); - return span; + return new Operation(span, Scope.noop()); } @Override public void receiveResponse( final Context context, final R response, - final Span span, + final Operation operation, final Throwable failure, final TagExtractor tagExtractor) { - if (span != null) { - end(span, response, tagExtractor, failure, true); + if (operation != null) { + end(operation, response, tagExtractor, failure, true); } } diff --git a/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/OpenTelemetryTracingFactory.java b/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/OpenTelemetryTracingFactory.java index a2887e2..7675c1b 100644 --- a/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/OpenTelemetryTracingFactory.java +++ b/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/OpenTelemetryTracingFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2021 Contributors to the Eclipse Foundation + * Copyright (c) 2011-2023 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -10,8 +10,6 @@ */ package io.vertx.tracing.opentelemetry; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.context.Scope; import io.vertx.core.json.JsonObject; import io.vertx.core.spi.VertxTracerFactory; import io.vertx.core.spi.tracing.VertxTracer; @@ -22,7 +20,7 @@ public class OpenTelemetryTracingFactory implements VertxTracerFactory { static final OpenTelemetryTracingFactory INSTANCE = new OpenTelemetryTracingFactory(); @Override - public VertxTracer tracer(final TracingOptions options) { + public VertxTracer tracer(final TracingOptions options) { OpenTelemetryOptions openTelemetryOptions; if (options instanceof OpenTelemetryOptions) { openTelemetryOptions = (OpenTelemetryOptions) options; diff --git a/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/Operation.java b/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/Operation.java new file mode 100644 index 0000000..ddb8be7 --- /dev/null +++ b/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/Operation.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011-2023 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + */ + +package io.vertx.tracing.opentelemetry; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Scope; + +import java.util.Objects; + +final class Operation { + + private final Span span; + private final Scope scope; + + Operation(Span span, Scope scope) { + this.span = Objects.requireNonNull(span); + this.scope = Objects.requireNonNull(scope); + } + + public Span span() { + return span; + } + + public Scope scope() { + return scope; + } +} diff --git a/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/VertxContextStorageProvider.java b/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/VertxContextStorageProvider.java index 31052d3..de9a553 100644 --- a/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/VertxContextStorageProvider.java +++ b/vertx-opentelemetry/src/main/java/io/vertx/tracing/opentelemetry/VertxContextStorageProvider.java @@ -1,14 +1,25 @@ +/* + * Copyright (c) 2011-2023 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + */ + package io.vertx.tracing.opentelemetry; import io.opentelemetry.context.Context; import io.opentelemetry.context.ContextStorage; import io.opentelemetry.context.ContextStorageProvider; import io.opentelemetry.context.Scope; -import io.vertx.core.Vertx; +import io.vertx.core.impl.ContextInternal; public class VertxContextStorageProvider implements ContextStorageProvider { - static String ACTIVE_CONTEXT = "tracing.context"; + private static final Object ACTIVE_CONTEXT = new Object(); @Override public ContextStorage get() { @@ -20,7 +31,11 @@ enum VertxContextStorage implements ContextStorage { @Override public Scope attach(Context toAttach) { - return attach(Vertx.currentContext(), toAttach); + ContextInternal current = ContextInternal.current(); + if (current == null) { + return ContextStorage.defaultStorage().attach(toAttach); + } + return attach(current, toAttach); } public Scope attach(io.vertx.core.Context vertxCtx, Context toAttach) { @@ -40,9 +55,9 @@ public Scope attach(io.vertx.core.Context vertxCtx, Context toAttach) { @Override public Context current() { - io.vertx.core.Context vertxCtx = Vertx.currentContext(); + ContextInternal vertxCtx = ContextInternal.current(); if (vertxCtx == null) { - return null; + return ContextStorage.defaultStorage().current(); } return vertxCtx.getLocal(ACTIVE_CONTEXT); } diff --git a/vertx-opentelemetry/src/test/java/io/vertx/tracing/opentelemetry/OpenTelemetryIntegrationTest.java b/vertx-opentelemetry/src/test/java/io/vertx/tracing/opentelemetry/OpenTelemetryIntegrationTest.java index bebd1bc..a941a9a 100644 --- a/vertx-opentelemetry/src/test/java/io/vertx/tracing/opentelemetry/OpenTelemetryIntegrationTest.java +++ b/vertx-opentelemetry/src/test/java/io/vertx/tracing/opentelemetry/OpenTelemetryIntegrationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2021 Contributors to the Eclipse Foundation + * Copyright (c) 2011-2023 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -22,13 +22,7 @@ import io.vertx.core.Future; import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; -import io.vertx.core.http.HttpClient; -import io.vertx.core.http.HttpClientOptions; -import io.vertx.core.http.HttpClientRequest; -import io.vertx.core.http.HttpClientResponse; -import io.vertx.core.http.HttpMethod; -import io.vertx.core.http.HttpServerOptions; -import io.vertx.core.http.RequestOptions; +import io.vertx.core.http.*; import io.vertx.core.tracing.TracingPolicy; import io.vertx.junit5.Checkpoint; import io.vertx.junit5.VertxExtension; @@ -49,21 +43,20 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; -import static org.junit.Assert.assertEquals; @ExtendWith(VertxExtension.class) public class OpenTelemetryIntegrationTest { @RegisterExtension - final OpenTelemetryExtension otelTesting = OpenTelemetryExtension.create(); + OpenTelemetryExtension otelTesting = OpenTelemetryExtension.create(); + private Vertx vertx; private TextMapPropagator textMapPropagator; @@ -249,35 +242,27 @@ private void sendRequest(VertxTestContext context) throws IOException { } - private void sendRequestWithTrace() throws IOException, ExecutionException, InterruptedException { + private void sendRequestWithTrace() throws Exception { URL url = new URL("http://localhost:8080"); - // We need to run this inside a vertx context in order to don't make the current span thingy to fail - vertx.executeBlocking(p -> { - Span span = otelTesting.getOpenTelemetry().getTracer("io.vertx").spanBuilder("/") - .setSpanKind(SpanKind.CLIENT) - .setAttribute("component", "vertx") - .startSpan(); - try { - span - .setAttribute(SemanticAttributes.HTTP_METHOD, "GET") - .setAttribute(SemanticAttributes.HTTP_URL, url.toString()); - - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - textMapPropagator.inject(io.opentelemetry.context.Context.root().with(span), con, setter); - con.setRequestMethod("GET"); - - assertThat(con.getResponseCode()).isEqualTo(200); - } catch (IOException e) { - e.printStackTrace(); - } finally { - span.end(); - p.complete(); - } - }) - .toCompletionStage() - .toCompletableFuture() - .get(); + Span span = otelTesting.getOpenTelemetry().getTracer("io.vertx").spanBuilder("/") + .setSpanKind(SpanKind.CLIENT) + .setAttribute("component", "vertx") + .startSpan(); + + try { + span + .setAttribute(SemanticAttributes.HTTP_METHOD, "GET") + .setAttribute(SemanticAttributes.HTTP_URL, url.toString()); + + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + textMapPropagator.inject(io.opentelemetry.context.Context.root().with(span), con, setter); + con.setRequestMethod("GET"); + + assertThat(con.getResponseCode()).isEqualTo(200); + } finally { + span.end(); + } } @Test diff --git a/vertx-opentelemetry/src/test/java/io/vertx/tracing/opentelemetry/OpenTelemetryTracingFactoryTest.java b/vertx-opentelemetry/src/test/java/io/vertx/tracing/opentelemetry/OpenTelemetryTracingFactoryTest.java index c871773..df1adab 100644 --- a/vertx-opentelemetry/src/test/java/io/vertx/tracing/opentelemetry/OpenTelemetryTracingFactoryTest.java +++ b/vertx-opentelemetry/src/test/java/io/vertx/tracing/opentelemetry/OpenTelemetryTracingFactoryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2021 Contributors to the Eclipse Foundation + * Copyright (c) 2011-2023 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -14,6 +14,7 @@ import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; +import io.opentelemetry.context.Scope; import io.opentelemetry.context.propagation.ContextPropagators; import io.vertx.core.Context; import io.vertx.core.Vertx; @@ -22,6 +23,7 @@ import io.vertx.core.spi.tracing.VertxTracer; import io.vertx.core.tracing.TracingPolicy; import io.vertx.junit5.VertxExtension; +import io.vertx.tracing.opentelemetry.VertxContextStorageProvider.VertxContextStorage; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -32,7 +34,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; -import static io.vertx.tracing.opentelemetry.VertxContextStorageProvider.ACTIVE_CONTEXT; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatNoException; import static org.mockito.Mockito.*; @@ -42,9 +43,9 @@ public class OpenTelemetryTracingFactoryTest { @Test public void receiveRequestShouldNotReturnSpanIfPolicyIsIgnore(final Vertx vertx) { - final VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); + VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); - final Span span = tracer.receiveRequest( + final Operation operation = tracer.receiveRequest( vertx.getOrCreateContext(), SpanKind.MESSAGING, TracingPolicy.IGNORE, @@ -54,14 +55,14 @@ public void receiveRequestShouldNotReturnSpanIfPolicyIsIgnore(final Vertx vertx) TagExtractor.empty() ); - assertThat(span).isNull(); + assertThat(operation).isNull(); } @Test public void receiveRequestShouldNotReturnSpanIfPolicyIsPropagateAndPreviousContextIsNotPresent(final Vertx vertx) { - final VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); + VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); - final Span span = tracer.receiveRequest( + final Operation operation = tracer.receiveRequest( vertx.getOrCreateContext(), SpanKind.MESSAGING, TracingPolicy.PROPAGATE, @@ -71,12 +72,12 @@ public void receiveRequestShouldNotReturnSpanIfPolicyIsPropagateAndPreviousConte TagExtractor.empty() ); - assertThat(span).isNull(); + assertThat(operation).isNull(); } @Test public void receiveRequestShouldReturnSpanIfPolicyIsPropagateAndPreviousContextIsPresent(final Vertx vertx) { - final VertxTracer tracer = new OpenTelemetryOptions( + VertxTracer tracer = new OpenTelemetryOptions( OpenTelemetry.propagating(ContextPropagators.create(W3CTraceContextPropagator.getInstance())) ).buildTracer(); @@ -85,7 +86,7 @@ public void receiveRequestShouldReturnSpanIfPolicyIsPropagateAndPreviousContextI ); final io.vertx.core.Context ctx = vertx.getOrCreateContext(); - final Span span = tracer.receiveRequest( + final Operation operation = tracer.receiveRequest( ctx, SpanKind.MESSAGING, TracingPolicy.PROPAGATE, @@ -95,10 +96,9 @@ public void receiveRequestShouldReturnSpanIfPolicyIsPropagateAndPreviousContextI TagExtractor.empty() ); - assertThat(span) - .isNotNull(); + assertThat(operation).isNotNull(); - final io.opentelemetry.context.Context tracingContext = ctx.getLocal(ACTIVE_CONTEXT); + final io.opentelemetry.context.Context tracingContext = VertxContextStorage.INSTANCE.current(); assertThat(tracingContext).isNotNull(); } @@ -113,14 +113,14 @@ public void receiveRequestShouldReturnAParentedSpanIfPolicyIsPropagateAndTheOtel final Span parentSpan = otelTracer.spanBuilder("example-span") .startSpan(); - CompletableFuture futureSpan = new CompletableFuture<>(); + CompletableFuture futureOperation = new CompletableFuture<>(); vertx.runOnContext(unused -> { parentSpan.makeCurrent(); - final VertxTracer tracer = new OpenTelemetryOptions(openTelemetry).buildTracer(); + VertxTracer tracer = new OpenTelemetryOptions(openTelemetry).buildTracer(); - final Span span = tracer.receiveRequest( + final Operation operation = tracer.receiveRequest( vertx.getOrCreateContext(), SpanKind.MESSAGING, TracingPolicy.PROPAGATE, @@ -132,27 +132,29 @@ public void receiveRequestShouldReturnAParentedSpanIfPolicyIsPropagateAndTheOtel parentSpan.end(); - futureSpan.complete(span); + futureOperation.complete(operation); }); - Span span = futureSpan.get(); + Operation operation = futureOperation.get(); - assertThat(span).isNotNull(); - assertThat(span.getSpanContext().getTraceId()) + assertThat(operation).isNotNull(); + assertThat(operation.span().getSpanContext().getTraceId()) .isEqualTo(parentSpan.getSpanContext().getTraceId()); } @Test public void sendResponseEndsSpan(final Vertx vertx) { - final VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); + VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); - final Span span = mock(Span.class); + Span span = mock(Span.class); doNothing().when(span).end(); + Scope scope = mock(Scope.class); + Operation operation = new Operation(span, scope); tracer.sendResponse( vertx.getOrCreateContext(), mock(Serializable.class), - span, + operation, mock(Exception.class), TagExtractor.empty() ); @@ -162,7 +164,7 @@ public void sendResponseEndsSpan(final Vertx vertx) { @Test public void sendResponseShouldNotThrowExceptionWhenSpanIsNull(final Vertx vertx) { - final VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); + VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); assertThatNoException().isThrownBy(() -> tracer.sendResponse( vertx.getOrCreateContext(), @@ -175,12 +177,12 @@ public void sendResponseShouldNotThrowExceptionWhenSpanIsNull(final Vertx vertx) @Test public void sendRequestShouldNotReturnSpanIfRequestIsNull(final Vertx vertx) { - final VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); + VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); final Context ctx = vertx.getOrCreateContext(); - ctx.putLocal(ACTIVE_CONTEXT, io.opentelemetry.context.Context.current()); + VertxContextStorage.INSTANCE.attach(io.opentelemetry.context.Context.current()); - final Span span = tracer.sendRequest( + final Operation operation = tracer.sendRequest( ctx, SpanKind.MESSAGING, TracingPolicy.PROPAGATE, @@ -191,17 +193,17 @@ public void sendRequestShouldNotReturnSpanIfRequestIsNull(final Vertx vertx) { TagExtractor.empty() ); - assertThat(span).isNull(); + assertThat(operation).isNull(); } @Test public void sendRequestShouldNotReturnSpanIfPolicyIsIgnore(final Vertx vertx) { - final VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); + VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); final Context ctx = vertx.getOrCreateContext(); - ctx.putLocal(ACTIVE_CONTEXT, io.opentelemetry.context.Context.current()); + VertxContextStorage.INSTANCE.attach(io.opentelemetry.context.Context.current()); - final Span span = tracer.sendRequest( + final Operation operation = tracer.sendRequest( ctx, SpanKind.MESSAGING, TracingPolicy.IGNORE, @@ -212,15 +214,15 @@ public void sendRequestShouldNotReturnSpanIfPolicyIsIgnore(final Vertx vertx) { TagExtractor.empty() ); - assertThat(span).isNull(); + assertThat(operation).isNull(); } @Test public void sendRequestShouldNotReturnSpanIfPolicyIsPropagateAndPreviousContextIsNotPresent(final Vertx vertx) { - final VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); + VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); - final Span span = tracer.sendRequest( + final Operation operation = tracer.sendRequest( vertx.getOrCreateContext(), SpanKind.MESSAGING, TracingPolicy.PROPAGATE, @@ -231,17 +233,17 @@ public void sendRequestShouldNotReturnSpanIfPolicyIsPropagateAndPreviousContextI TagExtractor.empty() ); - assertThat(span).isNull(); + assertThat(operation).isNull(); } @Test public void sendRequestShouldReturnSpanIfPolicyIsPropagateAndPreviousContextIsPresent(final Vertx vertx) { - final VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); + VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); final Context ctx = vertx.getOrCreateContext(); - ctx.putLocal(ACTIVE_CONTEXT, io.opentelemetry.context.Context.current()); + VertxContextStorage.INSTANCE.attach(io.opentelemetry.context.Context.current()); - final Span span = tracer.sendRequest( + final Operation operation = tracer.sendRequest( ctx, SpanKind.MESSAGING, TracingPolicy.PROPAGATE, @@ -252,16 +254,16 @@ public void sendRequestShouldReturnSpanIfPolicyIsPropagateAndPreviousContextIsPr TagExtractor.empty() ); - assertThat(span).isNotNull(); + assertThat(operation).isNotNull(); } @Test public void sendRequestShouldReturnSpanIfPolicyIsAlwaysAndPreviousContextIsNotPresent(final Vertx vertx) { - final VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); + VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); final Context ctx = vertx.getOrCreateContext(); - final Span span = tracer.sendRequest( + final Operation operation = tracer.sendRequest( ctx, SpanKind.MESSAGING, TracingPolicy.ALWAYS, @@ -272,20 +274,22 @@ public void sendRequestShouldReturnSpanIfPolicyIsAlwaysAndPreviousContextIsNotPr TagExtractor.empty() ); - assertThat(span).isNotNull(); + assertThat(operation).isNotNull(); } @Test public void receiveResponseEndsSpan(final Vertx vertx) { - final VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); + VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); - final Span span = mock(Span.class); + Span span = mock(Span.class); doNothing().when(span).end(); + Scope scope = mock(Scope.class); + Operation operation = new Operation(span, scope); tracer.receiveResponse( vertx.getOrCreateContext(), mock(Serializable.class), - span, + operation, mock(Exception.class), TagExtractor.empty() ); @@ -295,7 +299,7 @@ public void receiveResponseEndsSpan(final Vertx vertx) { @Test public void receiveResponseShouldNotThrowExceptionWhenSpanIsNull(final Vertx vertx) { - final VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); + VertxTracer tracer = new OpenTelemetryOptions(OpenTelemetry.noop()).buildTracer(); assertThatNoException().isThrownBy(() -> tracer.receiveResponse( vertx.getOrCreateContext(),