From 995baa8888883673c616298ae548320b8742d2d0 Mon Sep 17 00:00:00 2001 From: Helen <56097766+heyams@users.noreply.github.com> Date: Sat, 11 Mar 2023 01:23:37 -0800 Subject: [PATCH] Convert Jetty 11 groovy to java (#7976) related to https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/7195 --- .../jetty/v11_0/JettyHandlerTest.java | 175 ++++++++++++++++++ .../src/test/groovy/JettyHandlerTest.groovy | 143 -------------- 2 files changed, 175 insertions(+), 143 deletions(-) create mode 100644 instrumentation/jetty/jetty-11.0/javaagent/src/test/Java/io/opentelemetry/javaagent/instrumentation/jetty/v11_0/JettyHandlerTest.java delete mode 100644 instrumentation/jetty/jetty-11.0/javaagent/src/test/groovy/JettyHandlerTest.groovy diff --git a/instrumentation/jetty/jetty-11.0/javaagent/src/test/Java/io/opentelemetry/javaagent/instrumentation/jetty/v11_0/JettyHandlerTest.java b/instrumentation/jetty/jetty-11.0/javaagent/src/test/Java/io/opentelemetry/javaagent/instrumentation/jetty/v11_0/JettyHandlerTest.java new file mode 100644 index 000000000000..4ec07e39f3a5 --- /dev/null +++ b/instrumentation/jetty/jetty-11.0/javaagent/src/test/Java/io/opentelemetry/javaagent/instrumentation/jetty/v11_0/JettyHandlerTest.java @@ -0,0 +1,175 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.jetty.v11_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 jakarta.servlet.DispatcherType; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.Writer; +import java.util.Collections; +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 { + + @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("jakarta.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); + } + } + } +} diff --git a/instrumentation/jetty/jetty-11.0/javaagent/src/test/groovy/JettyHandlerTest.groovy b/instrumentation/jetty/jetty-11.0/javaagent/src/test/groovy/JettyHandlerTest.groovy deleted file mode 100644 index ef0e0f03b93f..000000000000 --- a/instrumentation/jetty/jetty-11.0/javaagent/src/test/groovy/JettyHandlerTest.groovy +++ /dev/null @@ -1,143 +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 jakarta.servlet.DispatcherType -import jakarta.servlet.ServletException -import jakarta.servlet.http.HttpServletRequest -import jakarta.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 spock.lang.Shared - -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 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("jakarta.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> 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, request, response) - } - } - } -}