Migrate opentelemetry-api testing module to Instrumenter API
MODIFY
instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/groovy/ContextBridgeTest.groovy
instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/groovy/ContextBridgeTest.groovy
@@ -11,7 +11,6 @@ import io.opentelemetry.context.ContextKey
import io.opentelemetry.extension.annotations.WithSpan
import io.opentelemetry.instrumentation.api.instrumenter.SpanKey
import io.opentelemetry.instrumentation.api.tracer.ClientSpan
-import io.opentelemetry.instrumentation.api.tracer.ConsumerSpan
import io.opentelemetry.instrumentation.api.tracer.ServerSpan
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
@@ -161,17 +160,6 @@ class ContextBridgeTest extends AgentInstrumentationSpecification {
}
}
- def "test consumer span bridge"() {
- expect:
- AgentSpanTesting.runWithConsumerSpan("consumer") {
- assert Span.current() != null
- assert ConsumerSpan.fromContextOrNull(Context.current()) != null
- runWithSpan("internal") {
- assert ConsumerSpan.fromContextOrNull(Context.current()) != null
- }
- }
- }
-
def "test client span bridge"() {
expect:
AgentSpanTesting.runWithClientSpan("client") {

MODIFY
instrumentation/opentelemetry-api/opentelemetry-api-1.0/testing/src/main/java/AgentSpanTesting.java
instrumentation/opentelemetry-api/opentelemetry-api-1.0/testing/src/main/java/AgentSpanTesting.java
@@ -13,14 +13,6 @@ public class AgentSpanTesting {
runnable.run();
}
- /**
- * Runs the provided {@code runnable} inside the scope of an CONSUMER span with name {@code
- * spanName}.
- */
- public static void runWithConsumerSpan(String spanName, Runnable runnable) {
- runnable.run();
- }
-
/**
* Runs the provided {@code runnable} inside the scope of an CLIENT span with name {@code
* spanName}.

MODIFY
instrumentation/opentelemetry-api/opentelemetry-api-1.0/testing/src/main/java/AgentSpanTestingInstrumentation.java
instrumentation/opentelemetry-api/opentelemetry-api-1.0/testing/src/main/java/AgentSpanTestingInstrumentation.java
@@ -24,8 +24,6 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
public void transform(TypeTransformer transformer) {
transformer.applyAdviceToMethod(
named("runWithServerSpan"), this.getClass().getName() + "$RunWithServerSpanAdvice");
- transformer.applyAdviceToMethod(
- named("runWithConsumerSpan"), this.getClass().getName() + "$RunWithConsumerSpanAdvice");
transformer.applyAdviceToMethod(
named("runWithClientSpan"), this.getClass().getName() + "$RunWithClientSpanAdvice");
transformer.applyAdviceToMethod(
@@ -40,33 +38,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
@Advice.Argument(0) String spanName,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
- context = AgentSpanTestingTracer.tracer().startServerSpan(spanName);
- scope = context.makeCurrent();
- }
-
- @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
- public static void onExit(
- @Advice.Thrown Throwable throwable,
- @Advice.Local("otelContext") Context context,
- @Advice.Local("otelScope") Scope scope) {
- scope.close();
- if (throwable != null) {
- AgentSpanTestingTracer.tracer().endExceptionally(context, throwable);
- } else {
- AgentSpanTestingTracer.tracer().end(context);
- }
- }
- }
-
- @SuppressWarnings("unused")
- public static class RunWithConsumerSpanAdvice {
-
- @Advice.OnMethodEnter(suppress = Throwable.class)
- public static void onEnter(
- @Advice.Argument(0) String spanName,
- @Advice.Local("otelContext") Context context,
- @Advice.Local("otelScope") Scope scope) {
- context = AgentSpanTestingTracer.tracer().startConsumerSpan(spanName);
+ context = AgentSpanTestingInstrumenter.startServerSpan(spanName);
scope = context.makeCurrent();
}
@@ -76,11 +48,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
scope.close();
- if (throwable != null) {
- AgentSpanTestingTracer.tracer().endExceptionally(context, throwable);
- } else {
- AgentSpanTestingTracer.tracer().end(context);
- }
+ AgentSpanTestingInstrumenter.end(context, throwable);
}
}
@@ -92,7 +60,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
@Advice.Argument(0) String spanName,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
- context = AgentSpanTestingTracer.tracer().startClientSpan(spanName);
+ context = AgentSpanTestingInstrumenter.startClientSpan(spanName);
scope = context.makeCurrent();
}
@@ -102,11 +70,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
scope.close();
- if (throwable != null) {
- AgentSpanTestingTracer.tracer().endExceptionally(context, throwable);
- } else {
- AgentSpanTestingTracer.tracer().end(context);
- }
+ AgentSpanTestingInstrumenter.end(context, throwable);
}
}
@@ -118,7 +82,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
@Advice.Argument(0) String spanName,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
- context = AgentSpanTestingTracer.tracer().startSpanWithAllKeys(spanName);
+ context = AgentSpanTestingInstrumenter.startSpanWithAllKeys(spanName);
scope = context.makeCurrent();
}
@@ -128,11 +92,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
scope.close();
- if (throwable != null) {
- AgentSpanTestingTracer.tracer().endExceptionally(context, throwable);
- } else {
- AgentSpanTestingTracer.tracer().end(context);
- }
+ AgentSpanTestingInstrumenter.end(context, throwable);
}
}
}

MODIFY
instrumentation/opentelemetry-api/opentelemetry-api-1.0/testing/src/main/java/AgentSpanTestingInstrumentationModule.java
instrumentation/opentelemetry-api/opentelemetry-api-1.0/testing/src/main/java/AgentSpanTestingInstrumentationModule.java
@@ -18,7 +18,7 @@ public class AgentSpanTestingInstrumentationModule extends InstrumentationModule
@Override
public boolean isHelperClass(String className) {
- return className.startsWith("AgentSpanTestingTracer");
+ return className.startsWith("AgentSpanTestingInstrumenter");
}
@Override

ADD
instrumentation/opentelemetry-api/opentelemetry-api-1.0/testing/src/main/java/AgentSpanTestingInstrumenter.java
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import io.opentelemetry.api.GlobalOpenTelemetry;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.SpanKind;
+import io.opentelemetry.context.Context;
+import io.opentelemetry.context.ContextKey;
+import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
+import io.opentelemetry.instrumentation.api.instrumenter.SpanKey;
+import java.lang.reflect.Field;
+
+public final class AgentSpanTestingInstrumenter {
+
+ private static final ContextKey<Request> REQUEST_CONTEXT_KEY =
+ ContextKey.named("test-request-key");
+
+ private static final Instrumenter<Request, Void> INSTRUMENTER =
+ Instrumenter.<Request, Void>builder(
+ GlobalOpenTelemetry.get(), "test", request -> request.name)
+ .addContextCustomizer(
+ (context, request, startAttributes) -> context.with(REQUEST_CONTEXT_KEY, request))
+ .newInstrumenter(request -> request.kind);
+
+ public static Context startServerSpan(String name) {
+ return start(name, SpanKind.SERVER);
+ }
+
+ public static Context startClientSpan(String name) {
+ return start(name, SpanKind.CLIENT);
+ }
+
+ public static Context startSpanWithAllKeys(String name) {
+ Context context = start(name, SpanKind.INTERNAL);
+ Span span = Span.fromContext(context);
+ for (SpanKey spanKey : SpanKeyAccess.getSpanKeys()) {
+ context = spanKey.storeInContext(context, span);
+ }
+ return context;
+ }
+
+ private static Context start(String name, SpanKind kind) {
+ return INSTRUMENTER.start(Context.current(), new Request(name, kind));
+ }
+
+ public static void end(Context context, Throwable error) {
+ INSTRUMENTER.end(context, context.get(REQUEST_CONTEXT_KEY), null, error);
+ }
+
+ private static final class Request {
+ private final String name;
+ private final SpanKind kind;
+
+ public Request(String name, SpanKind kind) {
+ this.name = name;
+ this.kind = kind;
+ }
+ }
+
+ private static final class SpanKeyAccess {
+
+ public static SpanKey[] getSpanKeys() {
+ return new SpanKey[] {
+ SpanKey.SERVER,
+ getSpanKeyByName("HTTP_CLIENT"),
+ getSpanKeyByName("RPC_CLIENT"),
+ getSpanKeyByName("DB_CLIENT"),
+ SpanKey.ALL_CLIENTS,
+ getSpanKeyByName("PRODUCER"),
+ getSpanKeyByName("CONSUMER_RECEIVE"),
+ getSpanKeyByName("CONSUMER_PROCESS")
+ };
+ }
+
+ private static SpanKey getSpanKeyByName(String name) {
+ try {
+ Field field = SpanKey.class.getDeclaredField(name);
+ field.setAccessible(true);
+ return (SpanKey) field.get(name);
+ } catch (NoSuchFieldException | IllegalAccessException exception) {
+ throw new IllegalStateException("Failed to find span key named " + name, exception);
+ }
+ }
+ }
+
+ private AgentSpanTestingInstrumenter() {}
+}

DELETE
instrumentation/opentelemetry-api/opentelemetry-api-1.0/testing/src/main/java/AgentSpanTestingTracer.java
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-import io.opentelemetry.api.GlobalOpenTelemetry;
-import io.opentelemetry.api.trace.Span;
-import io.opentelemetry.api.trace.SpanBuilder;
-import io.opentelemetry.api.trace.SpanKind;
-import io.opentelemetry.context.Context;
-import io.opentelemetry.instrumentation.api.instrumenter.SpanKey;
-import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
-import java.lang.reflect.Field;
-
-public class AgentSpanTestingTracer extends BaseTracer {
- private static final AgentSpanTestingTracer TRACER = new AgentSpanTestingTracer();
-
- private AgentSpanTestingTracer() {
- super(GlobalOpenTelemetry.get());
- }
-
- public static AgentSpanTestingTracer tracer() {
- return TRACER;
- }
-
- public Context startServerSpan(String name) {
- Context parentContext = Context.current();
- SpanBuilder spanBuilder = spanBuilder(parentContext, name, SpanKind.SERVER);
- return withServerSpan(parentContext, spanBuilder.startSpan());
- }
-
- public Context startConsumerSpan(String name) {
- Context parentContext = Context.current();
- SpanBuilder spanBuilder = spanBuilder(parentContext, name, SpanKind.CONSUMER);
- return withConsumerSpan(parentContext, spanBuilder.startSpan());
- }
-
- public Context startClientSpan(String name) {
- Context parentContext = Context.current();
- SpanBuilder spanBuilder = spanBuilder(parentContext, name, SpanKind.CLIENT);
- return withClientSpan(parentContext, spanBuilder.startSpan());
- }
-
- public Context startSpanWithAllKeys(String name) {
- Context parentContext = Context.current();
- SpanBuilder spanBuilder = spanBuilder(parentContext, name, SpanKind.INTERNAL);
- Span span = spanBuilder.startSpan();
- Context newContext = parentContext.with(span);
- for (SpanKey spanKey : SpanKeyAccess.getSpanKeys()) {
- newContext = spanKey.storeInContext(newContext, span);
- }
- return newContext;
- }
-
- @Override
- protected String getInstrumentationName() {
- return "agent-span-test-instrumentation";
- }
-
- private static class SpanKeyAccess {
-
- public static SpanKey[] getSpanKeys() {
- return new SpanKey[] {
- SpanKey.SERVER,
- getSpanKeyByName("HTTP_CLIENT"),
- getSpanKeyByName("RPC_CLIENT"),
- getSpanKeyByName("DB_CLIENT"),
- SpanKey.ALL_CLIENTS,
- getSpanKeyByName("PRODUCER"),
- getSpanKeyByName("CONSUMER_RECEIVE"),
- getSpanKeyByName("CONSUMER_PROCESS")
- };
- }
-
- private static SpanKey getSpanKeyByName(String name) {
- try {
- Field field = SpanKey.class.getDeclaredField(name);
- field.setAccessible(true);
- return (SpanKey) field.get(name);
- } catch (NoSuchFieldException | IllegalAccessException exception) {
- throw new IllegalStateException("Failed to find span key named " + name, exception);
- }
- }
- }
-}

Migrate opentelemetry-api testing module to Instrumenter API (#4580)