From 6107f1170af3875216a4cab96d2d7b8d787e40e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Vandon?= Date: Thu, 16 Apr 2026 14:21:07 +0200 Subject: [PATCH 1/5] wip --- .../vertx_3_4/server/EndHandlerWrapper.java | 18 +++ .../vertx_3_4/server/RouteHandlerWrapper.java | 44 ++++++- .../server/RouteImplInstrumentation.java | 12 +- .../vertx_3_4/server/RouteMatchesAdvice.java | 39 ++++++ .../server/RouteHandlerWrapperTest.groovy | 45 +++++++ .../vertx_4_0/server/EndHandlerWrapper.java | 19 +++ .../vertx_4_0/server/RouteHandlerWrapper.java | 44 ++++++- .../server/RouteImplInstrumentation.java | 12 +- .../vertx_4_0/server/RouteMatchesAdvice.java | 41 ++++++ .../server/RouteHandlerWrapperTest.groovy | 45 +++++++ .../application/.gitignore | 6 + .../application/build.gradle | 32 +++++ .../application/settings.gradle | 34 +++++ .../smoketest/springboot/AppInitializer.java | 22 ++++ .../springboot/SpringbootApplication.java | 14 ++ .../controller/FruitController.java | 33 +++++ .../smoketest/springboot/model/Fruit.java | 58 +++++++++ .../repository/FruitRepository.java | 12 ++ .../src/main/resources/application.properties | 16 +++ .../build.gradle | 121 ++++++++++++++++++ ...SpringBoot35UndertowIntegrationTest.groovy | 105 +++++++++++++++ .../datadog/smoketest/ProcessManager.groovy | 5 +- settings.gradle.kts | 1 + 23 files changed, 749 insertions(+), 29 deletions(-) create mode 100644 dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapperTest.groovy create mode 100644 dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapperTest.groovy create mode 100644 dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/.gitignore create mode 100644 dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/build.gradle create mode 100644 dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/settings.gradle create mode 100644 dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/AppInitializer.java create mode 100644 dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/SpringbootApplication.java create mode 100644 dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/controller/FruitController.java create mode 100644 dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/model/Fruit.java create mode 100644 dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/repository/FruitRepository.java create mode 100644 dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/resources/application.properties create mode 100644 dd-smoke-tests/spring-boot-3.5-webmvc-undertow/build.gradle create mode 100644 dd-smoke-tests/spring-boot-3.5-webmvc-undertow/src/test/groovy/SpringBoot35UndertowIntegrationTest.groovy diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/EndHandlerWrapper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/EndHandlerWrapper.java index a8cb1ebb079..56300b14780 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/EndHandlerWrapper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/EndHandlerWrapper.java @@ -1,6 +1,8 @@ package datadog.trace.instrumentation.vertx_3_4.server; import static datadog.trace.instrumentation.vertx_3_4.server.RouteHandlerWrapper.HANDLER_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_3_4.server.RouteHandlerWrapper.PARENT_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_3_4.server.RouteHandlerWrapper.updateRoute; import static datadog.trace.instrumentation.vertx_3_4.server.VertxDecorator.DECORATE; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; @@ -19,11 +21,27 @@ public class EndHandlerWrapper implements Handler { @Override public void handle(final Void event) { AgentSpan span = routingContext.get(HANDLER_SPAN_CONTEXT_KEY); + AgentSpan parentSpan = routingContext.get(PARENT_SPAN_CONTEXT_KEY); try { if (actual != null) { actual.handle(event); } } finally { + if (routingContext.currentRoute() != null) { + final String method = routingContext.request().rawMethod(); + String path = routingContext.currentRoute().getPath(); + String mountPoint = routingContext.mountPoint(); + if (mountPoint != null && !mountPoint.isEmpty()) { + if (mountPoint.charAt(mountPoint.length() - 1) == '/' + && path != null + && !path.isEmpty() + && path.charAt(0) == '/') { + mountPoint = mountPoint.substring(0, mountPoint.length() - 1); + } + path = mountPoint + path; + } + updateRoute(routingContext, method, path, parentSpan, span); + } if (span != null) { DECORATE.onResponse(span, routingContext.response()); span.finish(); diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapper.java index 1c0d35a0191..dced46ca892 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapper.java @@ -10,6 +10,7 @@ import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.api.ResourceNamePriorities; import datadog.trace.bootstrap.instrumentation.api.Tags; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; @@ -65,7 +66,8 @@ public void handle(final RoutingContext routingContext) { private void setRoute(RoutingContext routingContext) { final AgentSpan parentSpan = routingContext.get(PARENT_SPAN_CONTEXT_KEY); - if (parentSpan == null) { + final AgentSpan handlerSpan = routingContext.get(HANDLER_SPAN_CONTEXT_KEY); + if (parentSpan == null && handlerSpan == null) { return; } @@ -81,15 +83,38 @@ private void setRoute(RoutingContext routingContext) { } path = mountPoint + path; } - if (method != null && path != null && shouldUpdateRoute(routingContext, parentSpan, path)) { - routingContext.put(ROUTE_CONTEXT_KEY, path); + updateRoute(routingContext, method, path, parentSpan, handlerSpan); + } + + static void updateRoute( + final RoutingContext routingContext, + final String method, + final String path, + final AgentSpan parentSpan, + final AgentSpan handlerSpan) { + if (method == null || path == null) { + return; + } + if (!shouldUpdateRoute(routingContext, parentSpan, handlerSpan, path)) { + return; + } + + routingContext.put(ROUTE_CONTEXT_KEY, path); + if (parentSpan != null) { HTTP_RESOURCE_DECORATOR.withRoute(parentSpan, method, path, true); } + if (handlerSpan != null + && handlerSpan.getResourceNamePriority() < ResourceNamePriorities.HTTP_FRAMEWORK_ROUTE) { + HTTP_RESOURCE_DECORATOR.withRoute(handlerSpan, method, path, true); + } } static boolean shouldUpdateRoute( - final RoutingContext routingContext, final AgentSpan span, final String path) { - if (span == null) { + final RoutingContext routingContext, + final AgentSpan parentSpan, + final AgentSpan handlerSpan, + final String path) { + if (parentSpan == null && handlerSpan == null) { return false; } final String currentRoute = routingContext.get(ROUTE_CONTEXT_KEY); @@ -97,6 +122,13 @@ static boolean shouldUpdateRoute( return false; } // do not override route with a "/" if it's already set (it's probably more meaningful) - return !path.equals("/") || span.getTag(Tags.HTTP_ROUTE) == null; + if (!path.equals("/")) { + return true; + } + return !hasHttpRoute(parentSpan) && !hasHttpRoute(handlerSpan); + } + + private static boolean hasHttpRoute(final AgentSpan span) { + return span != null && span.getTag(Tags.HTTP_ROUTE) != null; } } diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteImplInstrumentation.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteImplInstrumentation.java index 4de2a5d6995..000afeffdd5 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteImplInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteImplInstrumentation.java @@ -20,8 +20,6 @@ public class RouteImplInstrumentation extends InstrumenterModule implements Instrumenter.ForKnownTypes, Instrumenter.HasMethodAdvice { - private Advice.PostProcessor.Factory postProcessorFactory; - public RouteImplInstrumentation() { super("vertx", "vertx-3.4"); } @@ -33,11 +31,9 @@ public Reference[] additionalMuzzleReferences() { @Override public boolean isApplicable(Set enabledSystems) { - if (enabledSystems.contains(TargetSystem.IAST)) { - postProcessorFactory = IastPostProcessorFactory.INSTANCE; - return true; - } - return enabledSystems.contains(TargetSystem.APPSEC); + return enabledSystems.contains(TargetSystem.TRACING) + || enabledSystems.contains(TargetSystem.APPSEC) + || enabledSystems.contains(TargetSystem.IAST); } @Override @@ -82,6 +78,6 @@ public void methodAdvice(MethodTransformer transformer) { @Override public Advice.PostProcessor.Factory postProcessor() { - return postProcessorFactory; + return IastPostProcessorFactory.INSTANCE; } } diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteMatchesAdvice.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteMatchesAdvice.java index 7aec8ec2487..95d149e5a68 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteMatchesAdvice.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteMatchesAdvice.java @@ -1,7 +1,12 @@ package datadog.trace.instrumentation.vertx_3_4.server; +import static datadog.trace.instrumentation.vertx_3_4.server.RouteHandlerWrapper.HANDLER_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_3_4.server.RouteHandlerWrapper.PARENT_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_3_4.server.RouteHandlerWrapper.updateRoute; + import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import io.vertx.ext.web.RoutingContext; import java.util.Map; import net.bytebuddy.asm.Advice; @@ -16,6 +21,23 @@ static void after( if (ret != 0 || t != null) { return; } + final AgentSpan parentSpan = ctx.get(PARENT_SPAN_CONTEXT_KEY); + final AgentSpan handlerSpan = ctx.get(HANDLER_SPAN_CONTEXT_KEY); + if (ctx.currentRoute() != null) { + final String method = ctx.request().rawMethod(); + String path = ctx.currentRoute().getPath(); + String mountPoint = ctx.mountPoint(); + if (mountPoint != null && !mountPoint.isEmpty()) { + if (mountPoint.charAt(mountPoint.length() - 1) == '/' + && path != null + && !path.isEmpty() + && path.charAt(0) == '/') { + mountPoint = mountPoint.substring(0, mountPoint.length() - 1); + } + path = mountPoint + path; + } + updateRoute(ctx, method, path, parentSpan, handlerSpan); + } Map params = ctx.pathParams(); if (params.isEmpty()) { return; @@ -35,6 +57,23 @@ static void after( if (!ret || t != null) { return; } + final AgentSpan parentSpan = ctx.get(PARENT_SPAN_CONTEXT_KEY); + final AgentSpan handlerSpan = ctx.get(HANDLER_SPAN_CONTEXT_KEY); + if (ctx.currentRoute() != null) { + final String method = ctx.request().rawMethod(); + String path = ctx.currentRoute().getPath(); + String mountPoint = ctx.mountPoint(); + if (mountPoint != null && !mountPoint.isEmpty()) { + if (mountPoint.charAt(mountPoint.length() - 1) == '/' + && path != null + && !path.isEmpty() + && path.charAt(0) == '/') { + mountPoint = mountPoint.substring(0, mountPoint.length() - 1); + } + path = mountPoint + path; + } + updateRoute(ctx, method, path, parentSpan, handlerSpan); + } Map params = ctx.pathParams(); if (params.isEmpty()) { return; diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapperTest.groovy b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapperTest.groovy new file mode 100644 index 00000000000..81e72cfa44b --- /dev/null +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapperTest.groovy @@ -0,0 +1,45 @@ +package datadog.trace.instrumentation.vertx_3_4.server + +import datadog.trace.agent.test.InstrumentationSpecification +import datadog.trace.bootstrap.instrumentation.api.AgentSpan +import datadog.trace.bootstrap.instrumentation.api.Tags +import io.vertx.ext.web.RoutingContext + +class RouteHandlerWrapperTest extends InstrumentationSpecification { + + void "updateRoute writes route to both spans"() { + given: + def context = Mock(RoutingContext) + def parentSpan = Mock(AgentSpan) + def handlerSpan = Mock(AgentSpan) + + when: + RouteHandlerWrapper.updateRoute(context, "GET", "/items/:id", parentSpan, handlerSpan) + + then: + 1 * context.get("dd.${Tags.HTTP_ROUTE}") >> null + 1 * context.put("dd.${Tags.HTTP_ROUTE}", "/items/:id") + 1 * parentSpan.setTag(Tags.HTTP_ROUTE, "/items/:id") + 1 * handlerSpan.getResourceNamePriority() >> Byte.MIN_VALUE + 1 * handlerSpan.setTag(Tags.HTTP_ROUTE, "/items/:id") + 0 * _ + } + + void "updateRoute does not replace root route when one exists"() { + given: + def context = Mock(RoutingContext) + def parentSpan = Mock(AgentSpan) + def handlerSpan = Mock(AgentSpan) + + when: + RouteHandlerWrapper.updateRoute(context, "GET", "/", parentSpan, handlerSpan) + + then: + 1 * context.get("dd.${Tags.HTTP_ROUTE}") >> null + 1 * parentSpan.getTag(Tags.HTTP_ROUTE) >> "/existing" + 1 * handlerSpan.getTag(Tags.HTTP_ROUTE) >> "/existing" + 0 * context.put(_, _) + 0 * parentSpan.setTag(_, _) + 0 * handlerSpan.setTag(_, _) + } +} diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/EndHandlerWrapper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/EndHandlerWrapper.java index a71584b11a7..4ce8cbab00a 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/EndHandlerWrapper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/EndHandlerWrapper.java @@ -1,6 +1,8 @@ package datadog.trace.instrumentation.vertx_4_0.server; import static datadog.trace.instrumentation.vertx_4_0.server.RouteHandlerWrapper.HANDLER_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_4_0.server.RouteHandlerWrapper.PARENT_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_4_0.server.RouteHandlerWrapper.updateRoute; import static datadog.trace.instrumentation.vertx_4_0.server.VertxDecorator.DECORATE; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; @@ -19,11 +21,28 @@ public class EndHandlerWrapper implements Handler { @Override public void handle(final Void event) { AgentSpan span = routingContext.get(HANDLER_SPAN_CONTEXT_KEY); + AgentSpan parentSpan = routingContext.get(PARENT_SPAN_CONTEXT_KEY); try { if (actual != null) { actual.handle(event); } } finally { + if (routingContext.currentRoute() != null) { + final String method = routingContext.request().method().name(); + String path = routingContext.currentRoute().getPath(); + if (path == null) { + path = routingContext.currentRoute().getName(); + } + final String mountPoint = routingContext.mountPoint(); + if (mountPoint != null && path != null) { + final String noBackslashhMountPoint = + mountPoint.endsWith("/") + ? mountPoint.substring(0, mountPoint.lastIndexOf("/")) + : mountPoint; + path = noBackslashhMountPoint + path; + } + updateRoute(routingContext, method, path, parentSpan, span); + } if (span != null) { DECORATE.onResponse(span, routingContext.response()); span.finish(); diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapper.java index a996806a1a8..83e78f70dbe 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapper.java @@ -10,6 +10,7 @@ import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.api.ResourceNamePriorities; import datadog.trace.bootstrap.instrumentation.api.Tags; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; @@ -62,7 +63,8 @@ public void handle(final RoutingContext routingContext) { private void setRoute(RoutingContext routingContext) { final AgentSpan parentSpan = routingContext.get(PARENT_SPAN_CONTEXT_KEY); - if (parentSpan == null) { + final AgentSpan handlerSpan = routingContext.get(HANDLER_SPAN_CONTEXT_KEY); + if (parentSpan == null && handlerSpan == null) { return; } @@ -82,15 +84,38 @@ private void setRoute(RoutingContext routingContext) { : mountPoint; path = noBackslashhMountPoint + path; } - if (method != null && path != null && shouldUpdateRoute(routingContext, parentSpan, path)) { - routingContext.put(ROUTE_CONTEXT_KEY, path); + updateRoute(routingContext, method, path, parentSpan, handlerSpan); + } + + static void updateRoute( + final RoutingContext routingContext, + final String method, + final String path, + final AgentSpan parentSpan, + final AgentSpan handlerSpan) { + if (method == null || path == null) { + return; + } + if (!shouldUpdateRoute(routingContext, parentSpan, handlerSpan, path)) { + return; + } + + routingContext.put(ROUTE_CONTEXT_KEY, path); + if (parentSpan != null) { HTTP_RESOURCE_DECORATOR.withRoute(parentSpan, method, path, true); } + if (handlerSpan != null + && handlerSpan.getResourceNamePriority() < ResourceNamePriorities.HTTP_FRAMEWORK_ROUTE) { + HTTP_RESOURCE_DECORATOR.withRoute(handlerSpan, method, path, true); + } } static boolean shouldUpdateRoute( - final RoutingContext routingContext, final AgentSpan span, final String path) { - if (span == null) { + final RoutingContext routingContext, + final AgentSpan parentSpan, + final AgentSpan handlerSpan, + final String path) { + if (parentSpan == null && handlerSpan == null) { return false; } final String currentRoute = routingContext.get(ROUTE_CONTEXT_KEY); @@ -98,6 +123,13 @@ static boolean shouldUpdateRoute( return false; } // do not override route with a "/" if it's already set (it's probably more meaningful) - return !path.equals("/") || span.getTag(Tags.HTTP_ROUTE) == null; + if (!path.equals("/")) { + return true; + } + return !hasHttpRoute(parentSpan) && !hasHttpRoute(handlerSpan); + } + + private static boolean hasHttpRoute(final AgentSpan span) { + return span != null && span.getTag(Tags.HTTP_ROUTE) != null; } } diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteImplInstrumentation.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteImplInstrumentation.java index a2041f43264..bf63ffc0a10 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteImplInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteImplInstrumentation.java @@ -18,8 +18,6 @@ public class RouteImplInstrumentation extends InstrumenterModule implements Instrumenter.ForKnownTypes, Instrumenter.HasMethodAdvice { - private Advice.PostProcessor.Factory postProcessorFactory; - public RouteImplInstrumentation() { super("vertx", "vertx-4.0"); } @@ -31,11 +29,9 @@ public Reference[] additionalMuzzleReferences() { @Override public boolean isApplicable(Set enabledSystems) { - if (enabledSystems.contains(TargetSystem.IAST)) { - postProcessorFactory = IastPostProcessorFactory.INSTANCE; - return true; - } - return enabledSystems.contains(TargetSystem.APPSEC); + return enabledSystems.contains(TargetSystem.TRACING) + || enabledSystems.contains(TargetSystem.APPSEC) + || enabledSystems.contains(TargetSystem.IAST); } @Override @@ -80,6 +76,6 @@ public void methodAdvice(MethodTransformer transformer) { @Override public Advice.PostProcessor.Factory postProcessor() { - return postProcessorFactory; + return IastPostProcessorFactory.INSTANCE; } } diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteMatchesAdvice.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteMatchesAdvice.java index f52ed53ece3..8880567f3c4 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteMatchesAdvice.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteMatchesAdvice.java @@ -1,7 +1,12 @@ package datadog.trace.instrumentation.vertx_4_0.server; +import static datadog.trace.instrumentation.vertx_4_0.server.RouteHandlerWrapper.HANDLER_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_4_0.server.RouteHandlerWrapper.PARENT_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_4_0.server.RouteHandlerWrapper.updateRoute; + import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import io.vertx.ext.web.RoutingContext; import java.util.Map; import net.bytebuddy.asm.Advice; @@ -16,6 +21,24 @@ static void after( if (ret != 0 || t != null) { return; } + final AgentSpan parentSpan = ctx.get(PARENT_SPAN_CONTEXT_KEY); + final AgentSpan handlerSpan = ctx.get(HANDLER_SPAN_CONTEXT_KEY); + if (ctx.currentRoute() != null) { + final String method = ctx.request().method().name(); + String path = ctx.currentRoute().getPath(); + if (path == null) { + path = ctx.currentRoute().getName(); + } + final String mountPoint = ctx.mountPoint(); + if (mountPoint != null && path != null) { + final String noBackslashhMountPoint = + mountPoint.endsWith("/") + ? mountPoint.substring(0, mountPoint.lastIndexOf("/")) + : mountPoint; + path = noBackslashhMountPoint + path; + } + updateRoute(ctx, method, path, parentSpan, handlerSpan); + } Map params = ctx.pathParams(); if (params.isEmpty()) { return; @@ -39,6 +62,24 @@ static void after( if (!ret || t != null) { return; } + final AgentSpan parentSpan = ctx.get(PARENT_SPAN_CONTEXT_KEY); + final AgentSpan handlerSpan = ctx.get(HANDLER_SPAN_CONTEXT_KEY); + if (ctx.currentRoute() != null) { + final String method = ctx.request().method().name(); + String path = ctx.currentRoute().getPath(); + if (path == null) { + path = ctx.currentRoute().getName(); + } + final String mountPoint = ctx.mountPoint(); + if (mountPoint != null && path != null) { + final String noBackslashhMountPoint = + mountPoint.endsWith("/") + ? mountPoint.substring(0, mountPoint.lastIndexOf("/")) + : mountPoint; + path = noBackslashhMountPoint + path; + } + updateRoute(ctx, method, path, parentSpan, handlerSpan); + } Map params = ctx.pathParams(); if (params.isEmpty()) { return; diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapperTest.groovy b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapperTest.groovy new file mode 100644 index 00000000000..f2844e39bcf --- /dev/null +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapperTest.groovy @@ -0,0 +1,45 @@ +package datadog.trace.instrumentation.vertx_4_0.server + +import datadog.trace.agent.test.InstrumentationSpecification +import datadog.trace.bootstrap.instrumentation.api.AgentSpan +import datadog.trace.bootstrap.instrumentation.api.Tags +import io.vertx.ext.web.RoutingContext + +class RouteHandlerWrapperTest extends InstrumentationSpecification { + + void "updateRoute writes route to both spans"() { + given: + def context = Mock(RoutingContext) + def parentSpan = Mock(AgentSpan) + def handlerSpan = Mock(AgentSpan) + + when: + RouteHandlerWrapper.updateRoute(context, "GET", "/items/:id", parentSpan, handlerSpan) + + then: + 1 * context.get("dd.${Tags.HTTP_ROUTE}") >> null + 1 * context.put("dd.${Tags.HTTP_ROUTE}", "/items/:id") + 1 * parentSpan.setTag(Tags.HTTP_ROUTE, "/items/:id") + 1 * handlerSpan.getResourceNamePriority() >> Byte.MIN_VALUE + 1 * handlerSpan.setTag(Tags.HTTP_ROUTE, "/items/:id") + 0 * _ + } + + void "updateRoute does not replace root route when one exists"() { + given: + def context = Mock(RoutingContext) + def parentSpan = Mock(AgentSpan) + def handlerSpan = Mock(AgentSpan) + + when: + RouteHandlerWrapper.updateRoute(context, "GET", "/", parentSpan, handlerSpan) + + then: + 1 * context.get("dd.${Tags.HTTP_ROUTE}") >> null + 1 * parentSpan.getTag(Tags.HTTP_ROUTE) >> "/existing" + 1 * handlerSpan.getTag(Tags.HTTP_ROUTE) >> "/existing" + 0 * context.put(_, _) + 0 * parentSpan.setTag(_, _) + 0 * handlerSpan.setTag(_, _) + } +} diff --git a/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/.gitignore b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/.gitignore new file mode 100644 index 00000000000..1ec2c548b11 --- /dev/null +++ b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/.gitignore @@ -0,0 +1,6 @@ +# Ignore all project specific gradle directories/files +.gradle +gradle +build +gradlew +gradlew.bat diff --git a/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/build.gradle b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/build.gradle new file mode 100644 index 00000000000..267a61d3500 --- /dev/null +++ b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/build.gradle @@ -0,0 +1,32 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '3.5.5' + id 'io.spring.dependency-management' version '1.1.7' +} + +def sharedRootDir = "$rootDir/../../../" +def sharedConfigDirectory = "$sharedRootDir/gradle" +rootProject.ext.sharedConfigDirectory = sharedConfigDirectory + +apply from: "$sharedConfigDirectory/repositories.gradle" + +if (hasProperty('appBuildDir')) { + buildDir = property('appBuildDir') +} + +version = "" + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-undertow' + implementation 'org.springframework.boot:spring-boot-starter-actuator' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation group: 'com.h2database', name: 'h2', version: '2.3.232' + compileOnly group:"com.google.code.findbugs", name:"jsr305", version:"3.0.2" + + if (hasProperty('apiJar')) { + implementation files(property('apiJar')) + } else { + implementation "com.datadoghq:dd-trace-api:1.2.0" + } +} diff --git a/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/settings.gradle b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/settings.gradle new file mode 100644 index 00000000000..fad11f4c4a5 --- /dev/null +++ b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/settings.gradle @@ -0,0 +1,34 @@ +pluginManagement { + repositories { + mavenLocal() + if (settings.hasProperty("gradlePluginProxy")) { + maven { + url settings["gradlePluginProxy"] + allowInsecureProtocol = true + } + } + if (settings.hasProperty("mavenRepositoryProxy")) { + maven { + url settings["mavenRepositoryProxy"] + allowInsecureProtocol = true + } + } + gradlePluginPortal() + mavenCentral() + } +} + +def isCI = providers.environmentVariable("CI").isPresent() + +// Don't pollute the dependency cache with the build cache +if (isCI) { + def sharedRootDir = "$rootDir/../../../" + buildCache { + local { + // This needs to line up with the code in the outer project settings.gradle + directory = "$sharedRootDir/workspace/build-cache" + } + } +} + +rootProject.name='webmvc-3.5-undertow-smoketest' diff --git a/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/AppInitializer.java b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/AppInitializer.java new file mode 100644 index 00000000000..a734f5bcd19 --- /dev/null +++ b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/AppInitializer.java @@ -0,0 +1,22 @@ +package datadog.smoketest.springboot; + +import datadog.smoketest.springboot.model.Fruit; +import datadog.smoketest.springboot.repository.FruitRepository; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.stereotype.Service; + +@Service +public class AppInitializer implements InitializingBean { + private final FruitRepository fruitRepository; + + public AppInitializer(FruitRepository fruitRepository) { + this.fruitRepository = fruitRepository; + } + + @Override + public void afterPropertiesSet() throws Exception { + fruitRepository.save(new Fruit("apple")); + fruitRepository.save(new Fruit("banana")); + fruitRepository.save(new Fruit("orange")); + } +} diff --git a/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/SpringbootApplication.java b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/SpringbootApplication.java new file mode 100644 index 00000000000..e26a5350e0e --- /dev/null +++ b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/SpringbootApplication.java @@ -0,0 +1,14 @@ +package datadog.smoketest.springboot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +@SpringBootApplication +@EnableJpaRepositories +public class SpringbootApplication { + + public static void main(final String[] args) { + SpringApplication.run(SpringbootApplication.class, args); + } +} diff --git a/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/controller/FruitController.java b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/controller/FruitController.java new file mode 100644 index 00000000000..9818e3ef87d --- /dev/null +++ b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/controller/FruitController.java @@ -0,0 +1,33 @@ +package datadog.smoketest.springboot.controller; + +import datadog.smoketest.springboot.model.Fruit; +import datadog.smoketest.springboot.repository.FruitRepository; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/fruits") +public class FruitController { + + private final FruitRepository fruitRepository; + + public FruitController(FruitRepository fruitRepository) { + this.fruitRepository = fruitRepository; + } + + @GetMapping + public Iterable listFruits() { + return fruitRepository.findAll(); + } + + @GetMapping("/{name}") + public ResponseEntity findOneFruit(@PathVariable("name") final String name) { + return fruitRepository + .findByName(name) + .map(ResponseEntity::ok) + .orElseGet(() -> ResponseEntity.notFound().build()); + } +} diff --git a/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/model/Fruit.java b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/model/Fruit.java new file mode 100644 index 00000000000..32cae6ce653 --- /dev/null +++ b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/model/Fruit.java @@ -0,0 +1,58 @@ +package datadog.smoketest.springboot.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import java.util.Objects; +import javax.annotation.Nonnull; + +@Entity +@Table +public class Fruit { + + public Fruit() {} + + public Fruit(@Nonnull String name) { + this.name = name; + } + + @Id @GeneratedValue private Long id; + + @Column(nullable = false) + private String name; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Fruit fruit = (Fruit) o; + return Objects.equals(id, fruit.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/repository/FruitRepository.java b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/repository/FruitRepository.java new file mode 100644 index 00000000000..0ae8142a77b --- /dev/null +++ b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/java/datadog/smoketest/springboot/repository/FruitRepository.java @@ -0,0 +1,12 @@ +package datadog.smoketest.springboot.repository; + +import datadog.smoketest.springboot.model.Fruit; +import java.util.Optional; +import javax.annotation.Nonnull; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface FruitRepository extends CrudRepository { + Optional findByName(@Nonnull final String name); +} diff --git a/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/resources/application.properties b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/resources/application.properties new file mode 100644 index 00000000000..84891dd7426 --- /dev/null +++ b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/application/src/main/resources/application.properties @@ -0,0 +1,16 @@ +logging.level.root=INFO +spring.datasource.url=jdbc:h2:mem:fruitdb +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password=password +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +spring.jpa.generate-ddl=true +spring.main.web-application-type=servlet +management.endpoints.web.exposure.include=health,info +logging.level.root=INFO +spring.datasource.url=jdbc:h2:mem:fruitdb +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password=password +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +spring.jpa.generate-ddl=true diff --git a/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/build.gradle b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/build.gradle new file mode 100644 index 00000000000..62aceeb9804 --- /dev/null +++ b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/build.gradle @@ -0,0 +1,121 @@ +apply from: "$rootDir/gradle/java.gradle" +import java.nio.file.Files +import java.nio.file.StandardCopyOption + +testJvmConstraints { + minJavaVersion = JavaVersion.VERSION_21 +} + +description = 'Spring Boot 3.5 WebMvc Undertow Smoke Tests.' + +dependencies { + testImplementation project(':dd-smoke-tests') +} + +def appDir = "$projectDir/application" +def appBuildDir = "$buildDir/application" +def isWindows = System.getProperty("os.name").toLowerCase().contains("win") +def gradlewCommand = isWindows ? 'gradlew.bat' : 'gradlew' + +tasks.register('webmvcUndertowBuild35', Exec) { + workingDir "$appDir" + environment += [ + "GRADLE_OPTS": "-Dorg.gradle.jvmargs='-Xmx512M'", + "JAVA_HOME": getLazyJavaHomeFor(21) + ] + commandLine "$rootDir/${gradlewCommand}", "bootJar", "--no-daemon", "--max-workers=4", "-PappBuildDir=$appBuildDir", "-PapiJar=${project(':dd-trace-api').tasks.jar.archiveFile.get()}" + + outputs.cacheIf { true } + + outputs.dir(appBuildDir) + .withPropertyName("applicationJar") + + inputs.files(fileTree(appDir) { + include '**/*' + exclude '.gradle/**' + }) + .withPropertyName("application") + .withPathSensitivity(PathSensitivity.RELATIVE) +} + +tasks.named("compileTestGroovy", GroovyCompile) { + dependsOn project(':dd-trace-api').tasks.named("jar") + dependsOn 'webmvcUndertowBuild35' + outputs.upToDateWhen { + !webmvcUndertowBuild35.didWork + } +} + +tasks.withType(Test).configureEach { + jvmArgs "-Ddatadog.smoketest.springboot.uberJar.path=$appBuildDir/libs/webmvc-3.5-undertow-smoketest.jar" +} + +def releasedAgentsDir = file("$buildDir/released-agents") +def agent1604File = file("$releasedAgentsDir/dd-java-agent-1.60.4.jar") +def agent1610File = file("$releasedAgentsDir/dd-java-agent-1.61.0.jar") + +def registerDownloadTask = { String taskName, String url, File outputFile -> + tasks.register(taskName) { + description = "Download ${outputFile.name} for regression checks." + outputs.file(outputFile) + doLast { + outputFile.parentFile.mkdirs() + if (!outputFile.exists()) { + new URL(url).withInputStream { inStream -> + Files.copy(inStream, outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING) + } + } + } + } +} + +def downloadAgent1604 = registerDownloadTask( + "downloadAgent1604", + "https://github.com/DataDog/dd-trace-java/releases/download/v1.60.4/dd-java-agent.jar", + agent1604File +) + +def downloadAgent1610 = registerDownloadTask( + "downloadAgent1610", + "https://github.com/DataDog/dd-trace-java/releases/download/v1.61.0/dd-java-agent.jar", + agent1610File +) + +def configureReleasedAgentTestTask = { String taskName, File agentJar, TaskProvider downloadTask -> + tasks.register(taskName, Test) { + group = "verification" + description = "Run Spring Boot 3.5 Undertow smoke test with ${agentJar.name}" + testClassesDirs = sourceSets.test.output.classesDirs + classpath = sourceSets.test.runtimeClasspath + dependsOn tasks.named("testClasses") + dependsOn "webmvcUndertowBuild35" + dependsOn downloadTask + useJUnitPlatform() + filter { + includeTestsMatching("SpringBoot35UndertowIntegrationTest") + } + // Override the default local-agent path injected by :dd-smoke-tests. + systemProperty "datadog.smoketest.agent.jar.path.override", agentJar.absolutePath + jvmArgs "-Ddatadog.smoketest.springboot.uberJar.path=$appBuildDir/libs/webmvc-3.5-undertow-smoketest.jar" + } +} + +def testWithAgent1604 = configureReleasedAgentTestTask("testWithAgent1604", agent1604File, downloadAgent1604) +def testWithAgent1610 = configureReleasedAgentTestTask("testWithAgent1610", agent1610File, downloadAgent1610) + +tasks.register("reproducerMatrix") { + group = "verification" + description = "Run reproducer against 1.60.4 then 1.61.0." + dependsOn testWithAgent1604 + dependsOn testWithAgent1610 +} + +spotless { + java { + target "**/*.java" + } + + groovyGradle { + target '*.gradle', "**/*.gradle" + } +} diff --git a/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/src/test/groovy/SpringBoot35UndertowIntegrationTest.groovy b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/src/test/groovy/SpringBoot35UndertowIntegrationTest.groovy new file mode 100644 index 00000000000..3bf387bb53f --- /dev/null +++ b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/src/test/groovy/SpringBoot35UndertowIntegrationTest.groovy @@ -0,0 +1,105 @@ +import datadog.smoketest.AbstractServerSmokeTest +import okhttp3.Request + +import java.util.concurrent.atomic.AtomicInteger +import java.util.regex.Pattern + +class SpringBoot35UndertowIntegrationTest extends AbstractServerSmokeTest { + + @Override + ProcessBuilder createProcessBuilder() { + String springBootShadowJar = System.getProperty("datadog.smoketest.springboot.uberJar.path") + + List command = new ArrayList<>() + command.add(javaPath()) + command.addAll(defaultJavaProperties) + command.addAll((String[]) [ + "-Ddd.writer.type=MultiWriter:TraceStructureWriter:${output.getAbsolutePath()}:includeResource,DDAgentWriter", + "-Ddd.trace.debug=true", + "-jar", + springBootShadowJar, + "--server.port=${httpPort}" + ]) + ProcessBuilder processBuilder = new ProcessBuilder(command) + processBuilder.directory(new File(buildDirectory)) + } + + @Override + File createTemporaryFile() { + return File.createTempFile("trace-structure-docs", "out") + } + + @Override + protected Set expectedTraces() { + return [ + "\\[servlet\\.request:GET /fruits\\[spring\\.handler:FruitController\\.listFruits\\[repository\\.operation:FruitRepository\\.findAll\\[h2\\.query:.*", + "\\[servlet\\.request:GET /fruits/\\{name}\\[spring\\.handler:FruitController\\.findOneFruit\\[repository\\.operation:FruitRepository\\.findByName\\[h2\\.query:.*" + ] + } + + @Override + protected Set assertTraceCounts(Set expected, Map traceCounts) { + List remaining = expected.collect { Pattern.compile(it) }.toList() + for (def i = remaining.size() - 1; i >= 0; i--) { + for (Map.Entry entry : traceCounts.entrySet()) { + if (entry.getValue() > 0 && remaining.get(i).matcher(entry.getKey()).matches()) { + remaining.remove(i) + break + } + } + } + return remaining.collect { it.pattern() }.toSet() + } + + def "responds to /fruits without hanging"() { + setup: + String url = "http://localhost:${httpPort}/fruits" + + when: + def response = client.newCall(new Request.Builder().url(url).get().build()).execute() + + then: + response.code() == 200 + def responseBodyStr = response.body().string() + responseBodyStr != null + ["banana", "apple", "orange"].each { responseBodyStr.contains(it) } + waitForTraceCount(1) + } + + def "responds to /fruits/{name} without hanging"() { + setup: + String url = "http://localhost:${httpPort}/fruits/banana" + + when: + def response = client.newCall(new Request.Builder().url(url).get().build()).execute() + + then: + response.code() == 200 + def responseBodyStr = response.body().string() + responseBodyStr != null + responseBodyStr.contains("banana") + waitForTraceCount(1) + } + + def "actuator health endpoint remains responsive"() { + setup: + String url = "http://localhost:${httpPort}/actuator/health" + + when: + def response = client.newCall(new Request.Builder().url(url).get().build()).execute() + + then: + response.code() == 200 + response.body().string().contains("UP") + } + + @Override + boolean testTelemetry() { + false + } + + @Override + List expectedTelemetryDependencies() { + ['spring-core', 'io.undertow:undertow-core'] + } +} diff --git a/dd-smoke-tests/src/main/groovy/datadog/smoketest/ProcessManager.groovy b/dd-smoke-tests/src/main/groovy/datadog/smoketest/ProcessManager.groovy index 31e24c70488..891c5c04d02 100644 --- a/dd-smoke-tests/src/main/groovy/datadog/smoketest/ProcessManager.groovy +++ b/dd-smoke-tests/src/main/groovy/datadog/smoketest/ProcessManager.groovy @@ -19,7 +19,10 @@ abstract class ProcessManager extends Specification { @Shared protected String buildDirectory = System.getProperty("datadog.smoketest.builddir") @Shared - protected String shadowJarPath = System.getProperty("datadog.smoketest.agent.shadowJar.path") + protected String shadowJarPath = + System.getProperty( + "datadog.smoketest.agent.jar.path.override", + System.getProperty("datadog.smoketest.agent.shadowJar.path")) @Shared protected boolean isIBM = System.getProperty("java.vendor", "").contains("IBM") diff --git a/settings.gradle.kts b/settings.gradle.kts index 074514e7126..0aad88cfca7 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -228,6 +228,7 @@ include( ":dd-smoke-tests:spring-boot-2.6-webmvc", ":dd-smoke-tests:spring-boot-3.0-webmvc", ":dd-smoke-tests:spring-boot-3.3-webmvc", + ":dd-smoke-tests:spring-boot-3.5-webmvc-undertow", ":dd-smoke-tests:spring-boot-rabbit", ":dd-smoke-tests:spring-security", ":dd-smoke-tests:springboot", From d980ce39ffdc224370caa1f00e1c5eeb00218669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Vandon?= Date: Thu, 16 Apr 2026 15:21:51 +0200 Subject: [PATCH 2/5] add tag for debug purposes --- .../vertx_3_4/server/EndHandlerWrapper.java | 2 +- .../vertx_3_4/server/RouteHandlerWrapper.java | 11 +++++++++-- .../vertx_3_4/server/RouteMatchesAdvice.java | 4 ++-- .../server/RouteHandlerWrapperTest.groovy | 10 +++++++--- .../vertx_4_0/server/EndHandlerWrapper.java | 2 +- .../vertx_4_0/server/RouteHandlerWrapper.java | 11 +++++++++-- .../vertx_4_0/server/RouteMatchesAdvice.java | 4 ++-- .../server/RouteHandlerWrapperTest.groovy | 10 +++++++--- .../spring-boot-3.5-webmvc-undertow/build.gradle | 4 ++-- 9 files changed, 40 insertions(+), 18 deletions(-) rename dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/{datadog/trace/instrumentation/vertx_3_4 => }/server/RouteHandlerWrapperTest.groovy (77%) rename dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/{datadog/trace/instrumentation/vertx_4_0 => }/server/RouteHandlerWrapperTest.groovy (77%) diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/EndHandlerWrapper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/EndHandlerWrapper.java index 56300b14780..7935c8d06c3 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/EndHandlerWrapper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/EndHandlerWrapper.java @@ -40,7 +40,7 @@ public void handle(final Void event) { } path = mountPoint + path; } - updateRoute(routingContext, method, path, parentSpan, span); + updateRoute(routingContext, method, path, parentSpan, span, "end_handler"); } if (span != null) { DECORATE.onResponse(span, routingContext.response()); diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapper.java index dced46ca892..07e31ef76fb 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapper.java @@ -21,6 +21,7 @@ public class RouteHandlerWrapper implements Handler { static final String PARENT_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".parent"; static final String HANDLER_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".handler"; static final String ROUTE_CONTEXT_KEY = "dd." + Tags.HTTP_ROUTE; + static final String ROUTE_OVERWRITE_DEBUG_TAG = "dd.debug.vertx.route_overwrite"; private final Handler actual; private final boolean spanStarter; @@ -83,7 +84,7 @@ private void setRoute(RoutingContext routingContext) { } path = mountPoint + path; } - updateRoute(routingContext, method, path, parentSpan, handlerSpan); + updateRoute(routingContext, method, path, parentSpan, handlerSpan, "route_handler"); } static void updateRoute( @@ -91,21 +92,27 @@ static void updateRoute( final String method, final String path, final AgentSpan parentSpan, - final AgentSpan handlerSpan) { + final AgentSpan handlerSpan, + final String source) { if (method == null || path == null) { return; } + final String previousRoute = routingContext.get(ROUTE_CONTEXT_KEY); if (!shouldUpdateRoute(routingContext, parentSpan, handlerSpan, path)) { return; } routingContext.put(ROUTE_CONTEXT_KEY, path); + final String previous = previousRoute == null ? "" : previousRoute; + final String debugValue = source + ":" + previous + "->" + path; if (parentSpan != null) { HTTP_RESOURCE_DECORATOR.withRoute(parentSpan, method, path, true); + parentSpan.setTag(ROUTE_OVERWRITE_DEBUG_TAG, debugValue); } if (handlerSpan != null && handlerSpan.getResourceNamePriority() < ResourceNamePriorities.HTTP_FRAMEWORK_ROUTE) { HTTP_RESOURCE_DECORATOR.withRoute(handlerSpan, method, path, true); + handlerSpan.setTag(ROUTE_OVERWRITE_DEBUG_TAG, debugValue); } } diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteMatchesAdvice.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteMatchesAdvice.java index 95d149e5a68..c020f9e3926 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteMatchesAdvice.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteMatchesAdvice.java @@ -36,7 +36,7 @@ static void after( } path = mountPoint + path; } - updateRoute(ctx, method, path, parentSpan, handlerSpan); + updateRoute(ctx, method, path, parentSpan, handlerSpan, "matches"); } Map params = ctx.pathParams(); if (params.isEmpty()) { @@ -72,7 +72,7 @@ static void after( } path = mountPoint + path; } - updateRoute(ctx, method, path, parentSpan, handlerSpan); + updateRoute(ctx, method, path, parentSpan, handlerSpan, "matches"); } Map params = ctx.pathParams(); if (params.isEmpty()) { diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapperTest.groovy b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/server/RouteHandlerWrapperTest.groovy similarity index 77% rename from dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapperTest.groovy rename to dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/server/RouteHandlerWrapperTest.groovy index 81e72cfa44b..feb3c98c5d0 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapperTest.groovy +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/server/RouteHandlerWrapperTest.groovy @@ -1,8 +1,9 @@ -package datadog.trace.instrumentation.vertx_3_4.server +package server import datadog.trace.agent.test.InstrumentationSpecification import datadog.trace.bootstrap.instrumentation.api.AgentSpan import datadog.trace.bootstrap.instrumentation.api.Tags +import datadog.trace.instrumentation.vertx_3_4.server.RouteHandlerWrapper import io.vertx.ext.web.RoutingContext class RouteHandlerWrapperTest extends InstrumentationSpecification { @@ -14,14 +15,17 @@ class RouteHandlerWrapperTest extends InstrumentationSpecification { def handlerSpan = Mock(AgentSpan) when: - RouteHandlerWrapper.updateRoute(context, "GET", "/items/:id", parentSpan, handlerSpan) + RouteHandlerWrapper.updateRoute( + context, "GET", "/items/:id", parentSpan, handlerSpan, "matches") then: 1 * context.get("dd.${Tags.HTTP_ROUTE}") >> null 1 * context.put("dd.${Tags.HTTP_ROUTE}", "/items/:id") 1 * parentSpan.setTag(Tags.HTTP_ROUTE, "/items/:id") + 1 * parentSpan.setTag("dd.debug.vertx.route_overwrite", "matches:->/items/:id") 1 * handlerSpan.getResourceNamePriority() >> Byte.MIN_VALUE 1 * handlerSpan.setTag(Tags.HTTP_ROUTE, "/items/:id") + 1 * handlerSpan.setTag("dd.debug.vertx.route_overwrite", "matches:->/items/:id") 0 * _ } @@ -32,7 +36,7 @@ class RouteHandlerWrapperTest extends InstrumentationSpecification { def handlerSpan = Mock(AgentSpan) when: - RouteHandlerWrapper.updateRoute(context, "GET", "/", parentSpan, handlerSpan) + RouteHandlerWrapper.updateRoute(context, "GET", "/", parentSpan, handlerSpan, "matches") then: 1 * context.get("dd.${Tags.HTTP_ROUTE}") >> null diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/EndHandlerWrapper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/EndHandlerWrapper.java index 4ce8cbab00a..dae53b4e63f 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/EndHandlerWrapper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/EndHandlerWrapper.java @@ -41,7 +41,7 @@ public void handle(final Void event) { : mountPoint; path = noBackslashhMountPoint + path; } - updateRoute(routingContext, method, path, parentSpan, span); + updateRoute(routingContext, method, path, parentSpan, span, "end_handler"); } if (span != null) { DECORATE.onResponse(span, routingContext.response()); diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapper.java index 83e78f70dbe..96672f94ca6 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapper.java @@ -20,6 +20,7 @@ public class RouteHandlerWrapper implements Handler { static final String PARENT_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".parent"; static final String HANDLER_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".handler"; static final String ROUTE_CONTEXT_KEY = "dd." + Tags.HTTP_ROUTE; + static final String ROUTE_OVERWRITE_DEBUG_TAG = "dd.debug.vertx.route_overwrite"; private final Handler actual; private final boolean spanStarter; @@ -84,7 +85,7 @@ private void setRoute(RoutingContext routingContext) { : mountPoint; path = noBackslashhMountPoint + path; } - updateRoute(routingContext, method, path, parentSpan, handlerSpan); + updateRoute(routingContext, method, path, parentSpan, handlerSpan, "route_handler"); } static void updateRoute( @@ -92,21 +93,27 @@ static void updateRoute( final String method, final String path, final AgentSpan parentSpan, - final AgentSpan handlerSpan) { + final AgentSpan handlerSpan, + final String source) { if (method == null || path == null) { return; } + final String previousRoute = routingContext.get(ROUTE_CONTEXT_KEY); if (!shouldUpdateRoute(routingContext, parentSpan, handlerSpan, path)) { return; } routingContext.put(ROUTE_CONTEXT_KEY, path); + final String previous = previousRoute == null ? "" : previousRoute; + final String debugValue = source + ":" + previous + "->" + path; if (parentSpan != null) { HTTP_RESOURCE_DECORATOR.withRoute(parentSpan, method, path, true); + parentSpan.setTag(ROUTE_OVERWRITE_DEBUG_TAG, debugValue); } if (handlerSpan != null && handlerSpan.getResourceNamePriority() < ResourceNamePriorities.HTTP_FRAMEWORK_ROUTE) { HTTP_RESOURCE_DECORATOR.withRoute(handlerSpan, method, path, true); + handlerSpan.setTag(ROUTE_OVERWRITE_DEBUG_TAG, debugValue); } } diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteMatchesAdvice.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteMatchesAdvice.java index 8880567f3c4..de8bbcc3d75 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteMatchesAdvice.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteMatchesAdvice.java @@ -37,7 +37,7 @@ static void after( : mountPoint; path = noBackslashhMountPoint + path; } - updateRoute(ctx, method, path, parentSpan, handlerSpan); + updateRoute(ctx, method, path, parentSpan, handlerSpan, "matches"); } Map params = ctx.pathParams(); if (params.isEmpty()) { @@ -78,7 +78,7 @@ static void after( : mountPoint; path = noBackslashhMountPoint + path; } - updateRoute(ctx, method, path, parentSpan, handlerSpan); + updateRoute(ctx, method, path, parentSpan, handlerSpan, "matches"); } Map params = ctx.pathParams(); if (params.isEmpty()) { diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapperTest.groovy b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/server/RouteHandlerWrapperTest.groovy similarity index 77% rename from dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapperTest.groovy rename to dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/server/RouteHandlerWrapperTest.groovy index f2844e39bcf..143dfef41ff 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapperTest.groovy +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/server/RouteHandlerWrapperTest.groovy @@ -1,8 +1,9 @@ -package datadog.trace.instrumentation.vertx_4_0.server +package server import datadog.trace.agent.test.InstrumentationSpecification import datadog.trace.bootstrap.instrumentation.api.AgentSpan import datadog.trace.bootstrap.instrumentation.api.Tags +import datadog.trace.instrumentation.vertx_4_0.server.RouteHandlerWrapper import io.vertx.ext.web.RoutingContext class RouteHandlerWrapperTest extends InstrumentationSpecification { @@ -14,14 +15,17 @@ class RouteHandlerWrapperTest extends InstrumentationSpecification { def handlerSpan = Mock(AgentSpan) when: - RouteHandlerWrapper.updateRoute(context, "GET", "/items/:id", parentSpan, handlerSpan) + RouteHandlerWrapper.updateRoute( + context, "GET", "/items/:id", parentSpan, handlerSpan, "matches") then: 1 * context.get("dd.${Tags.HTTP_ROUTE}") >> null 1 * context.put("dd.${Tags.HTTP_ROUTE}", "/items/:id") 1 * parentSpan.setTag(Tags.HTTP_ROUTE, "/items/:id") + 1 * parentSpan.setTag("dd.debug.vertx.route_overwrite", "matches:->/items/:id") 1 * handlerSpan.getResourceNamePriority() >> Byte.MIN_VALUE 1 * handlerSpan.setTag(Tags.HTTP_ROUTE, "/items/:id") + 1 * handlerSpan.setTag("dd.debug.vertx.route_overwrite", "matches:->/items/:id") 0 * _ } @@ -32,7 +36,7 @@ class RouteHandlerWrapperTest extends InstrumentationSpecification { def handlerSpan = Mock(AgentSpan) when: - RouteHandlerWrapper.updateRoute(context, "GET", "/", parentSpan, handlerSpan) + RouteHandlerWrapper.updateRoute(context, "GET", "/", parentSpan, handlerSpan, "matches") then: 1 * context.get("dd.${Tags.HTTP_ROUTE}") >> null diff --git a/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/build.gradle b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/build.gradle index 62aceeb9804..3e3a0646a33 100644 --- a/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/build.gradle +++ b/dd-smoke-tests/spring-boot-3.5-webmvc-undertow/build.gradle @@ -73,13 +73,13 @@ def downloadAgent1604 = registerDownloadTask( "downloadAgent1604", "https://github.com/DataDog/dd-trace-java/releases/download/v1.60.4/dd-java-agent.jar", agent1604File -) + ) def downloadAgent1610 = registerDownloadTask( "downloadAgent1610", "https://github.com/DataDog/dd-trace-java/releases/download/v1.61.0/dd-java-agent.jar", agent1610File -) + ) def configureReleasedAgentTestTask = { String taskName, File agentJar, TaskProvider downloadTask -> tasks.register(taskName, Test) { From ae10fb30203b8fe29db4cbcc1f9c549b925f72e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Vandon?= Date: Thu, 16 Apr 2026 21:23:16 +0200 Subject: [PATCH 3/5] fix tests --- .../vertx_3_4/server/EndHandlerWrapper.java | 6 +- .../vertx_3_4/server/RouteHandlerWrapper.java | 63 +---------------- .../server/RouteImplInstrumentation.java | 2 +- .../vertx_3_4/server/RouteMatchesAdvice.java | 6 +- .../vertx_3_4/server/RouteUpdateHelper.java | 69 +++++++++++++++++++ .../server/RouteHandlerWrapperTest.groovy | 6 +- .../vertx_4_0/server/EndHandlerWrapper.java | 6 +- .../vertx_4_0/server/RouteHandlerWrapper.java | 63 +---------------- .../server/RouteImplInstrumentation.java | 2 +- .../vertx_4_0/server/RouteMatchesAdvice.java | 6 +- .../vertx_4_0/server/RouteUpdateHelper.java | 69 +++++++++++++++++++ .../server/RouteHandlerWrapperTest.groovy | 6 +- 12 files changed, 164 insertions(+), 140 deletions(-) create mode 100644 dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteUpdateHelper.java create mode 100644 dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteUpdateHelper.java diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/EndHandlerWrapper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/EndHandlerWrapper.java index 7935c8d06c3..03e226454ff 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/EndHandlerWrapper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/EndHandlerWrapper.java @@ -1,8 +1,8 @@ package datadog.trace.instrumentation.vertx_3_4.server; -import static datadog.trace.instrumentation.vertx_3_4.server.RouteHandlerWrapper.HANDLER_SPAN_CONTEXT_KEY; -import static datadog.trace.instrumentation.vertx_3_4.server.RouteHandlerWrapper.PARENT_SPAN_CONTEXT_KEY; -import static datadog.trace.instrumentation.vertx_3_4.server.RouteHandlerWrapper.updateRoute; +import static datadog.trace.instrumentation.vertx_3_4.server.RouteUpdateHelper.HANDLER_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_3_4.server.RouteUpdateHelper.PARENT_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_3_4.server.RouteUpdateHelper.updateRoute; import static datadog.trace.instrumentation.vertx_3_4.server.VertxDecorator.DECORATE; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapper.java index 07e31ef76fb..d45ab969fde 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapper.java @@ -4,25 +4,20 @@ import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopScope; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; -import static datadog.trace.bootstrap.instrumentation.decorator.http.HttpResourceDecorator.HTTP_RESOURCE_DECORATOR; +import static datadog.trace.instrumentation.vertx_3_4.server.RouteUpdateHelper.HANDLER_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_3_4.server.RouteUpdateHelper.PARENT_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_3_4.server.RouteUpdateHelper.updateRoute; import static datadog.trace.instrumentation.vertx_3_4.server.VertxDecorator.DECORATE; import static datadog.trace.instrumentation.vertx_3_4.server.VertxDecorator.INSTRUMENTATION_NAME; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; -import datadog.trace.bootstrap.instrumentation.api.ResourceNamePriorities; -import datadog.trace.bootstrap.instrumentation.api.Tags; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import io.vertx.ext.web.impl.RouteImpl; import io.vertx.ext.web.impl.RouterImpl; public class RouteHandlerWrapper implements Handler { - static final String PARENT_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".parent"; - static final String HANDLER_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".handler"; - static final String ROUTE_CONTEXT_KEY = "dd." + Tags.HTTP_ROUTE; - static final String ROUTE_OVERWRITE_DEBUG_TAG = "dd.debug.vertx.route_overwrite"; - private final Handler actual; private final boolean spanStarter; @@ -86,56 +81,4 @@ private void setRoute(RoutingContext routingContext) { } updateRoute(routingContext, method, path, parentSpan, handlerSpan, "route_handler"); } - - static void updateRoute( - final RoutingContext routingContext, - final String method, - final String path, - final AgentSpan parentSpan, - final AgentSpan handlerSpan, - final String source) { - if (method == null || path == null) { - return; - } - final String previousRoute = routingContext.get(ROUTE_CONTEXT_KEY); - if (!shouldUpdateRoute(routingContext, parentSpan, handlerSpan, path)) { - return; - } - - routingContext.put(ROUTE_CONTEXT_KEY, path); - final String previous = previousRoute == null ? "" : previousRoute; - final String debugValue = source + ":" + previous + "->" + path; - if (parentSpan != null) { - HTTP_RESOURCE_DECORATOR.withRoute(parentSpan, method, path, true); - parentSpan.setTag(ROUTE_OVERWRITE_DEBUG_TAG, debugValue); - } - if (handlerSpan != null - && handlerSpan.getResourceNamePriority() < ResourceNamePriorities.HTTP_FRAMEWORK_ROUTE) { - HTTP_RESOURCE_DECORATOR.withRoute(handlerSpan, method, path, true); - handlerSpan.setTag(ROUTE_OVERWRITE_DEBUG_TAG, debugValue); - } - } - - static boolean shouldUpdateRoute( - final RoutingContext routingContext, - final AgentSpan parentSpan, - final AgentSpan handlerSpan, - final String path) { - if (parentSpan == null && handlerSpan == null) { - return false; - } - final String currentRoute = routingContext.get(ROUTE_CONTEXT_KEY); - if (currentRoute != null && currentRoute.equals(path)) { - return false; - } - // do not override route with a "/" if it's already set (it's probably more meaningful) - if (!path.equals("/")) { - return true; - } - return !hasHttpRoute(parentSpan) && !hasHttpRoute(handlerSpan); - } - - private static boolean hasHttpRoute(final AgentSpan span) { - return span != null && span.getTag(Tags.HTTP_ROUTE) != null; - } } diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteImplInstrumentation.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteImplInstrumentation.java index 000afeffdd5..2d8253efd8d 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteImplInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteImplInstrumentation.java @@ -46,7 +46,7 @@ public String[] knownMatchingTypes() { @Override public String[] helperClassNames() { return new String[] { - packageName + ".PathParameterPublishingHelper", + packageName + ".RouteUpdateHelper", packageName + ".PathParameterPublishingHelper", }; } diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteMatchesAdvice.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteMatchesAdvice.java index c020f9e3926..9011964a851 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteMatchesAdvice.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteMatchesAdvice.java @@ -1,8 +1,8 @@ package datadog.trace.instrumentation.vertx_3_4.server; -import static datadog.trace.instrumentation.vertx_3_4.server.RouteHandlerWrapper.HANDLER_SPAN_CONTEXT_KEY; -import static datadog.trace.instrumentation.vertx_3_4.server.RouteHandlerWrapper.PARENT_SPAN_CONTEXT_KEY; -import static datadog.trace.instrumentation.vertx_3_4.server.RouteHandlerWrapper.updateRoute; +import static datadog.trace.instrumentation.vertx_3_4.server.RouteUpdateHelper.HANDLER_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_3_4.server.RouteUpdateHelper.PARENT_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_3_4.server.RouteUpdateHelper.updateRoute; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteUpdateHelper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteUpdateHelper.java new file mode 100644 index 00000000000..12f475af7e0 --- /dev/null +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteUpdateHelper.java @@ -0,0 +1,69 @@ +package datadog.trace.instrumentation.vertx_3_4.server; + +import static datadog.trace.bootstrap.instrumentation.decorator.http.HttpResourceDecorator.HTTP_RESOURCE_DECORATOR; + +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.api.ResourceNamePriorities; +import datadog.trace.bootstrap.instrumentation.api.Tags; +import io.vertx.ext.web.RoutingContext; + +public final class RouteUpdateHelper { + public static final String PARENT_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".parent"; + public static final String HANDLER_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".handler"; + public static final String ROUTE_CONTEXT_KEY = "dd." + Tags.HTTP_ROUTE; + public static final String ROUTE_OVERWRITE_DEBUG_TAG = "dd.debug.vertx.route_overwrite"; + + private RouteUpdateHelper() {} + + public static void updateRoute( + final RoutingContext routingContext, + final String method, + final String path, + final AgentSpan parentSpan, + final AgentSpan handlerSpan, + final String source) { + if (method == null || path == null) { + return; + } + final String previousRoute = routingContext.get(ROUTE_CONTEXT_KEY); + if (!shouldUpdateRoute(routingContext, parentSpan, handlerSpan, path)) { + return; + } + + routingContext.put(ROUTE_CONTEXT_KEY, path); + final String previous = previousRoute == null ? "" : previousRoute; + final String debugValue = source + ":" + previous + "->" + path; + if (parentSpan != null) { + HTTP_RESOURCE_DECORATOR.withRoute(parentSpan, method, path, true); + parentSpan.setTag(ROUTE_OVERWRITE_DEBUG_TAG, debugValue); + } + if (handlerSpan != null + && handlerSpan.getResourceNamePriority() < ResourceNamePriorities.HTTP_FRAMEWORK_ROUTE) { + HTTP_RESOURCE_DECORATOR.withRoute(handlerSpan, method, path, true); + handlerSpan.setTag(ROUTE_OVERWRITE_DEBUG_TAG, debugValue); + } + } + + public static boolean shouldUpdateRoute( + final RoutingContext routingContext, + final AgentSpan parentSpan, + final AgentSpan handlerSpan, + final String path) { + if (parentSpan == null && handlerSpan == null) { + return false; + } + final String currentRoute = routingContext.get(ROUTE_CONTEXT_KEY); + if (currentRoute != null && currentRoute.equals(path)) { + return false; + } + // do not override route with a "/" if it's already set (it's probably more meaningful) + if (!path.equals("/")) { + return true; + } + return !hasHttpRoute(parentSpan) && !hasHttpRoute(handlerSpan); + } + + public static boolean hasHttpRoute(final AgentSpan span) { + return span != null && span.getTag(Tags.HTTP_ROUTE) != null; + } +} diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/server/RouteHandlerWrapperTest.groovy b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/server/RouteHandlerWrapperTest.groovy index feb3c98c5d0..f9c028dca86 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/server/RouteHandlerWrapperTest.groovy +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/server/RouteHandlerWrapperTest.groovy @@ -3,7 +3,7 @@ package server import datadog.trace.agent.test.InstrumentationSpecification import datadog.trace.bootstrap.instrumentation.api.AgentSpan import datadog.trace.bootstrap.instrumentation.api.Tags -import datadog.trace.instrumentation.vertx_3_4.server.RouteHandlerWrapper +import datadog.trace.instrumentation.vertx_3_4.server.RouteUpdateHelper import io.vertx.ext.web.RoutingContext class RouteHandlerWrapperTest extends InstrumentationSpecification { @@ -15,7 +15,7 @@ class RouteHandlerWrapperTest extends InstrumentationSpecification { def handlerSpan = Mock(AgentSpan) when: - RouteHandlerWrapper.updateRoute( + RouteUpdateHelper.updateRoute( context, "GET", "/items/:id", parentSpan, handlerSpan, "matches") then: @@ -36,7 +36,7 @@ class RouteHandlerWrapperTest extends InstrumentationSpecification { def handlerSpan = Mock(AgentSpan) when: - RouteHandlerWrapper.updateRoute(context, "GET", "/", parentSpan, handlerSpan, "matches") + RouteUpdateHelper.updateRoute(context, "GET", "/", parentSpan, handlerSpan, "matches") then: 1 * context.get("dd.${Tags.HTTP_ROUTE}") >> null diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/EndHandlerWrapper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/EndHandlerWrapper.java index dae53b4e63f..ec6246606f8 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/EndHandlerWrapper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/EndHandlerWrapper.java @@ -1,8 +1,8 @@ package datadog.trace.instrumentation.vertx_4_0.server; -import static datadog.trace.instrumentation.vertx_4_0.server.RouteHandlerWrapper.HANDLER_SPAN_CONTEXT_KEY; -import static datadog.trace.instrumentation.vertx_4_0.server.RouteHandlerWrapper.PARENT_SPAN_CONTEXT_KEY; -import static datadog.trace.instrumentation.vertx_4_0.server.RouteHandlerWrapper.updateRoute; +import static datadog.trace.instrumentation.vertx_4_0.server.RouteUpdateHelper.HANDLER_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_4_0.server.RouteUpdateHelper.PARENT_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_4_0.server.RouteUpdateHelper.updateRoute; import static datadog.trace.instrumentation.vertx_4_0.server.VertxDecorator.DECORATE; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapper.java index 96672f94ca6..113a47de585 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapper.java @@ -4,24 +4,19 @@ import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopScope; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; -import static datadog.trace.bootstrap.instrumentation.decorator.http.HttpResourceDecorator.HTTP_RESOURCE_DECORATOR; +import static datadog.trace.instrumentation.vertx_4_0.server.RouteUpdateHelper.HANDLER_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_4_0.server.RouteUpdateHelper.PARENT_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_4_0.server.RouteUpdateHelper.updateRoute; import static datadog.trace.instrumentation.vertx_4_0.server.VertxDecorator.DECORATE; import static datadog.trace.instrumentation.vertx_4_0.server.VertxDecorator.INSTRUMENTATION_NAME; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; -import datadog.trace.bootstrap.instrumentation.api.ResourceNamePriorities; -import datadog.trace.bootstrap.instrumentation.api.Tags; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import io.vertx.ext.web.impl.RouteImpl; public class RouteHandlerWrapper implements Handler { - static final String PARENT_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".parent"; - static final String HANDLER_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".handler"; - static final String ROUTE_CONTEXT_KEY = "dd." + Tags.HTTP_ROUTE; - static final String ROUTE_OVERWRITE_DEBUG_TAG = "dd.debug.vertx.route_overwrite"; - private final Handler actual; private final boolean spanStarter; @@ -87,56 +82,4 @@ private void setRoute(RoutingContext routingContext) { } updateRoute(routingContext, method, path, parentSpan, handlerSpan, "route_handler"); } - - static void updateRoute( - final RoutingContext routingContext, - final String method, - final String path, - final AgentSpan parentSpan, - final AgentSpan handlerSpan, - final String source) { - if (method == null || path == null) { - return; - } - final String previousRoute = routingContext.get(ROUTE_CONTEXT_KEY); - if (!shouldUpdateRoute(routingContext, parentSpan, handlerSpan, path)) { - return; - } - - routingContext.put(ROUTE_CONTEXT_KEY, path); - final String previous = previousRoute == null ? "" : previousRoute; - final String debugValue = source + ":" + previous + "->" + path; - if (parentSpan != null) { - HTTP_RESOURCE_DECORATOR.withRoute(parentSpan, method, path, true); - parentSpan.setTag(ROUTE_OVERWRITE_DEBUG_TAG, debugValue); - } - if (handlerSpan != null - && handlerSpan.getResourceNamePriority() < ResourceNamePriorities.HTTP_FRAMEWORK_ROUTE) { - HTTP_RESOURCE_DECORATOR.withRoute(handlerSpan, method, path, true); - handlerSpan.setTag(ROUTE_OVERWRITE_DEBUG_TAG, debugValue); - } - } - - static boolean shouldUpdateRoute( - final RoutingContext routingContext, - final AgentSpan parentSpan, - final AgentSpan handlerSpan, - final String path) { - if (parentSpan == null && handlerSpan == null) { - return false; - } - final String currentRoute = routingContext.get(ROUTE_CONTEXT_KEY); - if (currentRoute != null && currentRoute.equals(path)) { - return false; - } - // do not override route with a "/" if it's already set (it's probably more meaningful) - if (!path.equals("/")) { - return true; - } - return !hasHttpRoute(parentSpan) && !hasHttpRoute(handlerSpan); - } - - private static boolean hasHttpRoute(final AgentSpan span) { - return span != null && span.getTag(Tags.HTTP_ROUTE) != null; - } } diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteImplInstrumentation.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteImplInstrumentation.java index bf63ffc0a10..944ae4b7196 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteImplInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteImplInstrumentation.java @@ -44,7 +44,7 @@ public String[] knownMatchingTypes() { @Override public String[] helperClassNames() { return new String[] { - packageName + ".PathParameterPublishingHelper", + packageName + ".RouteUpdateHelper", packageName + ".PathParameterPublishingHelper", }; } diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteMatchesAdvice.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteMatchesAdvice.java index de8bbcc3d75..83b051ec507 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteMatchesAdvice.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteMatchesAdvice.java @@ -1,8 +1,8 @@ package datadog.trace.instrumentation.vertx_4_0.server; -import static datadog.trace.instrumentation.vertx_4_0.server.RouteHandlerWrapper.HANDLER_SPAN_CONTEXT_KEY; -import static datadog.trace.instrumentation.vertx_4_0.server.RouteHandlerWrapper.PARENT_SPAN_CONTEXT_KEY; -import static datadog.trace.instrumentation.vertx_4_0.server.RouteHandlerWrapper.updateRoute; +import static datadog.trace.instrumentation.vertx_4_0.server.RouteUpdateHelper.HANDLER_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_4_0.server.RouteUpdateHelper.PARENT_SPAN_CONTEXT_KEY; +import static datadog.trace.instrumentation.vertx_4_0.server.RouteUpdateHelper.updateRoute; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteUpdateHelper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteUpdateHelper.java new file mode 100644 index 00000000000..f98de2012d1 --- /dev/null +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteUpdateHelper.java @@ -0,0 +1,69 @@ +package datadog.trace.instrumentation.vertx_4_0.server; + +import static datadog.trace.bootstrap.instrumentation.decorator.http.HttpResourceDecorator.HTTP_RESOURCE_DECORATOR; + +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.api.ResourceNamePriorities; +import datadog.trace.bootstrap.instrumentation.api.Tags; +import io.vertx.ext.web.RoutingContext; + +public final class RouteUpdateHelper { + public static final String PARENT_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".parent"; + public static final String HANDLER_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".handler"; + public static final String ROUTE_CONTEXT_KEY = "dd." + Tags.HTTP_ROUTE; + public static final String ROUTE_OVERWRITE_DEBUG_TAG = "dd.debug.vertx.route_overwrite"; + + private RouteUpdateHelper() {} + + public static void updateRoute( + final RoutingContext routingContext, + final String method, + final String path, + final AgentSpan parentSpan, + final AgentSpan handlerSpan, + final String source) { + if (method == null || path == null) { + return; + } + final String previousRoute = routingContext.get(ROUTE_CONTEXT_KEY); + if (!shouldUpdateRoute(routingContext, parentSpan, handlerSpan, path)) { + return; + } + + routingContext.put(ROUTE_CONTEXT_KEY, path); + final String previous = previousRoute == null ? "" : previousRoute; + final String debugValue = source + ":" + previous + "->" + path; + if (parentSpan != null) { + HTTP_RESOURCE_DECORATOR.withRoute(parentSpan, method, path, true); + parentSpan.setTag(ROUTE_OVERWRITE_DEBUG_TAG, debugValue); + } + if (handlerSpan != null + && handlerSpan.getResourceNamePriority() < ResourceNamePriorities.HTTP_FRAMEWORK_ROUTE) { + HTTP_RESOURCE_DECORATOR.withRoute(handlerSpan, method, path, true); + handlerSpan.setTag(ROUTE_OVERWRITE_DEBUG_TAG, debugValue); + } + } + + public static boolean shouldUpdateRoute( + final RoutingContext routingContext, + final AgentSpan parentSpan, + final AgentSpan handlerSpan, + final String path) { + if (parentSpan == null && handlerSpan == null) { + return false; + } + final String currentRoute = routingContext.get(ROUTE_CONTEXT_KEY); + if (currentRoute != null && currentRoute.equals(path)) { + return false; + } + // do not override route with a "/" if it's already set (it's probably more meaningful) + if (!path.equals("/")) { + return true; + } + return !hasHttpRoute(parentSpan) && !hasHttpRoute(handlerSpan); + } + + public static boolean hasHttpRoute(final AgentSpan span) { + return span != null && span.getTag(Tags.HTTP_ROUTE) != null; + } +} diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/server/RouteHandlerWrapperTest.groovy b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/server/RouteHandlerWrapperTest.groovy index 143dfef41ff..d919d5be3e8 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/server/RouteHandlerWrapperTest.groovy +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/server/RouteHandlerWrapperTest.groovy @@ -3,7 +3,7 @@ package server import datadog.trace.agent.test.InstrumentationSpecification import datadog.trace.bootstrap.instrumentation.api.AgentSpan import datadog.trace.bootstrap.instrumentation.api.Tags -import datadog.trace.instrumentation.vertx_4_0.server.RouteHandlerWrapper +import datadog.trace.instrumentation.vertx_4_0.server.RouteUpdateHelper import io.vertx.ext.web.RoutingContext class RouteHandlerWrapperTest extends InstrumentationSpecification { @@ -15,7 +15,7 @@ class RouteHandlerWrapperTest extends InstrumentationSpecification { def handlerSpan = Mock(AgentSpan) when: - RouteHandlerWrapper.updateRoute( + RouteUpdateHelper.updateRoute( context, "GET", "/items/:id", parentSpan, handlerSpan, "matches") then: @@ -36,7 +36,7 @@ class RouteHandlerWrapperTest extends InstrumentationSpecification { def handlerSpan = Mock(AgentSpan) when: - RouteHandlerWrapper.updateRoute(context, "GET", "/", parentSpan, handlerSpan, "matches") + RouteUpdateHelper.updateRoute(context, "GET", "/", parentSpan, handlerSpan, "matches") then: 1 * context.get("dd.${Tags.HTTP_ROUTE}") >> null From 4f1d73d321be6f9ebb458e62d7cd3560b5fee25a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Vandon?= Date: Thu, 16 Apr 2026 21:51:58 +0200 Subject: [PATCH 4/5] missing helper --- .../vertx_3_4/server/RouteHandlerInstrumentation.java | 1 + .../vertx_4_0/server/RouteHandlerInstrumentation.java | 1 + 2 files changed, 2 insertions(+) diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerInstrumentation.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerInstrumentation.java index 6e4c5445d7d..f09054cdee7 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerInstrumentation.java @@ -21,6 +21,7 @@ public RouteHandlerInstrumentation() { public String[] helperClassNames() { return new String[] { packageName + ".EndHandlerWrapper", + packageName + ".RouteUpdateHelper", packageName + ".RouteHandlerWrapper", packageName + ".VertxDecorator", packageName + ".VertxDecorator$VertxURIDataAdapter", diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerInstrumentation.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerInstrumentation.java index 5cb72e52e65..081e65546ed 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerInstrumentation.java @@ -27,6 +27,7 @@ public Reference[] additionalMuzzleReferences() { public String[] helperClassNames() { return new String[] { packageName + ".EndHandlerWrapper", + packageName + ".RouteUpdateHelper", packageName + ".RouteHandlerWrapper", packageName + ".VertxDecorator", }; From 978b0ecde7610d42c712371f821f429de94017e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Vandon?= Date: Thu, 16 Apr 2026 22:13:14 +0200 Subject: [PATCH 5/5] remove the unseless code --- .../vertx_3_4/server/EndHandlerWrapper.java | 18 ------------------ .../vertx_3_4/server/RouteHandlerWrapper.java | 2 +- .../vertx_3_4/server/RouteMatchesAdvice.java | 4 ++-- .../vertx_3_4/server/RouteUpdateHelper.java | 9 +-------- .../server/RouteHandlerWrapperTest.groovy | 6 ++---- .../vertx_4_0/server/EndHandlerWrapper.java | 19 ------------------- .../vertx_4_0/server/RouteHandlerWrapper.java | 2 +- .../vertx_4_0/server/RouteMatchesAdvice.java | 4 ++-- .../vertx_4_0/server/RouteUpdateHelper.java | 9 +-------- .../server/RouteHandlerWrapperTest.groovy | 6 ++---- 10 files changed, 12 insertions(+), 67 deletions(-) diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/EndHandlerWrapper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/EndHandlerWrapper.java index 03e226454ff..b401e6b4576 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/EndHandlerWrapper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/EndHandlerWrapper.java @@ -1,8 +1,6 @@ package datadog.trace.instrumentation.vertx_3_4.server; import static datadog.trace.instrumentation.vertx_3_4.server.RouteUpdateHelper.HANDLER_SPAN_CONTEXT_KEY; -import static datadog.trace.instrumentation.vertx_3_4.server.RouteUpdateHelper.PARENT_SPAN_CONTEXT_KEY; -import static datadog.trace.instrumentation.vertx_3_4.server.RouteUpdateHelper.updateRoute; import static datadog.trace.instrumentation.vertx_3_4.server.VertxDecorator.DECORATE; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; @@ -21,27 +19,11 @@ public class EndHandlerWrapper implements Handler { @Override public void handle(final Void event) { AgentSpan span = routingContext.get(HANDLER_SPAN_CONTEXT_KEY); - AgentSpan parentSpan = routingContext.get(PARENT_SPAN_CONTEXT_KEY); try { if (actual != null) { actual.handle(event); } } finally { - if (routingContext.currentRoute() != null) { - final String method = routingContext.request().rawMethod(); - String path = routingContext.currentRoute().getPath(); - String mountPoint = routingContext.mountPoint(); - if (mountPoint != null && !mountPoint.isEmpty()) { - if (mountPoint.charAt(mountPoint.length() - 1) == '/' - && path != null - && !path.isEmpty() - && path.charAt(0) == '/') { - mountPoint = mountPoint.substring(0, mountPoint.length() - 1); - } - path = mountPoint + path; - } - updateRoute(routingContext, method, path, parentSpan, span, "end_handler"); - } if (span != null) { DECORATE.onResponse(span, routingContext.response()); span.finish(); diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapper.java index d45ab969fde..359fbb9d5f8 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteHandlerWrapper.java @@ -79,6 +79,6 @@ private void setRoute(RoutingContext routingContext) { } path = mountPoint + path; } - updateRoute(routingContext, method, path, parentSpan, handlerSpan, "route_handler"); + updateRoute(routingContext, method, path, parentSpan, handlerSpan); } } diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteMatchesAdvice.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteMatchesAdvice.java index 9011964a851..724bdfc71cf 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteMatchesAdvice.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteMatchesAdvice.java @@ -36,7 +36,7 @@ static void after( } path = mountPoint + path; } - updateRoute(ctx, method, path, parentSpan, handlerSpan, "matches"); + updateRoute(ctx, method, path, parentSpan, handlerSpan); } Map params = ctx.pathParams(); if (params.isEmpty()) { @@ -72,7 +72,7 @@ static void after( } path = mountPoint + path; } - updateRoute(ctx, method, path, parentSpan, handlerSpan, "matches"); + updateRoute(ctx, method, path, parentSpan, handlerSpan); } Map params = ctx.pathParams(); if (params.isEmpty()) { diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteUpdateHelper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteUpdateHelper.java index 12f475af7e0..252d743810e 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteUpdateHelper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RouteUpdateHelper.java @@ -11,7 +11,6 @@ public final class RouteUpdateHelper { public static final String PARENT_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".parent"; public static final String HANDLER_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".handler"; public static final String ROUTE_CONTEXT_KEY = "dd." + Tags.HTTP_ROUTE; - public static final String ROUTE_OVERWRITE_DEBUG_TAG = "dd.debug.vertx.route_overwrite"; private RouteUpdateHelper() {} @@ -20,27 +19,21 @@ public static void updateRoute( final String method, final String path, final AgentSpan parentSpan, - final AgentSpan handlerSpan, - final String source) { + final AgentSpan handlerSpan) { if (method == null || path == null) { return; } - final String previousRoute = routingContext.get(ROUTE_CONTEXT_KEY); if (!shouldUpdateRoute(routingContext, parentSpan, handlerSpan, path)) { return; } routingContext.put(ROUTE_CONTEXT_KEY, path); - final String previous = previousRoute == null ? "" : previousRoute; - final String debugValue = source + ":" + previous + "->" + path; if (parentSpan != null) { HTTP_RESOURCE_DECORATOR.withRoute(parentSpan, method, path, true); - parentSpan.setTag(ROUTE_OVERWRITE_DEBUG_TAG, debugValue); } if (handlerSpan != null && handlerSpan.getResourceNamePriority() < ResourceNamePriorities.HTTP_FRAMEWORK_ROUTE) { HTTP_RESOURCE_DECORATOR.withRoute(handlerSpan, method, path, true); - handlerSpan.setTag(ROUTE_OVERWRITE_DEBUG_TAG, debugValue); } } diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/server/RouteHandlerWrapperTest.groovy b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/server/RouteHandlerWrapperTest.groovy index f9c028dca86..135f228e711 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/server/RouteHandlerWrapperTest.groovy +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/server/RouteHandlerWrapperTest.groovy @@ -16,16 +16,14 @@ class RouteHandlerWrapperTest extends InstrumentationSpecification { when: RouteUpdateHelper.updateRoute( - context, "GET", "/items/:id", parentSpan, handlerSpan, "matches") + context, "GET", "/items/:id", parentSpan, handlerSpan) then: 1 * context.get("dd.${Tags.HTTP_ROUTE}") >> null 1 * context.put("dd.${Tags.HTTP_ROUTE}", "/items/:id") 1 * parentSpan.setTag(Tags.HTTP_ROUTE, "/items/:id") - 1 * parentSpan.setTag("dd.debug.vertx.route_overwrite", "matches:->/items/:id") 1 * handlerSpan.getResourceNamePriority() >> Byte.MIN_VALUE 1 * handlerSpan.setTag(Tags.HTTP_ROUTE, "/items/:id") - 1 * handlerSpan.setTag("dd.debug.vertx.route_overwrite", "matches:->/items/:id") 0 * _ } @@ -36,7 +34,7 @@ class RouteHandlerWrapperTest extends InstrumentationSpecification { def handlerSpan = Mock(AgentSpan) when: - RouteUpdateHelper.updateRoute(context, "GET", "/", parentSpan, handlerSpan, "matches") + RouteUpdateHelper.updateRoute(context, "GET", "/", parentSpan, handlerSpan) then: 1 * context.get("dd.${Tags.HTTP_ROUTE}") >> null diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/EndHandlerWrapper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/EndHandlerWrapper.java index ec6246606f8..2db24f42e09 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/EndHandlerWrapper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/EndHandlerWrapper.java @@ -1,8 +1,6 @@ package datadog.trace.instrumentation.vertx_4_0.server; import static datadog.trace.instrumentation.vertx_4_0.server.RouteUpdateHelper.HANDLER_SPAN_CONTEXT_KEY; -import static datadog.trace.instrumentation.vertx_4_0.server.RouteUpdateHelper.PARENT_SPAN_CONTEXT_KEY; -import static datadog.trace.instrumentation.vertx_4_0.server.RouteUpdateHelper.updateRoute; import static datadog.trace.instrumentation.vertx_4_0.server.VertxDecorator.DECORATE; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; @@ -21,28 +19,11 @@ public class EndHandlerWrapper implements Handler { @Override public void handle(final Void event) { AgentSpan span = routingContext.get(HANDLER_SPAN_CONTEXT_KEY); - AgentSpan parentSpan = routingContext.get(PARENT_SPAN_CONTEXT_KEY); try { if (actual != null) { actual.handle(event); } } finally { - if (routingContext.currentRoute() != null) { - final String method = routingContext.request().method().name(); - String path = routingContext.currentRoute().getPath(); - if (path == null) { - path = routingContext.currentRoute().getName(); - } - final String mountPoint = routingContext.mountPoint(); - if (mountPoint != null && path != null) { - final String noBackslashhMountPoint = - mountPoint.endsWith("/") - ? mountPoint.substring(0, mountPoint.lastIndexOf("/")) - : mountPoint; - path = noBackslashhMountPoint + path; - } - updateRoute(routingContext, method, path, parentSpan, span, "end_handler"); - } if (span != null) { DECORATE.onResponse(span, routingContext.response()); span.finish(); diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapper.java index 113a47de585..2a521d87c7a 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteHandlerWrapper.java @@ -80,6 +80,6 @@ private void setRoute(RoutingContext routingContext) { : mountPoint; path = noBackslashhMountPoint + path; } - updateRoute(routingContext, method, path, parentSpan, handlerSpan, "route_handler"); + updateRoute(routingContext, method, path, parentSpan, handlerSpan); } } diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteMatchesAdvice.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteMatchesAdvice.java index 83b051ec507..1a48e8339d3 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteMatchesAdvice.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteMatchesAdvice.java @@ -37,7 +37,7 @@ static void after( : mountPoint; path = noBackslashhMountPoint + path; } - updateRoute(ctx, method, path, parentSpan, handlerSpan, "matches"); + updateRoute(ctx, method, path, parentSpan, handlerSpan); } Map params = ctx.pathParams(); if (params.isEmpty()) { @@ -78,7 +78,7 @@ static void after( : mountPoint; path = noBackslashhMountPoint + path; } - updateRoute(ctx, method, path, parentSpan, handlerSpan, "matches"); + updateRoute(ctx, method, path, parentSpan, handlerSpan); } Map params = ctx.pathParams(); if (params.isEmpty()) { diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteUpdateHelper.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteUpdateHelper.java index f98de2012d1..1e7de06a70f 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteUpdateHelper.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RouteUpdateHelper.java @@ -11,7 +11,6 @@ public final class RouteUpdateHelper { public static final String PARENT_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".parent"; public static final String HANDLER_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".handler"; public static final String ROUTE_CONTEXT_KEY = "dd." + Tags.HTTP_ROUTE; - public static final String ROUTE_OVERWRITE_DEBUG_TAG = "dd.debug.vertx.route_overwrite"; private RouteUpdateHelper() {} @@ -20,27 +19,21 @@ public static void updateRoute( final String method, final String path, final AgentSpan parentSpan, - final AgentSpan handlerSpan, - final String source) { + final AgentSpan handlerSpan) { if (method == null || path == null) { return; } - final String previousRoute = routingContext.get(ROUTE_CONTEXT_KEY); if (!shouldUpdateRoute(routingContext, parentSpan, handlerSpan, path)) { return; } routingContext.put(ROUTE_CONTEXT_KEY, path); - final String previous = previousRoute == null ? "" : previousRoute; - final String debugValue = source + ":" + previous + "->" + path; if (parentSpan != null) { HTTP_RESOURCE_DECORATOR.withRoute(parentSpan, method, path, true); - parentSpan.setTag(ROUTE_OVERWRITE_DEBUG_TAG, debugValue); } if (handlerSpan != null && handlerSpan.getResourceNamePriority() < ResourceNamePriorities.HTTP_FRAMEWORK_ROUTE) { HTTP_RESOURCE_DECORATOR.withRoute(handlerSpan, method, path, true); - handlerSpan.setTag(ROUTE_OVERWRITE_DEBUG_TAG, debugValue); } } diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/server/RouteHandlerWrapperTest.groovy b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/server/RouteHandlerWrapperTest.groovy index d919d5be3e8..7c1126eacdd 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/server/RouteHandlerWrapperTest.groovy +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/server/RouteHandlerWrapperTest.groovy @@ -16,16 +16,14 @@ class RouteHandlerWrapperTest extends InstrumentationSpecification { when: RouteUpdateHelper.updateRoute( - context, "GET", "/items/:id", parentSpan, handlerSpan, "matches") + context, "GET", "/items/:id", parentSpan, handlerSpan) then: 1 * context.get("dd.${Tags.HTTP_ROUTE}") >> null 1 * context.put("dd.${Tags.HTTP_ROUTE}", "/items/:id") 1 * parentSpan.setTag(Tags.HTTP_ROUTE, "/items/:id") - 1 * parentSpan.setTag("dd.debug.vertx.route_overwrite", "matches:->/items/:id") 1 * handlerSpan.getResourceNamePriority() >> Byte.MIN_VALUE 1 * handlerSpan.setTag(Tags.HTTP_ROUTE, "/items/:id") - 1 * handlerSpan.setTag("dd.debug.vertx.route_overwrite", "matches:->/items/:id") 0 * _ } @@ -36,7 +34,7 @@ class RouteHandlerWrapperTest extends InstrumentationSpecification { def handlerSpan = Mock(AgentSpan) when: - RouteUpdateHelper.updateRoute(context, "GET", "/", parentSpan, handlerSpan, "matches") + RouteUpdateHelper.updateRoute(context, "GET", "/", parentSpan, handlerSpan) then: 1 * context.get("dd.${Tags.HTTP_ROUTE}") >> null