diff --git a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/base/HttpServerTest.groovy b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/base/HttpServerTest.groovy index 44d1471771..a7b1cfbf67 100644 --- a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/base/HttpServerTest.groovy +++ b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/base/HttpServerTest.groovy @@ -8,11 +8,9 @@ import datadog.trace.agent.test.asserts.TraceAssert import datadog.trace.agent.test.utils.OkHttpUtils import datadog.trace.agent.test.utils.PortUtils import datadog.trace.api.DDSpanTypes -import datadog.trace.context.TraceScope import groovy.transform.stc.ClosureParams import groovy.transform.stc.SimpleType import io.opentracing.tag.Tags -import io.opentracing.util.GlobalTracer import okhttp3.HttpUrl import okhttp3.OkHttpClient import okhttp3.Request @@ -30,6 +28,8 @@ import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.REDIRE import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS import static datadog.trace.agent.test.utils.TraceUtils.basicSpan import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace +import static datadog.trace.instrumentation.api.AgentTracer.activeScope +import static datadog.trace.instrumentation.api.AgentTracer.activeSpan import static org.junit.Assume.assumeTrue @Unroll @@ -152,8 +152,8 @@ abstract class HttpServerTest ext } static T controller(ServerEndpoint endpoint, Closure closure) { - assert GlobalTracer.get().activeSpan() != null: "Controller should have a parent span." - assert ((TraceScope) GlobalTracer.get().scopeManager().active()).asyncPropagating: "Scope should be propagating async." + assert activeSpan() != null: "Controller should have a parent span." + assert activeScope().asyncPropagating: "Scope should be propagating async." if (endpoint == NOT_FOUND) { return closure() } diff --git a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/base/HttpServerTestAdvice.java b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/base/HttpServerTestAdvice.java index d6d2c22b75..3f5cff6c0e 100644 --- a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/base/HttpServerTestAdvice.java +++ b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/base/HttpServerTestAdvice.java @@ -1,11 +1,12 @@ package datadog.trace.agent.test.base; +import static datadog.trace.instrumentation.api.AgentTracer.activateSpan; +import static datadog.trace.instrumentation.api.AgentTracer.activeSpan; +import static datadog.trace.instrumentation.api.AgentTracer.startSpan; + import datadog.trace.api.DDTags; -import datadog.trace.context.TraceScope; -import io.opentracing.Scope; -import io.opentracing.Tracer; -import io.opentracing.noop.NoopScopeManager; -import io.opentracing.util.GlobalTracer; +import datadog.trace.instrumentation.api.AgentScope; +import datadog.trace.instrumentation.api.AgentSpan; import net.bytebuddy.asm.Advice; public abstract class HttpServerTestAdvice { @@ -16,28 +17,26 @@ public abstract class HttpServerTestAdvice { */ public static class ServerEntryAdvice { @Advice.OnMethodEnter - public static Scope methodEnter() { + public static AgentScope methodEnter() { if (!HttpServerTest.ENABLE_TEST_ADVICE.get()) { // Skip if not running the HttpServerTest. - return NoopScopeManager.NoopScope.INSTANCE; + return null; } - final Tracer tracer = GlobalTracer.get(); - if (tracer.activeSpan() != null) { - return NoopScopeManager.NoopScope.INSTANCE; + if (activeSpan() != null) { + return null; } else { - final Scope scope = - tracer - .buildSpan("TEST_SPAN") - .withTag(DDTags.RESOURCE_NAME, "ServerEntry") - .startActive(true); - ((TraceScope) scope).setAsyncPropagation(true); + final AgentSpan span = startSpan("TEST_SPAN").setTag(DDTags.RESOURCE_NAME, "ServerEntry"); + final AgentScope scope = activateSpan(span, true); + scope.setAsyncPropagation(true); return scope; } } @Advice.OnMethodExit(onThrowable = Throwable.class) - public static void methodExit(@Advice.Enter final Scope scope) { - scope.close(); + public static void methodExit(@Advice.Enter final AgentScope scope) { + if (scope != null) { + scope.close(); + } } } } diff --git a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextInjectionTestBase.groovy b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextInjectionTestBase.groovy index 1eee80b584..e29849c626 100644 --- a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextInjectionTestBase.groovy +++ b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextInjectionTestBase.groovy @@ -3,11 +3,14 @@ package datadog.trace.agent.test.log.injection import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.utils.ConfigUtils import datadog.trace.api.CorrelationIdentifier -import io.opentracing.Scope -import io.opentracing.util.GlobalTracer +import datadog.trace.instrumentation.api.AgentScope +import datadog.trace.instrumentation.api.AgentSpan import java.util.concurrent.atomic.AtomicReference +import static datadog.trace.instrumentation.api.AgentTracer.activateSpan +import static datadog.trace.instrumentation.api.AgentTracer.startSpan + /** * This class represents the standard test cases that new logging library integrations MUST * satisfy in order to support log injection. @@ -33,7 +36,8 @@ abstract class LogContextInjectionTestBase extends AgentTestRunner { def "Log context shows trace and span ids for active scope"() { when: put("foo", "bar") - Scope rootScope = GlobalTracer.get().buildSpan("root").startActive(true) + AgentSpan rootSpan = startSpan("root") + AgentScope rootScope = activateSpan(rootSpan, true) then: get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() @@ -41,7 +45,8 @@ abstract class LogContextInjectionTestBase extends AgentTestRunner { get("foo") == "bar" when: - Scope childScope = GlobalTracer.get().buildSpan("child").startActive(true) + AgentSpan childSpan = startSpan("child") + AgentScope childScope = activateSpan(childSpan, true) then: get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() @@ -85,7 +90,8 @@ abstract class LogContextInjectionTestBase extends AgentTestRunner { @Override void run() { // other trace in scope - final Scope thread2Scope = GlobalTracer.get().buildSpan("root2").startActive(true) + final AgentSpan thread2Span = startSpan("root2") + final AgentScope thread2Scope = activateSpan(thread2Span, true) try { thread2TraceId.set(get(CorrelationIdentifier.getTraceIdKey())) } finally { @@ -93,7 +99,8 @@ abstract class LogContextInjectionTestBase extends AgentTestRunner { } } } - final Scope mainScope = GlobalTracer.get().buildSpan("root").startActive(true) + final AgentSpan mainSpan = startSpan("root") + final AgentScope mainScope = activateSpan(mainSpan, true) thread1.start() thread2.start() final String mainThreadTraceId = get(CorrelationIdentifier.getTraceIdKey()) diff --git a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/server/http/TestHttpServer.groovy b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/server/http/TestHttpServer.groovy index f777af3b37..e13cedd666 100644 --- a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/server/http/TestHttpServer.groovy +++ b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/server/http/TestHttpServer.groovy @@ -2,11 +2,8 @@ package datadog.trace.agent.test.server.http import datadog.opentracing.DDSpan import datadog.trace.agent.test.asserts.ListWriterAssert -import io.opentracing.SpanContext -import io.opentracing.Tracer -import io.opentracing.propagation.Format +import datadog.trace.instrumentation.api.AgentSpan import io.opentracing.tag.Tags -import io.opentracing.util.GlobalTracer import org.eclipse.jetty.http.HttpMethods import org.eclipse.jetty.server.Handler import org.eclipse.jetty.server.Request @@ -19,6 +16,10 @@ import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse import java.util.concurrent.atomic.AtomicReference +import static datadog.trace.agent.test.server.http.HttpServletRequestExtractAdapter.GETTER +import static datadog.trace.instrumentation.api.AgentTracer.propagate +import static datadog.trace.instrumentation.api.AgentTracer.startSpan + class TestHttpServer implements AutoCloseable { static TestHttpServer httpServer(boolean start = true, @@ -38,8 +39,6 @@ class TestHttpServer implements AutoCloseable { private final Server internalServer private HandlersSpec handlers - public Tracer tracer = GlobalTracer.get() - private URI address private final AtomicReference last = new AtomicReference<>() @@ -233,15 +232,14 @@ class TestHttpServer implements AutoCloseable { isDDServer = Boolean.parseBoolean(request.getHeader("is-dd-server")) } if (isDDServer) { - final SpanContext extractedContext = - tracer.extract(Format.Builtin.HTTP_HEADERS, new HttpServletRequestExtractAdapter(req)) - def builder = tracer - .buildSpan("test-http-server") - .withTag(Tags.SPAN_KIND.key, Tags.SPAN_KIND_SERVER) + final AgentSpan.Context extractedContext = propagate().extract(req, GETTER) if (extractedContext != null) { - builder.asChildOf(extractedContext) + startSpan("test-http-server", extractedContext) + .setTag(Tags.SPAN_KIND.key, Tags.SPAN_KIND_SERVER).finish() + } else { + startSpan("test-http-server") + .setTag(Tags.SPAN_KIND.key, Tags.SPAN_KIND_SERVER).finish() } - builder.start().finish() } } diff --git a/dd-java-agent/testing/src/main/java/datadog/trace/agent/test/server/http/HttpServletRequestExtractAdapter.java b/dd-java-agent/testing/src/main/java/datadog/trace/agent/test/server/http/HttpServletRequestExtractAdapter.java index 7135d766d9..08761c21ba 100644 --- a/dd-java-agent/testing/src/main/java/datadog/trace/agent/test/server/http/HttpServletRequestExtractAdapter.java +++ b/dd-java-agent/testing/src/main/java/datadog/trace/agent/test/server/http/HttpServletRequestExtractAdapter.java @@ -1,14 +1,7 @@ package datadog.trace.agent.test.server.http; -import io.opentracing.propagation.TextMap; -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; +import datadog.trace.instrumentation.api.AgentPropagation; +import java.util.Collections; import javax.servlet.http.HttpServletRequest; /** @@ -17,80 +10,19 @@ import javax.servlet.http.HttpServletRequest; * @author Pavol Loffay */ // FIXME: This code is duplicated in several places. Extract to a common dependency. -public class HttpServletRequestExtractAdapter implements TextMap { +public class HttpServletRequestExtractAdapter + implements AgentPropagation.Getter { - private final Map> headers; + public static final HttpServletRequestExtractAdapter GETTER = + new HttpServletRequestExtractAdapter(); - public HttpServletRequestExtractAdapter(final HttpServletRequest httpServletRequest) { - headers = servletHeadersToMultiMap(httpServletRequest); + @Override + public Iterable keys(final HttpServletRequest carrier) { + return Collections.list(carrier.getHeaderNames()); } @Override - public Iterator> iterator() { - return new MultivaluedMapFlatIterator<>(headers.entrySet()); - } - - @Override - public void put(final String key, final String value) { - throw new UnsupportedOperationException("This class should be used only with Tracer.inject()!"); - } - - protected Map> servletHeadersToMultiMap( - final HttpServletRequest httpServletRequest) { - final Map> headersResult = new HashMap<>(); - - final Enumeration headerNamesIt = httpServletRequest.getHeaderNames(); - while (headerNamesIt.hasMoreElements()) { - final String headerName = headerNamesIt.nextElement().toString(); - - final Enumeration valuesIt = httpServletRequest.getHeaders(headerName); - final List valuesList = new ArrayList<>(1); - while (valuesIt.hasMoreElements()) { - valuesList.add(valuesIt.nextElement().toString()); - } - - headersResult.put(headerName, valuesList); - } - - return headersResult; - } - - public static final class MultivaluedMapFlatIterator implements Iterator> { - - private final Iterator>> mapIterator; - private Map.Entry> mapEntry; - private Iterator listIterator; - - public MultivaluedMapFlatIterator(final Set>> multiValuesEntrySet) { - mapIterator = multiValuesEntrySet.iterator(); - } - - @Override - public boolean hasNext() { - if (listIterator != null && listIterator.hasNext()) { - return true; - } - - return mapIterator.hasNext(); - } - - @Override - public Map.Entry next() { - if (mapEntry == null || (!listIterator.hasNext() && mapIterator.hasNext())) { - mapEntry = mapIterator.next(); - listIterator = mapEntry.getValue().iterator(); - } - - if (listIterator.hasNext()) { - return new AbstractMap.SimpleImmutableEntry<>(mapEntry.getKey(), listIterator.next()); - } else { - return new AbstractMap.SimpleImmutableEntry<>(mapEntry.getKey(), null); - } - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } + public String get(final HttpServletRequest carrier, final String key) { + return carrier.getHeader(key); } } diff --git a/dd-java-agent/testing/src/test/groovy/server/ServerTest.groovy b/dd-java-agent/testing/src/test/groovy/server/ServerTest.groovy index 32207c96e3..9761f01f6e 100644 --- a/dd-java-agent/testing/src/test/groovy/server/ServerTest.groovy +++ b/dd-java-agent/testing/src/test/groovy/server/ServerTest.groovy @@ -1,10 +1,9 @@ package server -import datadog.opentracing.DDTracer + import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.asserts.ListWriterAssert import datadog.trace.agent.test.utils.OkHttpUtils -import datadog.trace.common.writer.ListWriter import okhttp3.MultipartBody import okhttp3.Request import spock.lang.Shared @@ -300,8 +299,6 @@ class ServerTest extends AgentTestRunner { } } } - def writer = new ListWriter() - server.tracer = new DDTracer(writer) when: def request = new Request.Builder() @@ -315,7 +312,7 @@ class ServerTest extends AgentTestRunner { response.code() == 200 response.body().string().trim() == "done" - ListWriterAssert.assertTraces(writer, 1) { + ListWriterAssert.assertTraces(TEST_WRITER, 1) { server.distributedRequestTrace(it, 0) }