Convert tomcat 7 tests from groovy to java (#11402)
This commit is contained in:
parent
64bbbc801a
commit
b36d2845b3
|
@ -1,82 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright The OpenTelemetry Authors
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.tomcat.v7_0
|
|
||||||
|
|
||||||
import io.opentelemetry.instrumentation.test.base.HttpServerTest
|
|
||||||
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint
|
|
||||||
import javax.servlet.ServletException
|
|
||||||
import javax.servlet.annotation.WebServlet
|
|
||||||
import javax.servlet.http.HttpServlet
|
|
||||||
import javax.servlet.http.HttpServletRequest
|
|
||||||
import javax.servlet.http.HttpServletResponse
|
|
||||||
import java.util.concurrent.CountDownLatch
|
|
||||||
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_HEADERS
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.ERROR
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.EXCEPTION
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.INDEXED_CHILD
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.QUERY_PARAM
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS
|
|
||||||
|
|
||||||
@WebServlet(asyncSupported = true)
|
|
||||||
class AsyncServlet extends HttpServlet {
|
|
||||||
@Override
|
|
||||||
protected void service(HttpServletRequest req, HttpServletResponse resp) {
|
|
||||||
ServerEndpoint endpoint = ServerEndpoint.forPath(req.servletPath)
|
|
||||||
def latch = new CountDownLatch(1)
|
|
||||||
def context = req.startAsync()
|
|
||||||
if (endpoint == EXCEPTION) {
|
|
||||||
context.setTimeout(5000)
|
|
||||||
}
|
|
||||||
context.start {
|
|
||||||
try {
|
|
||||||
HttpServerTest.controller(endpoint) {
|
|
||||||
resp.contentType = "text/plain"
|
|
||||||
switch (endpoint) {
|
|
||||||
case SUCCESS:
|
|
||||||
resp.status = endpoint.status
|
|
||||||
resp.writer.print(endpoint.body)
|
|
||||||
break
|
|
||||||
case INDEXED_CHILD:
|
|
||||||
endpoint.collectSpanAttributes { req.getParameter(it) }
|
|
||||||
resp.status = endpoint.status
|
|
||||||
break
|
|
||||||
case QUERY_PARAM:
|
|
||||||
resp.status = endpoint.status
|
|
||||||
resp.writer.print(req.queryString)
|
|
||||||
break
|
|
||||||
case REDIRECT:
|
|
||||||
resp.sendRedirect(endpoint.body)
|
|
||||||
break
|
|
||||||
case CAPTURE_HEADERS:
|
|
||||||
resp.setHeader("X-Test-Response", req.getHeader("X-Test-Request"))
|
|
||||||
resp.status = endpoint.status
|
|
||||||
resp.writer.print(endpoint.body)
|
|
||||||
break
|
|
||||||
case ERROR:
|
|
||||||
resp.status = endpoint.status
|
|
||||||
resp.writer.print(endpoint.body)
|
|
||||||
break
|
|
||||||
case EXCEPTION:
|
|
||||||
resp.status = endpoint.status
|
|
||||||
def writer = resp.writer
|
|
||||||
writer.print(endpoint.body)
|
|
||||||
writer.close()
|
|
||||||
throw new ServletException(endpoint.body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
// complete at the end so the server span will end after the controller span
|
|
||||||
if (endpoint != EXCEPTION) {
|
|
||||||
context.complete()
|
|
||||||
}
|
|
||||||
latch.countDown()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
latch.await()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,90 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright The OpenTelemetry Authors
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.tomcat.v7_0
|
|
||||||
|
|
||||||
import io.opentelemetry.api.trace.SpanKind
|
|
||||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
|
||||||
import org.apache.tomcat.util.threads.TaskQueue
|
|
||||||
import org.apache.tomcat.util.threads.ThreadPoolExecutor
|
|
||||||
|
|
||||||
import java.util.concurrent.CountDownLatch
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
|
||||||
|
|
||||||
class ThreadPoolExecutorTest extends AgentInstrumentationSpecification {
|
|
||||||
|
|
||||||
// Test that PropagatedContext isn't cleared when ThreadPoolExecutor.execute fails with
|
|
||||||
// RejectedExecutionException
|
|
||||||
def "test tomcat thread pool"() {
|
|
||||||
setup:
|
|
||||||
def reject = new AtomicBoolean()
|
|
||||||
def queue = new TaskQueue() {
|
|
||||||
@Override
|
|
||||||
boolean offer(Runnable o) {
|
|
||||||
// TaskQueue.offer returns false when parent.getPoolSize() < parent.getMaximumPoolSize()
|
|
||||||
// here we simulate the same condition to trigger RejectedExecutionException handling in
|
|
||||||
// tomcat ThreadPoolExecutor
|
|
||||||
if (reject.get()) {
|
|
||||||
reject.set(false)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return super.offer(o)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
def pool = new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS, queue)
|
|
||||||
queue.setParent(pool)
|
|
||||||
|
|
||||||
CountDownLatch latch = new CountDownLatch(1)
|
|
||||||
|
|
||||||
runWithSpan("parent") {
|
|
||||||
pool.execute(new Runnable() {
|
|
||||||
@Override
|
|
||||||
void run() {
|
|
||||||
runWithSpan("child1") {
|
|
||||||
latch.await()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
reject.set(true)
|
|
||||||
pool.execute(new Runnable() {
|
|
||||||
@Override
|
|
||||||
void run() {
|
|
||||||
runWithSpan("child2") {
|
|
||||||
latch.await()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
latch.countDown()
|
|
||||||
|
|
||||||
expect:
|
|
||||||
assertTraces(1) {
|
|
||||||
trace(0, 3) {
|
|
||||||
span(0) {
|
|
||||||
name "parent"
|
|
||||||
kind SpanKind.INTERNAL
|
|
||||||
hasNoParent()
|
|
||||||
}
|
|
||||||
span(1) {
|
|
||||||
name "child1"
|
|
||||||
kind SpanKind.INTERNAL
|
|
||||||
childOf span(0)
|
|
||||||
}
|
|
||||||
span(2) {
|
|
||||||
name "child2"
|
|
||||||
kind SpanKind.INTERNAL
|
|
||||||
childOf span(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
pool.shutdown()
|
|
||||||
pool.awaitTermination(10, TimeUnit.SECONDS)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,143 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright The OpenTelemetry Authors
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.tomcat.v7_0
|
|
||||||
|
|
||||||
import io.opentelemetry.instrumentation.api.internal.HttpConstants
|
|
||||||
import io.opentelemetry.instrumentation.test.AgentTestTrait
|
|
||||||
import io.opentelemetry.instrumentation.test.asserts.TraceAssert
|
|
||||||
import io.opentelemetry.instrumentation.test.base.HttpServerTest
|
|
||||||
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint
|
|
||||||
import org.apache.catalina.Context
|
|
||||||
import org.apache.catalina.startup.Tomcat
|
|
||||||
import org.apache.tomcat.JarScanFilter
|
|
||||||
import org.apache.tomcat.JarScanType
|
|
||||||
import spock.lang.Unroll
|
|
||||||
|
|
||||||
import javax.servlet.Servlet
|
|
||||||
import javax.servlet.ServletException
|
|
||||||
import java.nio.file.Files
|
|
||||||
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.AUTH_REQUIRED
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_HEADERS
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.ERROR
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.EXCEPTION
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.INDEXED_CHILD
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.NOT_FOUND
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.QUERY_PARAM
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS
|
|
||||||
|
|
||||||
@Unroll
|
|
||||||
class TomcatAsyncTest extends HttpServerTest<Tomcat> implements AgentTestTrait {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Tomcat startServer(int port) {
|
|
||||||
def tomcatServer = new Tomcat()
|
|
||||||
|
|
||||||
def baseDir = Files.createTempDirectory("tomcat").toFile()
|
|
||||||
baseDir.deleteOnExit()
|
|
||||||
tomcatServer.setBaseDir(baseDir.getAbsolutePath())
|
|
||||||
|
|
||||||
tomcatServer.setPort(port)
|
|
||||||
tomcatServer.getConnector().enableLookups = true // get localhost instead of 127.0.0.1
|
|
||||||
|
|
||||||
File applicationDir = new File(baseDir, "/webapps/ROOT")
|
|
||||||
if (!applicationDir.exists()) {
|
|
||||||
applicationDir.mkdirs()
|
|
||||||
applicationDir.deleteOnExit()
|
|
||||||
}
|
|
||||||
Context servletContext = tomcatServer.addWebapp(contextPath, applicationDir.getAbsolutePath())
|
|
||||||
// Speed up startup by disabling jar scanning:
|
|
||||||
servletContext.getJarScanner().setJarScanFilter(new JarScanFilter() {
|
|
||||||
@Override
|
|
||||||
boolean check(JarScanType jarScanType, String jarName) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
setupServlets(servletContext)
|
|
||||||
|
|
||||||
tomcatServer.start()
|
|
||||||
|
|
||||||
return tomcatServer
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void stopServer(Tomcat server) {
|
|
||||||
server.stop()
|
|
||||||
server.destroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
String getContextPath() {
|
|
||||||
return "/tomcat-context"
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
String getMetricsInstrumentationName() {
|
|
||||||
// with async requests the span is started in one instrumentation (server instrumentation)
|
|
||||||
// but ended from another (servlet instrumentation)
|
|
||||||
"io.opentelemetry.servlet-3.0"
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setupServlets(Context context) {
|
|
||||||
def servlet = servlet()
|
|
||||||
|
|
||||||
addServlet(context, SUCCESS.path, servlet)
|
|
||||||
addServlet(context, QUERY_PARAM.path, servlet)
|
|
||||||
addServlet(context, ERROR.path, servlet)
|
|
||||||
addServlet(context, EXCEPTION.path, servlet)
|
|
||||||
addServlet(context, REDIRECT.path, servlet)
|
|
||||||
addServlet(context, AUTH_REQUIRED.path, servlet)
|
|
||||||
addServlet(context, CAPTURE_HEADERS.path, servlet)
|
|
||||||
addServlet(context, INDEXED_CHILD.path, servlet)
|
|
||||||
}
|
|
||||||
|
|
||||||
void addServlet(Context servletContext, String path, Class<Servlet> servlet) {
|
|
||||||
String name = UUID.randomUUID()
|
|
||||||
Tomcat.addServlet(servletContext, name, servlet.newInstance())
|
|
||||||
servletContext.addServletMappingDecoded(path, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
Class<Servlet> servlet() {
|
|
||||||
AsyncServlet
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
String expectedHttpRoute(ServerEndpoint endpoint, String method) {
|
|
||||||
if (method == HttpConstants._OTHER) {
|
|
||||||
return getContextPath() + endpoint.path
|
|
||||||
}
|
|
||||||
switch (endpoint) {
|
|
||||||
case NOT_FOUND:
|
|
||||||
return getContextPath() + "/*"
|
|
||||||
default:
|
|
||||||
return super.expectedHttpRoute(endpoint, method)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Throwable expectedException() {
|
|
||||||
new ServletException(EXCEPTION.body)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
boolean hasResponseSpan(ServerEndpoint endpoint) {
|
|
||||||
endpoint == NOT_FOUND || endpoint == REDIRECT
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void responseSpan(TraceAssert trace, int index, Object parent, String method, ServerEndpoint endpoint) {
|
|
||||||
switch (endpoint) {
|
|
||||||
case REDIRECT:
|
|
||||||
redirectSpan(trace, index, parent)
|
|
||||||
break
|
|
||||||
case NOT_FOUND:
|
|
||||||
sendErrorSpan(trace, index, parent)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,128 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright The OpenTelemetry Authors
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.tomcat.v7_0
|
|
||||||
|
|
||||||
import io.opentelemetry.instrumentation.api.internal.HttpConstants
|
|
||||||
import io.opentelemetry.instrumentation.test.AgentTestTrait
|
|
||||||
import io.opentelemetry.instrumentation.test.asserts.TraceAssert
|
|
||||||
import io.opentelemetry.instrumentation.test.base.HttpServerTest
|
|
||||||
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint
|
|
||||||
import org.apache.catalina.Context
|
|
||||||
import org.apache.catalina.connector.Request
|
|
||||||
import org.apache.catalina.connector.Response
|
|
||||||
import org.apache.catalina.core.StandardHost
|
|
||||||
import org.apache.catalina.startup.Tomcat
|
|
||||||
import org.apache.catalina.valves.ErrorReportValve
|
|
||||||
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.AUTH_ERROR
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.AUTH_REQUIRED
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_HEADERS
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_PARAMETERS
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.ERROR
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.EXCEPTION
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.INDEXED_CHILD
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.LOGIN
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.NOT_FOUND
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.PATH_PARAM
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.QUERY_PARAM
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT
|
|
||||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS
|
|
||||||
|
|
||||||
class TomcatHandlerTest extends HttpServerTest<Tomcat> implements AgentTestTrait {
|
|
||||||
|
|
||||||
private static final List<ServerEndpoint> serverEndpointsList = Arrays.asList(SUCCESS, REDIRECT, ERROR, EXCEPTION, NOT_FOUND, CAPTURE_HEADERS, CAPTURE_PARAMETERS, QUERY_PARAM, PATH_PARAM, AUTH_REQUIRED, LOGIN, AUTH_ERROR, INDEXED_CHILD)
|
|
||||||
|
|
||||||
def "Tomcat starts"() {
|
|
||||||
expect:
|
|
||||||
getServer() != null
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
String getContextPath() {
|
|
||||||
return "/app"
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
boolean hasResponseCustomizer(ServerEndpoint endpoint) {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
boolean testCapturedRequestParameters() {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
String expectedHttpRoute(ServerEndpoint endpoint, String method) {
|
|
||||||
if (method == HttpConstants._OTHER) {
|
|
||||||
return getContextPath() + endpoint.path
|
|
||||||
}
|
|
||||||
return super.expectedHttpRoute(endpoint, method)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Tomcat startServer(int port) {
|
|
||||||
Tomcat tomcat = new Tomcat()
|
|
||||||
tomcat.setBaseDir(File.createTempDir().absolutePath)
|
|
||||||
tomcat.setPort(port)
|
|
||||||
tomcat.getConnector()
|
|
||||||
|
|
||||||
Context ctx = tomcat.addContext(getContextPath(), new File(".").getAbsolutePath())
|
|
||||||
|
|
||||||
Tomcat.addServlet(ctx, "testServlet", new TestServlet())
|
|
||||||
|
|
||||||
// Mapping servlet to /* will result in all requests have a name of just a context.
|
|
||||||
serverEndpointsList.stream()
|
|
||||||
.filter { it != NOT_FOUND }
|
|
||||||
.forEach {
|
|
||||||
ctx.addServletMappingDecoded(it.path, "testServlet")
|
|
||||||
}
|
|
||||||
|
|
||||||
(tomcat.host as StandardHost).errorReportValveClass = ErrorHandlerValve.name
|
|
||||||
|
|
||||||
tomcat.start()
|
|
||||||
|
|
||||||
return tomcat
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void stopServer(Tomcat tomcat) {
|
|
||||||
tomcat.getServer().stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
boolean hasResponseSpan(ServerEndpoint endpoint) {
|
|
||||||
endpoint == REDIRECT || endpoint == ERROR || endpoint == NOT_FOUND
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void responseSpan(TraceAssert trace, int index, Object parent, String method, ServerEndpoint endpoint) {
|
|
||||||
switch (endpoint) {
|
|
||||||
case REDIRECT:
|
|
||||||
redirectSpan(trace, index, parent)
|
|
||||||
break
|
|
||||||
case ERROR:
|
|
||||||
case NOT_FOUND:
|
|
||||||
sendErrorSpan(trace, index, parent)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ErrorHandlerValve extends ErrorReportValve {
|
|
||||||
@Override
|
|
||||||
protected void report(Request request, Response response, Throwable t) {
|
|
||||||
if (response.getStatus() < 400 || response.getContentWritten() > 0 || !response.isError()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
response.writer.print(t ? t.cause.message : response.message)
|
|
||||||
} catch (IOException ignored) {
|
|
||||||
// Ignore exception when writing exception message to response fails on IO - same as is done
|
|
||||||
// by the superclass itself and by other built-in ErrorReportValve implementations.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.tomcat.v7_0;
|
||||||
|
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_HEADERS;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.ERROR;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.EXCEPTION;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.INDEXED_CHILD;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.QUERY_PARAM;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS;
|
||||||
|
|
||||||
|
import io.opentelemetry.instrumentation.test.base.HttpServerTest;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import javax.servlet.AsyncContext;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
@WebServlet(asyncSupported = true)
|
||||||
|
class AsyncServlet extends HttpServlet {
|
||||||
|
@Override
|
||||||
|
protected void service(HttpServletRequest req, HttpServletResponse resp) {
|
||||||
|
ServerEndpoint endpoint = ServerEndpoint.forPath(req.getServletPath());
|
||||||
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
AsyncContext context = req.startAsync();
|
||||||
|
if (endpoint == EXCEPTION) {
|
||||||
|
context.setTimeout(5000);
|
||||||
|
}
|
||||||
|
context.start(
|
||||||
|
() -> {
|
||||||
|
try {
|
||||||
|
HttpServerTest.controller(
|
||||||
|
endpoint,
|
||||||
|
() -> {
|
||||||
|
resp.setContentType("text/plain");
|
||||||
|
if (endpoint.equals(SUCCESS) || endpoint.equals(ERROR)) {
|
||||||
|
resp.setStatus(endpoint.getStatus());
|
||||||
|
resp.getWriter().print(endpoint.getBody());
|
||||||
|
} else if (endpoint.equals(INDEXED_CHILD)) {
|
||||||
|
endpoint.collectSpanAttributes(x -> req.getParameter(x));
|
||||||
|
resp.setStatus(endpoint.getStatus());
|
||||||
|
} else if (endpoint.equals(QUERY_PARAM)) {
|
||||||
|
resp.setStatus(endpoint.getStatus());
|
||||||
|
resp.getWriter().print(req.getQueryString());
|
||||||
|
} else if (endpoint.equals(REDIRECT)) {
|
||||||
|
resp.sendRedirect(endpoint.getBody());
|
||||||
|
} else if (endpoint.equals(CAPTURE_HEADERS)) {
|
||||||
|
resp.setHeader("X-Test-Response", req.getHeader("X-Test-Request"));
|
||||||
|
resp.setStatus(endpoint.getStatus());
|
||||||
|
resp.getWriter().print(endpoint.getBody());
|
||||||
|
} else if (endpoint.equals(EXCEPTION)) {
|
||||||
|
resp.setStatus(endpoint.getStatus());
|
||||||
|
PrintWriter writer = resp.getWriter();
|
||||||
|
writer.print(endpoint.getBody());
|
||||||
|
writer.close();
|
||||||
|
throw new ServletException(endpoint.getBody());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
// complete at the end so the server span will end after the controller span
|
||||||
|
if (endpoint != EXCEPTION) {
|
||||||
|
context.complete();
|
||||||
|
}
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
latch.await();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.tomcat.v7_0;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.apache.catalina.connector.Request;
|
||||||
|
import org.apache.catalina.connector.Response;
|
||||||
|
import org.apache.catalina.valves.ErrorReportValve;
|
||||||
|
|
||||||
|
class ErrorHandlerValve extends ErrorReportValve {
|
||||||
|
@Override
|
||||||
|
protected void report(Request request, Response response, Throwable t) {
|
||||||
|
if (response.getStatus() < 400 || response.getContentWritten() > 0 || !response.isError()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
response.getWriter().print(t != null ? t.getCause().getMessage() : response.getMessage());
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
// Ignore exception when writing exception message to response fails on IO - same as is done
|
||||||
|
// by the superclass itself and by other built-in ErrorReportValve implementations.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,7 +13,7 @@ import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
public class TestServlet extends HttpServlet {
|
class TestServlet extends HttpServlet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.tomcat.v7_0;
|
||||||
|
|
||||||
|
import io.opentelemetry.api.trace.SpanKind;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import org.apache.tomcat.util.threads.TaskQueue;
|
||||||
|
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
|
class ThreadPoolExecutorTest {
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
|
||||||
|
|
||||||
|
// Test that PropagatedContext isn't cleared when ThreadPoolExecutor.execute fails with
|
||||||
|
// RejectedExecutionException
|
||||||
|
@Test
|
||||||
|
void testTomcatThreadPool() throws InterruptedException {
|
||||||
|
AtomicBoolean reject = new AtomicBoolean();
|
||||||
|
TaskQueue queue =
|
||||||
|
new TaskQueue() {
|
||||||
|
@Override
|
||||||
|
public boolean offer(Runnable o) {
|
||||||
|
// TaskQueue.offer returns false when parent.getPoolSize() < parent.getMaximumPoolSize()
|
||||||
|
// here we simulate the same condition to trigger RejectedExecutionException handling in
|
||||||
|
// tomcat ThreadPoolExecutor
|
||||||
|
if (reject.get()) {
|
||||||
|
reject.set(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return super.offer(o);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS, queue);
|
||||||
|
queue.setParent(pool);
|
||||||
|
|
||||||
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
|
||||||
|
testing.runWithSpan(
|
||||||
|
"parent",
|
||||||
|
() -> {
|
||||||
|
pool.execute(
|
||||||
|
() -> {
|
||||||
|
try {
|
||||||
|
testing.runWithSpan("child1", () -> latch.await());
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
reject.set(true);
|
||||||
|
pool.execute(
|
||||||
|
() -> {
|
||||||
|
try {
|
||||||
|
testing.runWithSpan("child2", () -> latch.await());
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
latch.countDown();
|
||||||
|
|
||||||
|
testing.waitAndAssertTraces(
|
||||||
|
trace ->
|
||||||
|
trace.hasSpansSatisfyingExactly(
|
||||||
|
span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(),
|
||||||
|
span ->
|
||||||
|
span.hasName("child1").hasKind(SpanKind.INTERNAL).hasParent(trace.getSpan(0)),
|
||||||
|
span ->
|
||||||
|
span.hasName("child2").hasKind(SpanKind.INTERNAL).hasParent(trace.getSpan(0))));
|
||||||
|
|
||||||
|
pool.shutdown();
|
||||||
|
pool.awaitTermination(10, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.tomcat.v7_0;
|
||||||
|
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.AUTH_REQUIRED;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_HEADERS;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.ERROR;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.EXCEPTION;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.INDEXED_CHILD;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.NOT_FOUND;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.QUERY_PARAM;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import io.opentelemetry.api.common.Attributes;
|
||||||
|
import io.opentelemetry.api.trace.SpanKind;
|
||||||
|
import io.opentelemetry.instrumentation.api.internal.HttpConstants;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerTestOptions;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint;
|
||||||
|
import io.opentelemetry.sdk.testing.assertj.SpanDataAssert;
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.UUID;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import org.apache.catalina.Context;
|
||||||
|
import org.apache.catalina.LifecycleException;
|
||||||
|
import org.apache.catalina.startup.Tomcat;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
|
class TomcatAsyncTest extends AbstractHttpServerTest<Tomcat> {
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
static final InstrumentationExtension testing = HttpServerInstrumentationExtension.forAgent();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tomcat setupServer() throws Exception {
|
||||||
|
Tomcat tomcatServer = new Tomcat();
|
||||||
|
File baseDir = Files.createTempDirectory("tomcat").toFile();
|
||||||
|
baseDir.deleteOnExit();
|
||||||
|
tomcatServer.setBaseDir(baseDir.getAbsolutePath());
|
||||||
|
tomcatServer.setPort(port);
|
||||||
|
tomcatServer.getConnector().setEnableLookups(true); // get localhost instead of 127.0.0.1
|
||||||
|
|
||||||
|
File applicationDir = new File(baseDir, "/webapps/ROOT");
|
||||||
|
if (!applicationDir.exists()) {
|
||||||
|
applicationDir.mkdirs();
|
||||||
|
applicationDir.deleteOnExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
Context servletContext =
|
||||||
|
tomcatServer.addWebapp(getContextPath(), applicationDir.getAbsolutePath());
|
||||||
|
// Speed up startup by disabling jar scanning:
|
||||||
|
servletContext.getJarScanner().setJarScanFilter((jarScanType, jarName) -> false);
|
||||||
|
|
||||||
|
setupServlets(servletContext);
|
||||||
|
tomcatServer.start();
|
||||||
|
return tomcatServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setupServlets(Context context) throws Exception {
|
||||||
|
Class<AsyncServlet> servlet = AsyncServlet.class;
|
||||||
|
|
||||||
|
addServlet(context, SUCCESS.getPath(), servlet);
|
||||||
|
addServlet(context, QUERY_PARAM.getPath(), servlet);
|
||||||
|
addServlet(context, ERROR.getPath(), servlet);
|
||||||
|
addServlet(context, EXCEPTION.getPath(), servlet);
|
||||||
|
addServlet(context, REDIRECT.getPath(), servlet);
|
||||||
|
addServlet(context, AUTH_REQUIRED.getPath(), servlet);
|
||||||
|
addServlet(context, CAPTURE_HEADERS.getPath(), servlet);
|
||||||
|
addServlet(context, INDEXED_CHILD.getPath(), servlet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addServlet(Context servletContext, String path, Class<AsyncServlet> servlet)
|
||||||
|
throws Exception {
|
||||||
|
String name = UUID.randomUUID().toString();
|
||||||
|
Tomcat.addServlet(servletContext, name, servlet.getDeclaredConstructor().newInstance());
|
||||||
|
servletContext.addServletMappingDecoded(path, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopServer(Tomcat server) throws LifecycleException {
|
||||||
|
server.stop();
|
||||||
|
server.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpServerTestOptions options) {
|
||||||
|
options.setContextPath("/tomcat-context");
|
||||||
|
|
||||||
|
options.setExpectedHttpRoute(
|
||||||
|
(ServerEndpoint endpoint, String method) -> {
|
||||||
|
if (method.equals(HttpConstants._OTHER)) {
|
||||||
|
return getContextPath() + endpoint.getPath();
|
||||||
|
}
|
||||||
|
if (endpoint.equals(NOT_FOUND)) {
|
||||||
|
return getContextPath() + "/*";
|
||||||
|
}
|
||||||
|
return super.expectedHttpRoute(endpoint, method);
|
||||||
|
});
|
||||||
|
|
||||||
|
options.setExpectedException(new ServletException(EXCEPTION.getBody()));
|
||||||
|
|
||||||
|
options.setHasResponseSpan(endpoint -> endpoint == NOT_FOUND || endpoint == REDIRECT);
|
||||||
|
|
||||||
|
// with async requests the span is started in one instrumentation (server instrumentation)
|
||||||
|
// but ended from another (servlet instrumentation)
|
||||||
|
options.setMetricsInstrumentationName(() -> "io.opentelemetry.servlet-3.0");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SpanDataAssert assertResponseSpan(
|
||||||
|
SpanDataAssert span, String method, ServerEndpoint endpoint) {
|
||||||
|
if (endpoint.equals(REDIRECT)) {
|
||||||
|
span.satisfies(spanData -> assertThat(spanData.getName()).endsWith(".sendRedirect"));
|
||||||
|
} else if (endpoint.equals(NOT_FOUND)) {
|
||||||
|
span.satisfies(spanData -> assertThat(spanData.getName()).endsWith(".sendError"));
|
||||||
|
}
|
||||||
|
span.hasKind(SpanKind.INTERNAL).hasAttributesSatisfying(Attributes::isEmpty);
|
||||||
|
return span;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.tomcat.v7_0;
|
||||||
|
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.AUTH_ERROR;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.AUTH_REQUIRED;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_HEADERS;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_PARAMETERS;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.ERROR;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.EXCEPTION;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.INDEXED_CHILD;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.LOGIN;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.NOT_FOUND;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.PATH_PARAM;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.QUERY_PARAM;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS;
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import io.opentelemetry.api.common.Attributes;
|
||||||
|
import io.opentelemetry.api.trace.SpanKind;
|
||||||
|
import io.opentelemetry.instrumentation.api.internal.HttpConstants;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerTestOptions;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint;
|
||||||
|
import io.opentelemetry.sdk.testing.assertj.SpanDataAssert;
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.catalina.Context;
|
||||||
|
import org.apache.catalina.LifecycleException;
|
||||||
|
import org.apache.catalina.core.StandardHost;
|
||||||
|
import org.apache.catalina.startup.Tomcat;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
|
class TomcatHandlerTest extends AbstractHttpServerTest<Tomcat> {
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
static final InstrumentationExtension testing = HttpServerInstrumentationExtension.forAgent();
|
||||||
|
|
||||||
|
private static final List<ServerEndpoint> serverEndpointsList =
|
||||||
|
asList(
|
||||||
|
SUCCESS,
|
||||||
|
REDIRECT,
|
||||||
|
ERROR,
|
||||||
|
EXCEPTION,
|
||||||
|
NOT_FOUND,
|
||||||
|
CAPTURE_HEADERS,
|
||||||
|
CAPTURE_PARAMETERS,
|
||||||
|
QUERY_PARAM,
|
||||||
|
PATH_PARAM,
|
||||||
|
AUTH_REQUIRED,
|
||||||
|
LOGIN,
|
||||||
|
AUTH_ERROR,
|
||||||
|
INDEXED_CHILD);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tomcat setupServer() throws Exception {
|
||||||
|
Tomcat tomcatServer = new Tomcat();
|
||||||
|
File baseDir = Files.createTempDirectory("tomcat").toFile();
|
||||||
|
baseDir.deleteOnExit();
|
||||||
|
tomcatServer.setBaseDir(baseDir.getAbsolutePath());
|
||||||
|
tomcatServer.setPort(port);
|
||||||
|
tomcatServer.getConnector();
|
||||||
|
|
||||||
|
Context servletContext =
|
||||||
|
tomcatServer.addContext(getContextPath(), new File(".").getAbsolutePath());
|
||||||
|
|
||||||
|
Tomcat.addServlet(servletContext, "testServlet", new TestServlet());
|
||||||
|
|
||||||
|
// Mapping servlet to /* will result in all requests have a name of just a context.
|
||||||
|
serverEndpointsList.stream()
|
||||||
|
.filter(endpoint -> !endpoint.equals(NOT_FOUND))
|
||||||
|
.forEach(
|
||||||
|
endpoint -> servletContext.addServletMappingDecoded(endpoint.getPath(), "testServlet"));
|
||||||
|
|
||||||
|
StandardHost host = (StandardHost) tomcatServer.getHost();
|
||||||
|
host.setErrorReportValveClass(ErrorHandlerValve.class.getName());
|
||||||
|
|
||||||
|
tomcatServer.start();
|
||||||
|
return tomcatServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopServer(Tomcat server) throws LifecycleException {
|
||||||
|
server.stop();
|
||||||
|
server.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpServerTestOptions options) {
|
||||||
|
options.setContextPath("/app");
|
||||||
|
options.setHasResponseCustomizer(serverEndpoint -> true);
|
||||||
|
options.setTestCaptureRequestParameters(true);
|
||||||
|
options.setTestErrorBody(false);
|
||||||
|
|
||||||
|
options.setHasResponseSpan(
|
||||||
|
endpoint -> endpoint == REDIRECT || endpoint == ERROR || endpoint == NOT_FOUND);
|
||||||
|
|
||||||
|
options.setExpectedHttpRoute(
|
||||||
|
(ServerEndpoint endpoint, String method) -> {
|
||||||
|
if (method.equals(HttpConstants._OTHER)) {
|
||||||
|
return getContextPath() + endpoint.getPath();
|
||||||
|
}
|
||||||
|
return super.expectedHttpRoute(endpoint, method);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SpanDataAssert assertResponseSpan(
|
||||||
|
SpanDataAssert span, String method, ServerEndpoint endpoint) {
|
||||||
|
if (endpoint.equals(REDIRECT)) {
|
||||||
|
span.satisfies(spanData -> assertThat(spanData.getName()).endsWith(".sendRedirect"));
|
||||||
|
} else if (endpoint.equals(NOT_FOUND)) {
|
||||||
|
span.satisfies(spanData -> assertThat(spanData.getName()).endsWith(".sendError"));
|
||||||
|
}
|
||||||
|
span.hasKind(SpanKind.INTERNAL).hasAttributesSatisfying(Attributes::isEmpty);
|
||||||
|
return span;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue