From 17c7a5f8909d9640d4dd71341ccb7be6fa788890 Mon Sep 17 00:00:00 2001 From: Rohit Mohan Date: Thu, 30 Apr 2026 15:19:22 -0700 Subject: [PATCH 1/2] Fix Vert.x sub-router route attribute --- .../v3_0/RoutingContextHandlerWrapper.java | 4 ++++ .../vertx/web/v3_0/VertxWebServer.java | 2 ++ .../vertx/web/v3_0/Vertx41WebServer.java | 2 ++ .../vertx/web/v3_0/Vertx5WebServer.java | 2 ++ .../web/v3_0/AbstractVertxHttpServerTest.java | 21 +++++++++++++++++++ 5 files changed, 31 insertions(+) diff --git a/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/RoutingContextHandlerWrapper.java b/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/RoutingContextHandlerWrapper.java index 46c003387868..884c9cfc6136 100644 --- a/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/RoutingContextHandlerWrapper.java +++ b/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/RoutingContextHandlerWrapper.java @@ -51,6 +51,10 @@ public void handle(RoutingContext context) { private static String getRoute(Context otelContext, RoutingContext routingContext) { String route = routingContext.currentRoute().getPath(); + String mountPoint = routingContext.mountPoint(); + if (mountPoint != null) { + return mountPoint.endsWith("/") ? mountPoint + route.substring(1) : mountPoint + route; + } String existingRoute = RouteHolder.get(otelContext); return existingRoute != null ? existingRoute + route : route; } diff --git a/instrumentation/vertx/vertx-web-3.0/javaagent/src/version3Test/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/VertxWebServer.java b/instrumentation/vertx/vertx-web-3.0/javaagent/src/version3Test/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/VertxWebServer.java index 66f3984300b8..dad49b858b7e 100644 --- a/instrumentation/vertx/vertx-web-3.0/javaagent/src/version3Test/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/VertxWebServer.java +++ b/instrumentation/vertx/vertx-web-3.0/javaagent/src/version3Test/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/VertxWebServer.java @@ -25,6 +25,8 @@ void end(HttpServerResponse response, String message) { public void start(Future startFuture) { int port = config().getInteger(CONFIG_HTTP_SERVER_PORT); Router router = buildRouter(); + router.mountSubRouter("/child", buildRouter()); + Router mainRouter = Router.router(vertx); mainRouter.mountSubRouter("/vertx-app", router); diff --git a/instrumentation/vertx/vertx-web-3.0/javaagent/src/version41Test/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/Vertx41WebServer.java b/instrumentation/vertx/vertx-web-3.0/javaagent/src/version41Test/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/Vertx41WebServer.java index 74a3e2328335..02bdf847892f 100644 --- a/instrumentation/vertx/vertx-web-3.0/javaagent/src/version41Test/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/Vertx41WebServer.java +++ b/instrumentation/vertx/vertx-web-3.0/javaagent/src/version41Test/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/Vertx41WebServer.java @@ -25,6 +25,8 @@ void end(HttpServerResponse response, String message) { public void start(Promise startPromise) { int port = config().getInteger(CONFIG_HTTP_SERVER_PORT); Router router = buildRouter(); + router.route("/child/*").subRouter(buildRouter()); + Router mainRouter = Router.router(vertx); mainRouter.route("/vertx-app/*").subRouter(router); diff --git a/instrumentation/vertx/vertx-web-3.0/javaagent/src/version5Test/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/Vertx5WebServer.java b/instrumentation/vertx/vertx-web-3.0/javaagent/src/version5Test/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/Vertx5WebServer.java index 08f844ae2fd1..98dc0469fb75 100644 --- a/instrumentation/vertx/vertx-web-3.0/javaagent/src/version5Test/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/Vertx5WebServer.java +++ b/instrumentation/vertx/vertx-web-3.0/javaagent/src/version5Test/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/Vertx5WebServer.java @@ -25,6 +25,8 @@ void end(HttpServerResponse response, String message) { public void start(Promise startPromise) { int port = config().getInteger(CONFIG_HTTP_SERVER_PORT); Router router = buildRouter(); + router.route("/child/*").subRouter(buildRouter()); + Router mainRouter = Router.router(vertx); mainRouter.route("/vertx-app/*").subRouter(router); diff --git a/instrumentation/vertx/vertx-web-3.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/AbstractVertxHttpServerTest.java b/instrumentation/vertx/vertx-web-3.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/AbstractVertxHttpServerTest.java index 95185baef722..cf9165781052 100644 --- a/instrumentation/vertx/vertx-web-3.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/AbstractVertxHttpServerTest.java +++ b/instrumentation/vertx/vertx-web-3.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/AbstractVertxHttpServerTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.vertx.web.v3_0; import static java.util.concurrent.TimeUnit.SECONDS; +import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.instrumentation.api.internal.HttpConstants; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; @@ -13,6 +14,7 @@ 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.testing.internal.armeria.common.AggregatedHttpResponse; import io.vertx.core.AbstractVerticle; import io.vertx.core.DeploymentOptions; import io.vertx.core.Vertx; @@ -22,10 +24,14 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; abstract class AbstractVertxHttpServerTest extends AbstractHttpServerTest { + private static final ServerEndpoint SUB_ROUTER_PATH_PARAM = + new ServerEndpoint("SUB_ROUTER_PATH_PARAM", "child/path/123/param", 200, "123", false); + @RegisterExtension static final InstrumentationExtension testing = HttpServerInstrumentationExtension.forAgent(); @@ -45,10 +51,25 @@ protected void configure(HttpServerTestOptions options) { if (Objects.equals(endpoint, ServerEndpoint.NOT_FOUND)) { return getContextPath(); } + if (Objects.equals(endpoint, SUB_ROUTER_PATH_PARAM)) { + return getContextPath() + "/child/path/:id/param"; + } return super.expectedHttpRoute(endpoint, method); }); } + @Test + void subRouterRouteIncludesMountPath() { + String method = "GET"; + AggregatedHttpResponse response = + client.execute(request(SUB_ROUTER_PATH_PARAM, method)).aggregate().join(); + + assertThat(response.status().code()).isEqualTo(SUB_ROUTER_PATH_PARAM.getStatus()); + assertThat(response.contentUtf8()).isEqualTo(SUB_ROUTER_PATH_PARAM.getBody()); + + assertTheTraces(1, null, null, null, method, SUB_ROUTER_PATH_PARAM); + } + @Override protected Vertx setupServer() throws ExecutionException, InterruptedException, TimeoutException { Vertx server = From 8742f66a789aa592da716cbdd7a5abf9c7d4e995 Mon Sep 17 00:00:00 2001 From: Rohit Mohan Date: Thu, 30 Apr 2026 15:58:35 -0700 Subject: [PATCH 2/2] Handle pathless Vert.x sub-router routes --- .../vertx/web/v3_0/RoutingContextHandlerWrapper.java | 7 ++++++- .../vertx/web/v3_0/AbstractVertxWebServer.java | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/RoutingContextHandlerWrapper.java b/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/RoutingContextHandlerWrapper.java index 884c9cfc6136..9ae34081bde2 100644 --- a/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/RoutingContextHandlerWrapper.java +++ b/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/RoutingContextHandlerWrapper.java @@ -51,9 +51,14 @@ public void handle(RoutingContext context) { private static String getRoute(Context otelContext, RoutingContext routingContext) { String route = routingContext.currentRoute().getPath(); + if (route == null) { + return RouteHolder.get(otelContext); + } String mountPoint = routingContext.mountPoint(); if (mountPoint != null) { - return mountPoint.endsWith("/") ? mountPoint + route.substring(1) : mountPoint + route; + return mountPoint.endsWith("/") && route.startsWith("/") + ? mountPoint.substring(0, mountPoint.length() - 1) + route + : mountPoint + route; } String existingRoute = RouteHolder.get(otelContext); return existingRoute != null ? existingRoute + route : route; diff --git a/instrumentation/vertx/vertx-web-3.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/AbstractVertxWebServer.java b/instrumentation/vertx/vertx-web-3.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/AbstractVertxWebServer.java index b15f48259fae..24b7a8835bb4 100644 --- a/instrumentation/vertx/vertx-web-3.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/AbstractVertxWebServer.java +++ b/instrumentation/vertx/vertx-web-3.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/web/v3_0/AbstractVertxWebServer.java @@ -33,6 +33,7 @@ public abstract class AbstractVertxWebServer extends AbstractVerticle { Router buildRouter() { Router router = Router.router(vertx); + router.route().handler(RoutingContext::next); // verify that calling RoutingContext::next doesn't affect http.route router.route(SUCCESS.getPath()).handler(RoutingContext::next); //noinspection Convert2Lambda