Handle vert.x sub routes (#11535)

This commit is contained in:
Lauri Tulmin 2024-06-06 19:30:25 +03:00 committed by GitHub
parent b0e364680d
commit 8ada04aab7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 29 additions and 9 deletions

View File

@ -25,7 +25,9 @@ public class VertxLatestWebServer extends AbstractVertxWebServer {
public void start(Promise<Void> startPromise) { public void start(Promise<Void> startPromise) {
int port = config().getInteger(CONFIG_HTTP_SERVER_PORT); int port = config().getInteger(CONFIG_HTTP_SERVER_PORT);
Router router = buildRouter(); Router router = buildRouter();
Router mainRouter = Router.router(vertx);
mainRouter.route("/vertx-app/*").subRouter(router);
vertx.createHttpServer().requestHandler(router).listen(port, it -> startPromise.complete()); vertx.createHttpServer().requestHandler(mainRouter).listen(port, it -> startPromise.complete());
} }
} }

View File

@ -5,8 +5,12 @@
package io.opentelemetry.javaagent.instrumentation.vertx; package io.opentelemetry.javaagent.instrumentation.vertx;
import static io.opentelemetry.context.ContextKey.named;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context; import io.opentelemetry.context.Context;
import io.opentelemetry.context.ContextKey;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.instrumenter.LocalRootSpan; import io.opentelemetry.instrumentation.api.instrumenter.LocalRootSpan;
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerRoute; import io.opentelemetry.instrumentation.api.semconv.http.HttpServerRoute;
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerRouteSource; import io.opentelemetry.instrumentation.api.semconv.http.HttpServerRouteSource;
@ -20,6 +24,8 @@ import java.util.concurrent.ExecutionException;
/** This is used to wrap Vert.x Handlers to provide nice user-friendly SERVER span names */ /** This is used to wrap Vert.x Handlers to provide nice user-friendly SERVER span names */
public final class RoutingContextHandlerWrapper implements Handler<RoutingContext> { public final class RoutingContextHandlerWrapper implements Handler<RoutingContext> {
private static final ContextKey<String> ROUTE_KEY = named("opentelemetry-vertx-route");
private final Handler<RoutingContext> handler; private final Handler<RoutingContext> handler;
public RoutingContextHandlerWrapper(Handler<RoutingContext> handler) { public RoutingContextHandlerWrapper(Handler<RoutingContext> handler) {
@ -29,13 +35,13 @@ public final class RoutingContextHandlerWrapper implements Handler<RoutingContex
@Override @Override
public void handle(RoutingContext context) { public void handle(RoutingContext context) {
Context otelContext = Context.current(); Context otelContext = Context.current();
HttpServerRoute.update( String route = getRoute(otelContext, context);
otelContext, if (route != null && route.endsWith("/")) {
HttpServerRouteSource.CONTROLLER, route = route.substring(0, route.length() - 1);
RoutingContextHandlerWrapper::getRoute, }
context); HttpServerRoute.update(otelContext, HttpServerRouteSource.NESTED_CONTROLLER, route);
try { try (Scope ignore = otelContext.with(ROUTE_KEY, route).makeCurrent()) {
handler.handle(context); handler.handle(context);
} catch (Throwable throwable) { } catch (Throwable throwable) {
Span serverSpan = LocalRootSpan.fromContextOrNull(otelContext); Span serverSpan = LocalRootSpan.fromContextOrNull(otelContext);
@ -47,7 +53,9 @@ public final class RoutingContextHandlerWrapper implements Handler<RoutingContex
} }
private static String getRoute(Context otelContext, RoutingContext routingContext) { private static String getRoute(Context otelContext, RoutingContext routingContext) {
return routingContext.currentRoute().getPath(); String route = routingContext.currentRoute().getPath();
String existingRoute = otelContext.get(ROUTE_KEY);
return existingRoute != null ? existingRoute + route : route;
} }
private static Throwable unwrapThrowable(Throwable throwable) { private static Throwable unwrapThrowable(Throwable throwable) {

View File

@ -25,10 +25,12 @@ public class VertxWebServer extends AbstractVertxWebServer {
public void start(Future<Void> startFuture) { public void start(Future<Void> startFuture) {
int port = config().getInteger(CONFIG_HTTP_SERVER_PORT); int port = config().getInteger(CONFIG_HTTP_SERVER_PORT);
Router router = buildRouter(); Router router = buildRouter();
Router mainRouter = Router.router(vertx);
mainRouter.mountSubRouter("/vertx-app", router);
vertx vertx
.createHttpServer() .createHttpServer()
.requestHandler(router::accept) .requestHandler(mainRouter::accept)
.listen(port, it -> startFuture.complete()); .listen(port, it -> startFuture.complete());
} }
} }

View File

@ -58,11 +58,19 @@ abstract class AbstractVertxHttpServerTest extends HttpServerTest<Vertx> impleme
return false return false
} }
@Override
String getContextPath() {
"/vertx-app"
}
@Override @Override
String expectedHttpRoute(ServerEndpoint endpoint, String method) { String expectedHttpRoute(ServerEndpoint endpoint, String method) {
if (method == HttpConstants._OTHER) { if (method == HttpConstants._OTHER) {
return getContextPath() + endpoint.path return getContextPath() + endpoint.path
} }
if (endpoint == ServerEndpoint.NOT_FOUND) {
return getContextPath()
}
return super.expectedHttpRoute(endpoint, method) return super.expectedHttpRoute(endpoint, method)
} }
} }