import datadog.trace.agent.test.asserts.TraceAssert import datadog.trace.agent.test.base.HttpServerTest import datadog.trace.api.DDSpanTypes import datadog.trace.instrumentation.api.Tags import datadog.trace.instrumentation.servlet3.Servlet3Decorator import okhttp3.Request import org.apache.catalina.core.ApplicationFilterChain import javax.servlet.Servlet import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.AUTH_REQUIRED import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.ERROR import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.EXCEPTION import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.REDIRECT import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS abstract class AbstractServlet3Test extends HttpServerTest { @Override URI buildAddress() { return new URI("http://localhost:$port/$context/") } @Override Servlet3Decorator decorator() { return Servlet3Decorator.DECORATE } @Override String expectedOperationName() { return "servlet.request" } // FIXME: Add authentication tests back in... // @Shared // protected String user = "user" // @Shared // protected String pass = "password" abstract String getContext() Class servlet = servlet() abstract Class servlet() abstract void addServlet(CONTEXT context, String path, Class servlet) protected void setupServlets(CONTEXT context) { def servlet = servlet() addServlet(context, SUCCESS.path, servlet) addServlet(context, ERROR.path, servlet) addServlet(context, EXCEPTION.path, servlet) addServlet(context, REDIRECT.path, servlet) addServlet(context, AUTH_REQUIRED.path, servlet) } protected ServerEndpoint lastRequest @Override Request.Builder request(ServerEndpoint uri, String method, String body) { lastRequest = uri super.request(uri, method, body) } @Override void serverSpan(TraceAssert trace, int index, BigInteger traceID = null, BigInteger parentID = null, String method = "GET", ServerEndpoint endpoint = SUCCESS) { trace.span(index) { operationName expectedOperationName() spanType DDSpanTypes.HTTP_SERVER errored endpoint.errored if (parentID != null) { traceId traceID parentId parentID } else { parent() } tags { "$Tags.COMPONENT" serverDecorator.component() "$Tags.SPAN_KIND" Tags.SPAN_KIND_SERVER "$Tags.PEER_HOSTNAME" { it == "localhost" || it == "127.0.0.1" } "$Tags.PEER_HOST_IPV4" { it == null || it == "127.0.0.1" } // Optional "$Tags.PEER_PORT" Integer "$Tags.HTTP_URL" "${endpoint.resolve(address)}" "$Tags.HTTP_METHOD" method "$Tags.HTTP_STATUS" endpoint.status "servlet.context" "/$context" "servlet.path" { it == endpoint.path || it == "/dispatch$endpoint.path" } "span.origin.type" { it == servlet.name || it == ApplicationFilterChain.name } if (endpoint.errored) { "error.msg" { it == null || it == EXCEPTION.body } "error.type" { it == null || it == Exception.name } "error.stack" { it == null || it instanceof String } } defaultTags(true) } } } }