Convert Jetty 8.0 groovy to java (#7975)
related to https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/7195
This commit is contained in:
parent
995baa8888
commit
468aa9e777
|
@ -29,3 +29,11 @@ dependencies {
|
||||||
latestDepTestLibrary("org.eclipse.jetty:jetty-server:10.+") // see jetty-11.0 module
|
latestDepTestLibrary("org.eclipse.jetty:jetty-server:10.+") // see jetty-11.0 module
|
||||||
latestDepTestLibrary("org.eclipse.jetty:jetty-servlet:10.+") // see jetty-11.0 module
|
latestDepTestLibrary("org.eclipse.jetty:jetty-servlet:10.+") // see jetty-11.0 module
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// jetty-server 10+ requires Java 11
|
||||||
|
val latestDepTest = findProperty("testLatestDeps") as Boolean
|
||||||
|
if (latestDepTest) {
|
||||||
|
otelJava {
|
||||||
|
minJavaVersionSupported.set(JavaVersion.VERSION_11)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,144 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright The OpenTelemetry Authors
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
import io.opentelemetry.api.common.AttributeKey
|
|
||||||
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 io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
|
||||||
import org.eclipse.jetty.server.Request
|
|
||||||
import org.eclipse.jetty.server.Response
|
|
||||||
import org.eclipse.jetty.server.Server
|
|
||||||
import org.eclipse.jetty.server.handler.AbstractHandler
|
|
||||||
import org.eclipse.jetty.server.handler.ErrorHandler
|
|
||||||
import spock.lang.Shared
|
|
||||||
|
|
||||||
import javax.servlet.DispatcherType
|
|
||||||
import javax.servlet.ServletException
|
|
||||||
import javax.servlet.http.HttpServletRequest
|
|
||||||
import javax.servlet.http.HttpServletResponse
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
class JettyHandlerTest extends HttpServerTest<Server> implements AgentTestTrait {
|
|
||||||
|
|
||||||
static ErrorHandler errorHandler = new ErrorHandler() {
|
|
||||||
@Override
|
|
||||||
protected void handleErrorPage(HttpServletRequest request, Writer writer, int code, String message) throws IOException {
|
|
||||||
Throwable th = (Throwable) request.getAttribute("javax.servlet.error.exception")
|
|
||||||
message = th ? th.message : message
|
|
||||||
if (message) {
|
|
||||||
writer.write(message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Shared
|
|
||||||
TestHandler testHandler = new TestHandler()
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Server startServer(int port) {
|
|
||||||
def server = new Server(port)
|
|
||||||
server.setHandler(handler())
|
|
||||||
server.addBean(errorHandler)
|
|
||||||
server.start()
|
|
||||||
return server
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractHandler handler() {
|
|
||||||
testHandler
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void stopServer(Server server) {
|
|
||||||
server.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Set<AttributeKey<?>> httpAttributes(ServerEndpoint endpoint) {
|
|
||||||
def attributes = super.httpAttributes(endpoint)
|
|
||||||
attributes.remove(SemanticAttributes.HTTP_ROUTE)
|
|
||||||
attributes
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
boolean hasResponseSpan(ServerEndpoint endpoint) {
|
|
||||||
endpoint == REDIRECT || endpoint == ERROR
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void responseSpan(TraceAssert trace, int index, Object parent, String method, ServerEndpoint endpoint) {
|
|
||||||
switch (endpoint) {
|
|
||||||
case REDIRECT:
|
|
||||||
redirectSpan(trace, index, parent)
|
|
||||||
break
|
|
||||||
case ERROR:
|
|
||||||
sendErrorSpan(trace, index, parent)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handleRequest(Request request, HttpServletResponse response) {
|
|
||||||
ServerEndpoint endpoint = ServerEndpoint.forPath(request.requestURI)
|
|
||||||
controller(endpoint) {
|
|
||||||
response.contentType = "text/plain"
|
|
||||||
switch (endpoint) {
|
|
||||||
case SUCCESS:
|
|
||||||
response.status = endpoint.status
|
|
||||||
response.writer.print(endpoint.body)
|
|
||||||
break
|
|
||||||
case QUERY_PARAM:
|
|
||||||
response.status = endpoint.status
|
|
||||||
response.writer.print(request.queryString)
|
|
||||||
break
|
|
||||||
case REDIRECT:
|
|
||||||
response.sendRedirect(endpoint.body)
|
|
||||||
break
|
|
||||||
case ERROR:
|
|
||||||
response.sendError(endpoint.status, endpoint.body)
|
|
||||||
break
|
|
||||||
case CAPTURE_HEADERS:
|
|
||||||
response.setHeader("X-Test-Response", request.getHeader("X-Test-Request"))
|
|
||||||
response.status = endpoint.status
|
|
||||||
response.writer.print(endpoint.body)
|
|
||||||
break
|
|
||||||
case EXCEPTION:
|
|
||||||
throw new Exception(endpoint.body)
|
|
||||||
case INDEXED_CHILD:
|
|
||||||
INDEXED_CHILD.collectSpanAttributes { name -> request.getParameter(name) }
|
|
||||||
response.status = endpoint.status
|
|
||||||
response.writer.print(endpoint.body)
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
response.status = NOT_FOUND.status
|
|
||||||
response.writer.print(NOT_FOUND.body)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class TestHandler extends AbstractHandler {
|
|
||||||
@Override
|
|
||||||
void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
|
||||||
//This line here is to verify that we don't break Jetty if it wants to cast to implementation class
|
|
||||||
//See https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/1096
|
|
||||||
Response jettyResponse = response as Response
|
|
||||||
if (baseRequest.dispatcherType != DispatcherType.ERROR) {
|
|
||||||
handleRequest(baseRequest, jettyResponse)
|
|
||||||
baseRequest.handled = true
|
|
||||||
} else {
|
|
||||||
errorHandler.handle(target, baseRequest, baseRequest, response)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,98 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright The OpenTelemetry Authors
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
import io.opentelemetry.api.trace.SpanKind
|
|
||||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
|
||||||
import org.eclipse.jetty.util.thread.QueuedThreadPool
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assumptions.assumeTrue
|
|
||||||
|
|
||||||
class QueuedThreadPoolTest extends AgentInstrumentationSpecification {
|
|
||||||
|
|
||||||
def "QueueThreadPool 'dispatch' propagates"() {
|
|
||||||
setup:
|
|
||||||
def pool = new QueuedThreadPool()
|
|
||||||
// run test only if QueuedThreadPool has dispatch method
|
|
||||||
// dispatch method was removed in jetty 9.1
|
|
||||||
assumeTrue(pool.metaClass.getMetaMethod("dispatch", Runnable) != null)
|
|
||||||
pool.start()
|
|
||||||
|
|
||||||
new Runnable() {
|
|
||||||
@Override
|
|
||||||
void run() {
|
|
||||||
runWithSpan("parent") {
|
|
||||||
// this child will have a span
|
|
||||||
def child1 = new JavaAsyncChild()
|
|
||||||
// this child won't
|
|
||||||
def child2 = new JavaAsyncChild(false, false)
|
|
||||||
pool.dispatch(child1)
|
|
||||||
pool.dispatch(child2)
|
|
||||||
child1.waitForCompletion()
|
|
||||||
child2.waitForCompletion()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.run()
|
|
||||||
|
|
||||||
expect:
|
|
||||||
assertTraces(1) {
|
|
||||||
trace(0, 2) {
|
|
||||||
span(0) {
|
|
||||||
name "parent"
|
|
||||||
kind SpanKind.INTERNAL
|
|
||||||
hasNoParent()
|
|
||||||
}
|
|
||||||
span(1) {
|
|
||||||
name "asyncChild"
|
|
||||||
kind SpanKind.INTERNAL
|
|
||||||
childOf span(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
pool.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
def "QueueThreadPool 'dispatch' propagates lambda"() {
|
|
||||||
setup:
|
|
||||||
def pool = new QueuedThreadPool()
|
|
||||||
// run test only if QueuedThreadPool has dispatch method
|
|
||||||
// dispatch method was removed in jetty 9.1
|
|
||||||
assumeTrue(pool.metaClass.getMetaMethod("dispatch", Runnable) != null)
|
|
||||||
pool.start()
|
|
||||||
|
|
||||||
JavaAsyncChild child = new JavaAsyncChild(true, true)
|
|
||||||
new Runnable() {
|
|
||||||
@Override
|
|
||||||
void run() {
|
|
||||||
runWithSpan("parent") {
|
|
||||||
pool.dispatch(JavaLambdaMaker.lambda(child))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.run()
|
|
||||||
// We block in child to make sure spans close in predictable order
|
|
||||||
child.unblock()
|
|
||||||
child.waitForCompletion()
|
|
||||||
|
|
||||||
expect:
|
|
||||||
assertTraces(1) {
|
|
||||||
trace(0, 2) {
|
|
||||||
span(0) {
|
|
||||||
name "parent"
|
|
||||||
kind SpanKind.INTERNAL
|
|
||||||
hasNoParent()
|
|
||||||
}
|
|
||||||
span(1) {
|
|
||||||
name "asyncChild"
|
|
||||||
kind SpanKind.INTERNAL
|
|
||||||
childOf span(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
pool.stop()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,6 +3,8 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.jetty.v8_0;
|
||||||
|
|
||||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||||
import io.opentelemetry.api.trace.Tracer;
|
import io.opentelemetry.api.trace.Tracer;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
|
@ -3,6 +3,8 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.jetty.v8_0;
|
||||||
|
|
||||||
public class JavaLambdaMaker {
|
public class JavaLambdaMaker {
|
||||||
|
|
||||||
@SuppressWarnings("FunctionalExpressionCanBeFolded")
|
@SuppressWarnings("FunctionalExpressionCanBeFolded")
|
|
@ -0,0 +1,175 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.jetty.v8_0;
|
||||||
|
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.http.HttpServerTestOptions.DEFAULT_HTTP_ATTRIBUTES;
|
||||||
|
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.REDIRECT;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import io.opentelemetry.api.common.Attributes;
|
||||||
|
import io.opentelemetry.api.trace.SpanKind;
|
||||||
|
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 io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.Collections;
|
||||||
|
import javax.servlet.DispatcherType;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.eclipse.jetty.server.Request;
|
||||||
|
import org.eclipse.jetty.server.Response;
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||||
|
import org.eclipse.jetty.server.handler.ErrorHandler;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
|
public class JettyHandlerTest extends AbstractHttpServerTest<Server> {
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
static final InstrumentationExtension testing = HttpServerInstrumentationExtension.forAgent();
|
||||||
|
|
||||||
|
private static final ErrorHandler errorHandler =
|
||||||
|
new ErrorHandler() {
|
||||||
|
@Override
|
||||||
|
protected void handleErrorPage(
|
||||||
|
HttpServletRequest request, Writer writer, int code, String message)
|
||||||
|
throws IOException {
|
||||||
|
Throwable th = (Throwable) request.getAttribute("javax.servlet.error.exception");
|
||||||
|
String errorMsg = th != null ? th.getMessage() : message;
|
||||||
|
if (errorMsg != null) {
|
||||||
|
writer.write(errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final TestHandler testHandler = new TestHandler();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Server setupServer() {
|
||||||
|
Server server = new Server(port);
|
||||||
|
server.setHandler(testHandler);
|
||||||
|
server.addBean(errorHandler);
|
||||||
|
try {
|
||||||
|
server.start();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void stopServer(Server server) {
|
||||||
|
try {
|
||||||
|
server.stop();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpServerTestOptions options) {
|
||||||
|
options.setHttpAttributes(
|
||||||
|
unused ->
|
||||||
|
Sets.difference(
|
||||||
|
DEFAULT_HTTP_ATTRIBUTES, Collections.singleton(SemanticAttributes.HTTP_ROUTE)));
|
||||||
|
options.setHasResponseSpan(endpoint -> endpoint == REDIRECT || endpoint == ERROR);
|
||||||
|
options.setExpectedException(new IllegalStateException(EXCEPTION.getBody()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SpanDataAssert assertResponseSpan(
|
||||||
|
SpanDataAssert span, String method, ServerEndpoint endpoint) {
|
||||||
|
if (endpoint == REDIRECT) {
|
||||||
|
span.satisfies(spanData -> assertThat(spanData.getName()).endsWith(".sendRedirect"));
|
||||||
|
} else if (endpoint == ERROR) {
|
||||||
|
span.satisfies(spanData -> assertThat(spanData.getName()).endsWith(".sendError"));
|
||||||
|
}
|
||||||
|
span.hasKind(SpanKind.INTERNAL).hasAttributesSatisfying(Attributes::isEmpty);
|
||||||
|
return span;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void handleRequest(Request request, HttpServletResponse response) {
|
||||||
|
ServerEndpoint endpoint = ServerEndpoint.forPath(request.getRequestURI());
|
||||||
|
controller(
|
||||||
|
endpoint,
|
||||||
|
() -> {
|
||||||
|
try {
|
||||||
|
return response(request, response, endpoint);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HttpServletResponse response(
|
||||||
|
Request request, HttpServletResponse response, ServerEndpoint endpoint) throws IOException {
|
||||||
|
response.setContentType("text/plain");
|
||||||
|
switch (endpoint) {
|
||||||
|
case SUCCESS:
|
||||||
|
response.setStatus(endpoint.getStatus());
|
||||||
|
response.getWriter().print(endpoint.getBody());
|
||||||
|
break;
|
||||||
|
case QUERY_PARAM:
|
||||||
|
response.setStatus(endpoint.getStatus());
|
||||||
|
response.getWriter().print(request.getQueryString());
|
||||||
|
break;
|
||||||
|
case REDIRECT:
|
||||||
|
response.sendRedirect(endpoint.getBody());
|
||||||
|
break;
|
||||||
|
case ERROR:
|
||||||
|
response.sendError(endpoint.getStatus(), endpoint.getBody());
|
||||||
|
break;
|
||||||
|
case CAPTURE_HEADERS:
|
||||||
|
response.setHeader("X-Test-Response", request.getHeader("X-Test-Request"));
|
||||||
|
response.setStatus(endpoint.getStatus());
|
||||||
|
response.getWriter().print(endpoint.getBody());
|
||||||
|
break;
|
||||||
|
case EXCEPTION:
|
||||||
|
throw new IllegalStateException(endpoint.getBody());
|
||||||
|
case INDEXED_CHILD:
|
||||||
|
INDEXED_CHILD.collectSpanAttributes(name -> request.getParameter(name));
|
||||||
|
response.setStatus(endpoint.getStatus());
|
||||||
|
response.getWriter().print(endpoint.getBody());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
response.setStatus(NOT_FOUND.getStatus());
|
||||||
|
response.getWriter().print(NOT_FOUND.getBody());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestHandler extends AbstractHandler {
|
||||||
|
@Override
|
||||||
|
public void handle(
|
||||||
|
String target,
|
||||||
|
Request baseRequest,
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response)
|
||||||
|
throws IOException, ServletException {
|
||||||
|
// This line here is to verify that we don't break Jetty if it wants to cast to implementation
|
||||||
|
// class
|
||||||
|
Response jettyResponse = (Response) response;
|
||||||
|
if (baseRequest.getDispatcherType() != DispatcherType.ERROR) {
|
||||||
|
handleRequest(baseRequest, jettyResponse);
|
||||||
|
baseRequest.setHandled(true);
|
||||||
|
} else {
|
||||||
|
errorHandler.handle(target, baseRequest, baseRequest, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.jetty.v8_0;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||||
|
|
||||||
|
import io.opentelemetry.api.trace.SpanKind;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
|
class QueuedThreadPoolTest {
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
private static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void dispatchPropagates() throws Exception {
|
||||||
|
QueuedThreadPool pool = new QueuedThreadPool();
|
||||||
|
// run test only if QueuedThreadPool has dispatch method
|
||||||
|
// dispatch method was removed in jetty 9.1
|
||||||
|
Method dispatch = null;
|
||||||
|
try {
|
||||||
|
dispatch = QueuedThreadPool.class.getMethod("dispatch", Runnable.class);
|
||||||
|
} catch (NoSuchMethodException ignore) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
assumeTrue(dispatch != null);
|
||||||
|
pool.start();
|
||||||
|
|
||||||
|
Method finalDispatch = dispatch;
|
||||||
|
testing.runWithSpan(
|
||||||
|
"parent",
|
||||||
|
() -> {
|
||||||
|
// this child will have a span
|
||||||
|
JavaAsyncChild child1 = new JavaAsyncChild();
|
||||||
|
// this child won't
|
||||||
|
JavaAsyncChild child2 = new JavaAsyncChild(false, false);
|
||||||
|
if (finalDispatch != null) {
|
||||||
|
finalDispatch.invoke(pool, child1);
|
||||||
|
finalDispatch.invoke(pool, child2);
|
||||||
|
child1.waitForCompletion();
|
||||||
|
child2.waitForCompletion();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
testing.waitAndAssertTraces(
|
||||||
|
trace ->
|
||||||
|
trace.hasSpansSatisfyingExactlyInAnyOrder(
|
||||||
|
span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(),
|
||||||
|
span ->
|
||||||
|
span.hasName("asyncChild")
|
||||||
|
.hasKind(SpanKind.INTERNAL)
|
||||||
|
.hasParent(trace.getSpan(0))));
|
||||||
|
|
||||||
|
pool.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void dispatchPropagatesLambda() throws Exception {
|
||||||
|
QueuedThreadPool pool = new QueuedThreadPool();
|
||||||
|
// run test only if QueuedThreadPool has dispatch method
|
||||||
|
// dispatch method was removed in jetty 9.1
|
||||||
|
Method dispatch = null;
|
||||||
|
try {
|
||||||
|
dispatch = QueuedThreadPool.class.getMethod("dispatch", Runnable.class);
|
||||||
|
} catch (NoSuchMethodException ignore) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
assumeTrue(dispatch != null);
|
||||||
|
pool.start();
|
||||||
|
|
||||||
|
JavaAsyncChild child = new JavaAsyncChild(true, true);
|
||||||
|
Method finalDispatch = dispatch;
|
||||||
|
testing.runWithSpan(
|
||||||
|
"parent",
|
||||||
|
() -> {
|
||||||
|
if (finalDispatch != null) {
|
||||||
|
finalDispatch.invoke(pool, JavaLambdaMaker.lambda(child));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// We block in child to make sure spans close in predictable order
|
||||||
|
child.unblock();
|
||||||
|
child.waitForCompletion();
|
||||||
|
|
||||||
|
testing.waitAndAssertTraces(
|
||||||
|
trace ->
|
||||||
|
trace.hasSpansSatisfyingExactlyInAnyOrder(
|
||||||
|
span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(),
|
||||||
|
span ->
|
||||||
|
span.hasName("asyncChild")
|
||||||
|
.hasKind(SpanKind.INTERNAL)
|
||||||
|
.hasParent(trace.getSpan(0))));
|
||||||
|
|
||||||
|
pool.stop();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue