From db61f58eaf6223fff8927532982ccd95d4a2412a Mon Sep 17 00:00:00 2001 From: "alejandro.gonzalez" Date: Fri, 20 Jun 2025 09:05:10 +0200 Subject: [PATCH 1/7] Jersey support --- .../bytebuddy/matcher/ignored_class_name.trie | 2 + .../MessageBodyWriterInstrumentation.java | 92 ++++++++++++++++++ .../jax-rs-annotations-2/build.gradle | 6 ++ .../MessageBodyWriterInstrumentation.java | 97 +++++++++++++++++++ .../instrumentation/jersey/build.gradle | 2 + .../jersey2/ClassToConvertBodyTo.groovy | 7 ++ .../jersey2/Jersey2JettyTest.groovy | 5 + .../jersey2/ServiceResource.groovy | 11 ++- .../jersey3/ClassToConvertBodyTo.groovy | 7 ++ .../jersey3/Jersey3JettyTest.groovy | 5 + .../jersey3/ServiceResource.groovy | 10 +- dd-smoke-tests/jersey-2/build.gradle | 1 + .../main/java/com/restserver/Resource.java | 14 +++ .../smoketest/Jersey2AppsecSmokeTest.groovy | 80 +++++++++++++++ dd-smoke-tests/jersey-3/build.gradle | 2 + .../src/main/java/smoketest/MainApp.java | 3 + .../src/main/java/smoketest/Resource.java | 14 +++ .../src/main/java/smoketest/TestEntity.java | 15 +++ .../smoketest/Jersey3AppsecSmokeTest.groovy | 76 +++++++++++++++ .../datadog/smoketest/Jersey3SmokeTest.groovy | 2 - 20 files changed, 443 insertions(+), 8 deletions(-) create mode 100644 dd-java-agent/instrumentation/jakarta-rs-annotations-3/src/main/java/datadog/trace/instrumentation/jakarta3/MessageBodyWriterInstrumentation.java create mode 100644 dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/MessageBodyWriterInstrumentation.java create mode 100644 dd-smoke-tests/jersey-2/src/test/groovy/datadog/smoketest/Jersey2AppsecSmokeTest.groovy create mode 100644 dd-smoke-tests/jersey-3/src/main/java/smoketest/TestEntity.java create mode 100644 dd-smoke-tests/jersey-3/src/test/groovy/datadog/smoketest/Jersey3AppsecSmokeTest.groovy diff --git a/dd-java-agent/agent-tooling/src/main/resources/datadog/trace/agent/tooling/bytebuddy/matcher/ignored_class_name.trie b/dd-java-agent/agent-tooling/src/main/resources/datadog/trace/agent/tooling/bytebuddy/matcher/ignored_class_name.trie index 95b54a47715..18a88747eec 100644 --- a/dd-java-agent/agent-tooling/src/main/resources/datadog/trace/agent/tooling/bytebuddy/matcher/ignored_class_name.trie +++ b/dd-java-agent/agent-tooling/src/main/resources/datadog/trace/agent/tooling/bytebuddy/matcher/ignored_class_name.trie @@ -190,6 +190,8 @@ 0 com.fasterxml.jackson.databind.util.TokenBuffer$Parser 0 com.fasterxml.jackson.databind.ObjectMapper 0 com.fasterxml.jackson.module.afterburner.util.MyClassLoader +# Included for API Security response schema collection +0 com.fasterxml.jackson.jaxrs.* 2 com.github.mustachejava.* 2 com.google.api.* 0 com.google.api.client.http.HttpRequest diff --git a/dd-java-agent/instrumentation/jakarta-rs-annotations-3/src/main/java/datadog/trace/instrumentation/jakarta3/MessageBodyWriterInstrumentation.java b/dd-java-agent/instrumentation/jakarta-rs-annotations-3/src/main/java/datadog/trace/instrumentation/jakarta3/MessageBodyWriterInstrumentation.java new file mode 100644 index 00000000000..09c016d8c3a --- /dev/null +++ b/dd-java-agent/instrumentation/jakarta-rs-annotations-3/src/main/java/datadog/trace/instrumentation/jakarta3/MessageBodyWriterInstrumentation.java @@ -0,0 +1,92 @@ +package datadog.trace.instrumentation.jakarta3; + +import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.implementsInterface; +import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; +import static datadog.trace.api.gateway.Events.EVENTS; +import static net.bytebuddy.matcher.ElementMatchers.takesArguments; + +import com.google.auto.service.AutoService; +import datadog.appsec.api.blocking.BlockingException; +import datadog.trace.advice.ActiveRequestContext; +import datadog.trace.advice.RequiresRequestContext; +import datadog.trace.agent.tooling.Instrumenter; +import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.api.gateway.BlockResponseFunction; +import datadog.trace.api.gateway.CallbackProvider; +import datadog.trace.api.gateway.Flow; +import datadog.trace.api.gateway.RequestContext; +import datadog.trace.api.gateway.RequestContextSlot; +import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import jakarta.ws.rs.core.MediaType; +import java.util.function.BiFunction; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +@AutoService(InstrumenterModule.class) +public class MessageBodyWriterInstrumentation extends InstrumenterModule.AppSec + implements Instrumenter.ForTypeHierarchy, Instrumenter.HasMethodAdvice { + + public MessageBodyWriterInstrumentation() { + super("jakarta-rs"); + } + + @Override + public String hierarchyMarkerType() { + return "jakarta.ws.rs.ext.MessageBodyWriter"; + } + + @Override + public ElementMatcher hierarchyMatcher() { + return implementsInterface(named(hierarchyMarkerType())); + } + + @Override + public void methodAdvice(MethodTransformer transformer) { + transformer.applyAdvice( + named("writeTo").and(takesArguments(7)), getClass().getName() + "$MessageBodyWriterAdvice"); + } + + @RequiresRequestContext(RequestContextSlot.APPSEC) + public static class MessageBodyWriterAdvice { + @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) + static void after( + @Advice.Argument(0) Object entity, + @Advice.Argument(4) MediaType mediaType, + @ActiveRequestContext RequestContext reqCtx, + @Advice.Thrown Throwable t) { + if (t != null) { + return; + } + + // TODO check if this works or is better to use JSON MediaType + if (!MediaType.APPLICATION_JSON_TYPE.isCompatible(mediaType)) { + return; + } + + CallbackProvider cbp = AgentTracer.get().getCallbackProvider(RequestContextSlot.APPSEC); + BiFunction> callback = + cbp.getCallback(EVENTS.responseBody()); + if (callback == null) { + return; + } + + Flow flow = callback.apply(reqCtx, entity); + Flow.Action action = flow.getAction(); + if (action instanceof Flow.Action.RequestBlockingAction) { + BlockResponseFunction blockResponseFunction = reqCtx.getBlockResponseFunction(); + if (blockResponseFunction == null) { + return; + } + Flow.Action.RequestBlockingAction rba = (Flow.Action.RequestBlockingAction) action; + blockResponseFunction.tryCommitBlockingResponse( + reqCtx.getTraceSegment(), + rba.getStatusCode(), + rba.getBlockingContentType(), + rba.getExtraHeaders()); + + throw new BlockingException("Blocked request (for MessageBodyWriter)"); + } + } + } +} diff --git a/dd-java-agent/instrumentation/jax-rs-annotations-2/build.gradle b/dd-java-agent/instrumentation/jax-rs-annotations-2/build.gradle index 5b04967c113..50c9a86c164 100644 --- a/dd-java-agent/instrumentation/jax-rs-annotations-2/build.gradle +++ b/dd-java-agent/instrumentation/jax-rs-annotations-2/build.gradle @@ -10,6 +10,12 @@ muzzle { module = "javax.ws.rs-api" versions = "[,]" } + pass { + group = "javax.ws.rs" + module = "javax.ws.rs-api" + name = 'javax-message-body-writer' + versions = "[,]" + } } apply from: "$rootDir/gradle/java.gradle" diff --git a/dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/MessageBodyWriterInstrumentation.java b/dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/MessageBodyWriterInstrumentation.java new file mode 100644 index 00000000000..e72631feadf --- /dev/null +++ b/dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/MessageBodyWriterInstrumentation.java @@ -0,0 +1,97 @@ +package datadog.trace.instrumentation.jaxrs2; + +import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.implementsInterface; +import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; +import static datadog.trace.api.gateway.Events.EVENTS; +import static net.bytebuddy.matcher.ElementMatchers.takesArguments; + +import com.google.auto.service.AutoService; +import datadog.appsec.api.blocking.BlockingException; +import datadog.trace.advice.ActiveRequestContext; +import datadog.trace.advice.RequiresRequestContext; +import datadog.trace.agent.tooling.Instrumenter; +import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.api.gateway.BlockResponseFunction; +import datadog.trace.api.gateway.CallbackProvider; +import datadog.trace.api.gateway.Flow; +import datadog.trace.api.gateway.RequestContext; +import datadog.trace.api.gateway.RequestContextSlot; +import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import java.util.function.BiFunction; +import javax.ws.rs.core.MediaType; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +@AutoService(InstrumenterModule.class) +public class MessageBodyWriterInstrumentation extends InstrumenterModule.AppSec + implements Instrumenter.ForTypeHierarchy, Instrumenter.HasMethodAdvice { + + public MessageBodyWriterInstrumentation() { + super("jax-rs"); + } + + @Override + public String muzzleDirective() { + return "javax-message-body-writer"; + } + + @Override + public String hierarchyMarkerType() { + return "javax.ws.rs.ext.MessageBodyWriter"; + } + + @Override + public ElementMatcher hierarchyMatcher() { + return implementsInterface(named(hierarchyMarkerType())); + } + + @Override + public void methodAdvice(MethodTransformer transformer) { + transformer.applyAdvice( + named("writeTo").and(takesArguments(7)), getClass().getName() + "$MessageBodyWriterAdvice"); + } + + @RequiresRequestContext(RequestContextSlot.APPSEC) + public static class MessageBodyWriterAdvice { + @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) + static void after( + @Advice.Argument(0) Object entity, + @Advice.Argument(4) MediaType mediaType, + @ActiveRequestContext RequestContext reqCtx, + @Advice.Thrown Throwable t) { + if (t != null) { + return; + } + + // TODO check if this works or is better to use JSON MediaType + if (!MediaType.APPLICATION_JSON_TYPE.isCompatible(mediaType)) { + return; + } + + CallbackProvider cbp = AgentTracer.get().getCallbackProvider(RequestContextSlot.APPSEC); + BiFunction> callback = + cbp.getCallback(EVENTS.responseBody()); + if (callback == null) { + return; + } + + Flow flow = callback.apply(reqCtx, entity); + Flow.Action action = flow.getAction(); + if (action instanceof Flow.Action.RequestBlockingAction) { + BlockResponseFunction blockResponseFunction = reqCtx.getBlockResponseFunction(); + if (blockResponseFunction == null) { + return; + } + Flow.Action.RequestBlockingAction rba = (Flow.Action.RequestBlockingAction) action; + blockResponseFunction.tryCommitBlockingResponse( + reqCtx.getTraceSegment(), + rba.getStatusCode(), + rba.getBlockingContentType(), + rba.getExtraHeaders()); + + throw new BlockingException("Blocked request (for MessageBodyWriter)"); + } + } + } +} diff --git a/dd-java-agent/instrumentation/jersey/build.gradle b/dd-java-agent/instrumentation/jersey/build.gradle index 4ba678ee51f..6994d611389 100644 --- a/dd-java-agent/instrumentation/jersey/build.gradle +++ b/dd-java-agent/instrumentation/jersey/build.gradle @@ -56,6 +56,7 @@ dependencies { jersey2JettyTestRuntimeOnly group: 'javax.xml.bind', name: 'jaxb-api', version: '2.2.3' jersey2JettyTestRuntimeOnly project(':dd-java-agent:instrumentation:jetty-9') jersey2JettyTestRuntimeOnly project(':dd-java-agent:instrumentation:jersey-2-appsec') + jersey2JettyTestRuntimeOnly project(':dd-java-agent:instrumentation:jax-rs-annotations-2') jersey3JettyTestImplementation project(':dd-java-agent:testing'), { exclude group: 'org.eclipse.jetty', module: 'jetty-server' @@ -72,6 +73,7 @@ dependencies { jersey3JettyTestRuntimeOnly project(':dd-java-agent:instrumentation:jetty-11') jersey3JettyTestRuntimeOnly project(':dd-java-agent:instrumentation:jersey-2-appsec') jersey3JettyTestRuntimeOnly project(':dd-java-agent:instrumentation:jersey-3-appsec') + jersey3JettyTestRuntimeOnly project(':dd-java-agent:instrumentation:jakarta-rs-annotations-3') } configurations.getByName('jersey3JettyTestRuntimeClasspath').resolutionStrategy { diff --git a/dd-java-agent/instrumentation/jersey/src/jersey2JettyTest/groovy/datadog/trace/instrumentation/jersey2/ClassToConvertBodyTo.groovy b/dd-java-agent/instrumentation/jersey/src/jersey2JettyTest/groovy/datadog/trace/instrumentation/jersey2/ClassToConvertBodyTo.groovy index b9241a2daa2..03770bb3642 100644 --- a/dd-java-agent/instrumentation/jersey/src/jersey2JettyTest/groovy/datadog/trace/instrumentation/jersey2/ClassToConvertBodyTo.groovy +++ b/dd-java-agent/instrumentation/jersey/src/jersey2JettyTest/groovy/datadog/trace/instrumentation/jersey2/ClassToConvertBodyTo.groovy @@ -1,5 +1,12 @@ package datadog.trace.instrumentation.jersey2 +import groovy.json.JsonBuilder + class ClassToConvertBodyTo { String a + + @Override + String toString() { + new JsonBuilder([a: a]).toString() + } } diff --git a/dd-java-agent/instrumentation/jersey/src/jersey2JettyTest/groovy/datadog/trace/instrumentation/jersey2/Jersey2JettyTest.groovy b/dd-java-agent/instrumentation/jersey/src/jersey2JettyTest/groovy/datadog/trace/instrumentation/jersey2/Jersey2JettyTest.groovy index a1d8873c63b..3fa5a4672ad 100644 --- a/dd-java-agent/instrumentation/jersey/src/jersey2JettyTest/groovy/datadog/trace/instrumentation/jersey2/Jersey2JettyTest.groovy +++ b/dd-java-agent/instrumentation/jersey/src/jersey2JettyTest/groovy/datadog/trace/instrumentation/jersey2/Jersey2JettyTest.groovy @@ -9,6 +9,11 @@ import javax.ws.rs.ext.ExceptionMapper class Jersey2JettyTest extends HttpServerTest { + @Override + boolean testResponseBodyJson() { + return true + } + @Override HttpServer server() { new JettyServer() diff --git a/dd-java-agent/instrumentation/jersey/src/jersey2JettyTest/groovy/datadog/trace/instrumentation/jersey2/ServiceResource.groovy b/dd-java-agent/instrumentation/jersey/src/jersey2JettyTest/groovy/datadog/trace/instrumentation/jersey2/ServiceResource.groovy index 3d8aa7acebf..943361bc13a 100644 --- a/dd-java-agent/instrumentation/jersey/src/jersey2JettyTest/groovy/datadog/trace/instrumentation/jersey2/ServiceResource.groovy +++ b/dd-java-agent/instrumentation/jersey/src/jersey2JettyTest/groovy/datadog/trace/instrumentation/jersey2/ServiceResource.groovy @@ -10,6 +10,7 @@ import javax.ws.rs.HeaderParam import javax.ws.rs.POST import javax.ws.rs.Path import javax.ws.rs.PathParam +import javax.ws.rs.Produces import javax.ws.rs.QueryParam import javax.ws.rs.core.MediaType import javax.ws.rs.core.Response @@ -87,10 +88,14 @@ class ServiceResource { @POST @Path("body-json") + @Produces(MediaType.APPLICATION_JSON) Response bodyJson(ClassToConvertBodyTo obj) { - controller(BODY_JSON) { - Response.status(BODY_JSON.status).entity("""{"a":"${obj.a}"}""" as String).build() - } + return controller(BODY_JSON, () -> { + Response response = Response.status(BODY_JSON.status) + .entity(obj) + .build() + return response + }) } @GET diff --git a/dd-java-agent/instrumentation/jersey/src/jersey3JettyTest/groovy/datadog/trace/instrumentation/jersey3/ClassToConvertBodyTo.groovy b/dd-java-agent/instrumentation/jersey/src/jersey3JettyTest/groovy/datadog/trace/instrumentation/jersey3/ClassToConvertBodyTo.groovy index 43f6f153f71..862045cb5d5 100644 --- a/dd-java-agent/instrumentation/jersey/src/jersey3JettyTest/groovy/datadog/trace/instrumentation/jersey3/ClassToConvertBodyTo.groovy +++ b/dd-java-agent/instrumentation/jersey/src/jersey3JettyTest/groovy/datadog/trace/instrumentation/jersey3/ClassToConvertBodyTo.groovy @@ -1,5 +1,12 @@ package datadog.trace.instrumentation.jersey3 +import groovy.json.JsonBuilder + class ClassToConvertBodyTo { String a + + @Override + String toString() { + new JsonBuilder([a: a]).toString() + } } diff --git a/dd-java-agent/instrumentation/jersey/src/jersey3JettyTest/groovy/datadog/trace/instrumentation/jersey3/Jersey3JettyTest.groovy b/dd-java-agent/instrumentation/jersey/src/jersey3JettyTest/groovy/datadog/trace/instrumentation/jersey3/Jersey3JettyTest.groovy index 16a83a380a0..b8076813660 100644 --- a/dd-java-agent/instrumentation/jersey/src/jersey3JettyTest/groovy/datadog/trace/instrumentation/jersey3/Jersey3JettyTest.groovy +++ b/dd-java-agent/instrumentation/jersey/src/jersey3JettyTest/groovy/datadog/trace/instrumentation/jersey3/Jersey3JettyTest.groovy @@ -8,6 +8,11 @@ import jakarta.ws.rs.ext.ExceptionMapper class Jersey3JettyTest extends HttpServerTest { + @Override + boolean testResponseBodyJson() { + return true + } + @Override HttpServer server() { new JettyServer() diff --git a/dd-java-agent/instrumentation/jersey/src/jersey3JettyTest/groovy/datadog/trace/instrumentation/jersey3/ServiceResource.groovy b/dd-java-agent/instrumentation/jersey/src/jersey3JettyTest/groovy/datadog/trace/instrumentation/jersey3/ServiceResource.groovy index 07ce69be498..74dcdc7ed1a 100644 --- a/dd-java-agent/instrumentation/jersey/src/jersey3JettyTest/groovy/datadog/trace/instrumentation/jersey3/ServiceResource.groovy +++ b/dd-java-agent/instrumentation/jersey/src/jersey3JettyTest/groovy/datadog/trace/instrumentation/jersey3/ServiceResource.groovy @@ -1,6 +1,7 @@ package datadog.trace.instrumentation.jersey3 import datadog.appsec.api.blocking.Blocking +import jakarta.ws.rs.Produces import org.glassfish.jersey.media.multipart.FormDataParam import jakarta.ws.rs.Consumes @@ -87,10 +88,13 @@ class ServiceResource { @POST @Path("body-json") + @Produces(MediaType.APPLICATION_JSON) Response bodyJson(ClassToConvertBodyTo obj) { - controller(BODY_JSON) { - Response.status(BODY_JSON.status).entity("""{"a":"${obj.a}"}""" as String).build() - } + controller(BODY_JSON, () -> + Response.status(BODY_JSON.status) + .entity(obj) + .build() + ) } @GET diff --git a/dd-smoke-tests/jersey-2/build.gradle b/dd-smoke-tests/jersey-2/build.gradle index 26bc210173c..40ad77f276d 100644 --- a/dd-smoke-tests/jersey-2/build.gradle +++ b/dd-smoke-tests/jersey-2/build.gradle @@ -20,6 +20,7 @@ dependencies { implementation group: 'javax.xml', name: 'jaxb-api', version:'2.1' testImplementation project(':dd-smoke-tests') testImplementation(testFixtures(project(":dd-smoke-tests:iast-util"))) + testImplementation project(':dd-smoke-tests:appsec') } tasks.withType(Test).configureEach { diff --git a/dd-smoke-tests/jersey-2/src/main/java/com/restserver/Resource.java b/dd-smoke-tests/jersey-2/src/main/java/com/restserver/Resource.java index 246da86eca7..5119ddfb0fd 100644 --- a/dd-smoke-tests/jersey-2/src/main/java/com/restserver/Resource.java +++ b/dd-smoke-tests/jersey-2/src/main/java/com/restserver/Resource.java @@ -139,4 +139,18 @@ public Response responseLocation(@QueryParam("param") String param) throws URISy public Response getCookie() throws SQLException { return Response.ok().cookie(new NewCookie("user-id", "7")).build(); } + + @Path("/api_security/response") + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response bodyJson() { + TestEntity testEntity = new TestEntity("testing", "test"); + return Response.ok().entity(testEntity).build(); + } + + @GET + @Path("/api_security/sampling/{i}") + public Response apiSecuritySamplingWithStatus(@PathParam("i") int i) { + return Response.status(i).header("content-type", "text/plain").entity("Hello!\n").build(); + } } diff --git a/dd-smoke-tests/jersey-2/src/test/groovy/datadog/smoketest/Jersey2AppsecSmokeTest.groovy b/dd-smoke-tests/jersey-2/src/test/groovy/datadog/smoketest/Jersey2AppsecSmokeTest.groovy new file mode 100644 index 00000000000..00138eaf24b --- /dev/null +++ b/dd-smoke-tests/jersey-2/src/test/groovy/datadog/smoketest/Jersey2AppsecSmokeTest.groovy @@ -0,0 +1,80 @@ +package datadog.smoketest + +import datadog.smoketest.appsec.AbstractAppSecServerSmokeTest +import datadog.trace.api.Platform +import okhttp3.Request +import okhttp3.Response + +class Jersey2AppsecSmokeTest extends AbstractAppSecServerSmokeTest{ + + @Override + ProcessBuilder createProcessBuilder() { + String jarPath = System.getProperty('datadog.smoketest.jersey2.jar.path') + + List command = [] + command.add(javaPath()) + command.addAll(defaultJavaProperties) + command.addAll(defaultAppSecProperties) + command.add('-Ddd.integration.grizzly.enabled=true') + if (Platform.isJavaVersionAtLeast(17)) { + command.addAll((String[]) ['--add-opens', 'java.base/java.lang=ALL-UNNAMED']) + } + command.addAll(['-jar', jarPath, Integer.toString(httpPort)]) + ProcessBuilder processBuilder = new ProcessBuilder(command) + processBuilder.directory(new File(buildDirectory)) + return processBuilder + } + + void 'API Security samples only one request per endpoint'() { + given: + def url = "http://localhost:${httpPort}/hello/api_security/sampling/200?test=value" + def request = new Request.Builder() + .url(url) + .addHeader('X-My-Header', "value") + .get() + .build() + + when: + List responses = (1..3).collect { + client.newCall(request).execute() + } + + then: + responses.each { + assert it.code() == 200 + } + waitForTraceCount(3) + def spans = rootSpans.toList().toSorted { it.span.duration } + spans.size() == 3 + def sampledSpans = spans.findAll { + it.meta.keySet().any { + it.startsWith('_dd.appsec.s.req.') + } + } + sampledSpans.size() == 1 + def span = sampledSpans[0] + span.meta.containsKey('_dd.appsec.s.req.query') + span.meta.containsKey('_dd.appsec.s.req.params') + span.meta.containsKey('_dd.appsec.s.req.headers') + } + + + void 'test response schema extraction'() { + given: + def url = "http://localhost:${httpPort}/hello/api_security/response" + def request = new Request.Builder() + .url(url) + .get() + .build() + + when: + final response = client.newCall(request).execute() + waitForTraceCount(1) + + then: + response.code() == 200 + def span = rootSpans.first() + span.meta.containsKey('_dd.appsec.s.res.headers') + span.meta.containsKey('_dd.appsec.s.res.body') + } +} diff --git a/dd-smoke-tests/jersey-3/build.gradle b/dd-smoke-tests/jersey-3/build.gradle index 72f34087434..e5ca3613f20 100644 --- a/dd-smoke-tests/jersey-3/build.gradle +++ b/dd-smoke-tests/jersey-3/build.gradle @@ -14,11 +14,13 @@ jar { dependencies { implementation group: 'org.glassfish.jersey.containers', name: 'jersey-container-grizzly2-http', version:'3.0.2' + implementation 'org.glassfish.jersey.media:jersey-media-json-jackson:3.0.2' implementation group: 'org.glassfish.jersey.inject', name: 'jersey-hk2', version:'3.0.2' implementation group: 'org.glassfish.hk2', name: 'hk2-metadata-generator', version:'3.0.2' implementation group: 'jakarta.activation', name: 'jakarta.activation-api', version:'2.0.1' testImplementation project(':dd-smoke-tests') testImplementation(testFixtures(project(":dd-smoke-tests:iast-util"))) + testImplementation project(':dd-smoke-tests:appsec') } tasks.withType(Test).configureEach { diff --git a/dd-smoke-tests/jersey-3/src/main/java/smoketest/MainApp.java b/dd-smoke-tests/jersey-3/src/main/java/smoketest/MainApp.java index cadbcd20b47..ba2f6eced0d 100644 --- a/dd-smoke-tests/jersey-3/src/main/java/smoketest/MainApp.java +++ b/dd-smoke-tests/jersey-3/src/main/java/smoketest/MainApp.java @@ -7,6 +7,7 @@ import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; import org.glassfish.jersey.internal.inject.ParamConverters.StringConstructor; +import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; import smoketest.config.AutoScanFeature; @@ -29,6 +30,8 @@ public static HttpServer startServer(String httpPort) { // enable auto scan @Contract and @Service config.register(AutoScanFeature.class); + config.register(JacksonFeature.class); + LOGGER.info("Starting Server........"); URI uri = URI.create(BASE_URI + httpPort + "/"); diff --git a/dd-smoke-tests/jersey-3/src/main/java/smoketest/Resource.java b/dd-smoke-tests/jersey-3/src/main/java/smoketest/Resource.java index b872edc6849..9c2e376c333 100644 --- a/dd-smoke-tests/jersey-3/src/main/java/smoketest/Resource.java +++ b/dd-smoke-tests/jersey-3/src/main/java/smoketest/Resource.java @@ -129,4 +129,18 @@ public Response responseLocation(@QueryParam("param") String param) throws URISy public Response getCookie() throws SQLException { return Response.ok().cookie(new NewCookie("user-id", "7")).build(); } + + @Path("/api_security/response") + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response bodyJson() { + TestEntity testEntity = new TestEntity("testing", "test"); + return Response.ok().entity(testEntity).build(); + } + + @GET + @Path("/api_security/sampling/{i}") + public Response apiSecuritySamplingWithStatus(@PathParam("i") int i) { + return Response.status(i).header("content-type", "text/plain").entity("Hello!\n").build(); + } } diff --git a/dd-smoke-tests/jersey-3/src/main/java/smoketest/TestEntity.java b/dd-smoke-tests/jersey-3/src/main/java/smoketest/TestEntity.java new file mode 100644 index 00000000000..18d6693760b --- /dev/null +++ b/dd-smoke-tests/jersey-3/src/main/java/smoketest/TestEntity.java @@ -0,0 +1,15 @@ +package smoketest; + +public class TestEntity { + public String param1; + public String param2; + + public TestEntity() { + super(); + } + + public TestEntity(String param1, String param2) { + this.param1 = param1; + this.param2 = param2; + } +} diff --git a/dd-smoke-tests/jersey-3/src/test/groovy/datadog/smoketest/Jersey3AppsecSmokeTest.groovy b/dd-smoke-tests/jersey-3/src/test/groovy/datadog/smoketest/Jersey3AppsecSmokeTest.groovy new file mode 100644 index 00000000000..dc8b3bfceea --- /dev/null +++ b/dd-smoke-tests/jersey-3/src/test/groovy/datadog/smoketest/Jersey3AppsecSmokeTest.groovy @@ -0,0 +1,76 @@ +package datadog.smoketest + +import datadog.smoketest.appsec.AbstractAppSecServerSmokeTest +import okhttp3.Request +import okhttp3.Response + +class Jersey3AppsecSmokeTest extends AbstractAppSecServerSmokeTest { + + @Override + ProcessBuilder createProcessBuilder() { + String jarPath = System.getProperty('datadog.smoketest.jersey3.jar.path') + + List command = [] + command.add(javaPath()) + command.addAll(defaultJavaProperties) + command.addAll(defaultAppSecProperties) + command.add('-Ddd.integration.grizzly.enabled=true') + command.addAll(['-jar', jarPath, Integer.toString(httpPort)]) + ProcessBuilder processBuilder = new ProcessBuilder(command) + processBuilder.directory(new File(buildDirectory)) + return processBuilder + } + + void 'API Security samples only one request per endpoint'() { + given: + def url = "http://localhost:${httpPort}/hello/api_security/sampling/200?test=value" + def request = new Request.Builder() + .url(url) + .addHeader('X-My-Header', "value") + .get() + .build() + + when: + List responses = (1..3).collect { + client.newCall(request).execute() + } + + then: + responses.each { + assert it.code() == 200 + } + waitForTraceCount(3) + def spans = rootSpans.toList().toSorted { it.span.duration } + spans.size() == 3 + def sampledSpans = spans.findAll { + it.meta.keySet().any { + it.startsWith('_dd.appsec.s.req.') + } + } + sampledSpans.size() == 1 + def span = sampledSpans[0] + span.meta.containsKey('_dd.appsec.s.req.query') + span.meta.containsKey('_dd.appsec.s.req.params') + span.meta.containsKey('_dd.appsec.s.req.headers') + } + + + void 'test response schema extraction'() { + given: + def url = "http://localhost:${httpPort}/hello/api_security/response" + def request = new Request.Builder() + .url(url) + .get() + .build() + + when: + final response = client.newCall(request).execute() + waitForTraceCount(1) + + then: + response.code() == 200 + def span = rootSpans.first() + span.meta.containsKey('_dd.appsec.s.res.headers') + span.meta.containsKey('_dd.appsec.s.res.body') + } +} diff --git a/dd-smoke-tests/jersey-3/src/test/groovy/datadog/smoketest/Jersey3SmokeTest.groovy b/dd-smoke-tests/jersey-3/src/test/groovy/datadog/smoketest/Jersey3SmokeTest.groovy index 4ee050d62f4..62b6641fbf6 100644 --- a/dd-smoke-tests/jersey-3/src/test/groovy/datadog/smoketest/Jersey3SmokeTest.groovy +++ b/dd-smoke-tests/jersey-3/src/test/groovy/datadog/smoketest/Jersey3SmokeTest.groovy @@ -17,8 +17,6 @@ class Jersey3SmokeTest extends AbstractJerseySmokeTest { command.addAll(defaultJavaProperties) command.addAll(iastJvmOpts()) command.add(withSystemProperty('integration.grizzly.enabled', true)) - //command.add("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000") - //command.add("-Xdebug") command.addAll(['-jar', jarPath, Integer.toString(httpPort)]) ProcessBuilder processBuilder = new ProcessBuilder(command) processBuilder.directory(new File(buildDirectory)) From 3cd9bcbba0d8c07930ac01f1ba69a54246e36599 Mon Sep 17 00:00:00 2001 From: "alejandro.gonzalez" Date: Fri, 27 Jun 2025 07:40:10 +0200 Subject: [PATCH 2/7] WIP --- .../trace/agent/test/utils/OkHttpUtils.java | 2 +- .../main/java/com/restserver/RequestBody.java | 45 +++++++++++++++++++ .../main/java/com/restserver/Resource.java | 8 ++-- .../smoketest/Jersey2AppsecSmokeTest.groovy | 21 ++++++++- .../src/main/java/smoketest/RequestBody.java | 45 +++++++++++++++++++ .../src/main/java/smoketest/Resource.java | 9 ++-- .../smoketest/Jersey3AppsecSmokeTest.groovy | 21 ++++++++- 7 files changed, 140 insertions(+), 11 deletions(-) create mode 100644 dd-smoke-tests/jersey-2/src/main/java/com/restserver/RequestBody.java create mode 100644 dd-smoke-tests/jersey-3/src/main/java/smoketest/RequestBody.java diff --git a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/utils/OkHttpUtils.java b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/utils/OkHttpUtils.java index 361aab3845c..d93ad269cc2 100644 --- a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/utils/OkHttpUtils.java +++ b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/utils/OkHttpUtils.java @@ -52,7 +52,7 @@ public class OkHttpUtils { } public static OkHttpClient.Builder clientBuilder() { - final TimeUnit unit = TimeUnit.MINUTES; + final TimeUnit unit = TimeUnit.HOURS; return new OkHttpClient.Builder() .addInterceptor(EXPECT_CONTINUE_INTERCEPTOR) .addInterceptor(LOGGING_INTERCEPTOR) diff --git a/dd-smoke-tests/jersey-2/src/main/java/com/restserver/RequestBody.java b/dd-smoke-tests/jersey-2/src/main/java/com/restserver/RequestBody.java new file mode 100644 index 00000000000..535cab104cd --- /dev/null +++ b/dd-smoke-tests/jersey-2/src/main/java/com/restserver/RequestBody.java @@ -0,0 +1,45 @@ +package com.restserver; + +import java.util.List; + +public class RequestBody { + private List main; + private Object nullable; + + public List getMain() { + return main; + } + + public void setMain(List main) { + this.main = main; + } + + public Object getNullable() { + return nullable; + } + + public void setNullable(Object nullable) { + this.nullable = nullable; + } + + public static class KeyValue { + private String key; + private Double value; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Double getValue() { + return value; + } + + public void setValue(Double value) { + this.value = value; + } + } +} diff --git a/dd-smoke-tests/jersey-2/src/main/java/com/restserver/Resource.java b/dd-smoke-tests/jersey-2/src/main/java/com/restserver/Resource.java index 5119ddfb0fd..2538b616a34 100644 --- a/dd-smoke-tests/jersey-2/src/main/java/com/restserver/Resource.java +++ b/dd-smoke-tests/jersey-2/src/main/java/com/restserver/Resource.java @@ -141,11 +141,11 @@ public Response getCookie() throws SQLException { } @Path("/api_security/response") - @GET + @POST @Produces(MediaType.APPLICATION_JSON) - public Response bodyJson() { - TestEntity testEntity = new TestEntity("testing", "test"); - return Response.ok().entity(testEntity).build(); + @Consumes(MediaType.APPLICATION_JSON) + public Response bodyJson(RequestBody input) { + return Response.ok(input).build(); } @GET diff --git a/dd-smoke-tests/jersey-2/src/test/groovy/datadog/smoketest/Jersey2AppsecSmokeTest.groovy b/dd-smoke-tests/jersey-2/src/test/groovy/datadog/smoketest/Jersey2AppsecSmokeTest.groovy index 00138eaf24b..ee70d63feb2 100644 --- a/dd-smoke-tests/jersey-2/src/test/groovy/datadog/smoketest/Jersey2AppsecSmokeTest.groovy +++ b/dd-smoke-tests/jersey-2/src/test/groovy/datadog/smoketest/Jersey2AppsecSmokeTest.groovy @@ -1,10 +1,17 @@ package datadog.smoketest import datadog.smoketest.appsec.AbstractAppSecServerSmokeTest +import datadog.trace.agent.test.utils.OkHttpUtils import datadog.trace.api.Platform +import groovy.json.JsonOutput +import groovy.json.JsonSlurper +import okhttp3.MediaType import okhttp3.Request +import okhttp3.RequestBody import okhttp3.Response +import java.util.zip.GZIPInputStream + class Jersey2AppsecSmokeTest extends AbstractAppSecServerSmokeTest{ @Override @@ -62,9 +69,14 @@ class Jersey2AppsecSmokeTest extends AbstractAppSecServerSmokeTest{ void 'test response schema extraction'() { given: def url = "http://localhost:${httpPort}/hello/api_security/response" + def client = OkHttpUtils.clientBuilder().build() + def body = [ + "main" : [["key": "id001", "value": 1345.67], ["value": 1567.89, "key": "id002"]], + "nullable": null, + ] def request = new Request.Builder() .url(url) - .get() + .post(RequestBody.create(MediaType.get('application/json'), JsonOutput.toJson(body))) .build() when: @@ -76,5 +88,12 @@ class Jersey2AppsecSmokeTest extends AbstractAppSecServerSmokeTest{ def span = rootSpans.first() span.meta.containsKey('_dd.appsec.s.res.headers') span.meta.containsKey('_dd.appsec.s.res.body') + final schema = new JsonSlurper().parse(unzip(span.meta.get('_dd.appsec.s.res.body'))) + assert schema == [["main": [[[["key": [8], "value": [16]]]], ["len": 2]], "nullable": [1]]] + } + + private static byte[] unzip(final String text) { + final inflaterStream = new GZIPInputStream(new ByteArrayInputStream(text.decodeBase64())) + return inflaterStream.getBytes() } } diff --git a/dd-smoke-tests/jersey-3/src/main/java/smoketest/RequestBody.java b/dd-smoke-tests/jersey-3/src/main/java/smoketest/RequestBody.java new file mode 100644 index 00000000000..1c1cc183f41 --- /dev/null +++ b/dd-smoke-tests/jersey-3/src/main/java/smoketest/RequestBody.java @@ -0,0 +1,45 @@ +package smoketest; + +import java.util.List; + +public class RequestBody { + private List main; + private Object nullable; + + public List getMain() { + return main; + } + + public void setMain(List main) { + this.main = main; + } + + public Object getNullable() { + return nullable; + } + + public void setNullable(Object nullable) { + this.nullable = nullable; + } + + public static class KeyValue { + private String key; + private Double value; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Double getValue() { + return value; + } + + public void setValue(Double value) { + this.value = value; + } + } +} diff --git a/dd-smoke-tests/jersey-3/src/main/java/smoketest/Resource.java b/dd-smoke-tests/jersey-3/src/main/java/smoketest/Resource.java index 9c2e376c333..9e5d7364ca3 100644 --- a/dd-smoke-tests/jersey-3/src/main/java/smoketest/Resource.java +++ b/dd-smoke-tests/jersey-3/src/main/java/smoketest/Resource.java @@ -1,5 +1,6 @@ package smoketest; +import jakarta.ws.rs.Consumes; import jakarta.ws.rs.CookieParam; import jakarta.ws.rs.FormParam; import jakarta.ws.rs.GET; @@ -131,11 +132,11 @@ public Response getCookie() throws SQLException { } @Path("/api_security/response") - @GET + @POST @Produces(MediaType.APPLICATION_JSON) - public Response bodyJson() { - TestEntity testEntity = new TestEntity("testing", "test"); - return Response.ok().entity(testEntity).build(); + @Consumes(MediaType.APPLICATION_JSON) + public Response bodyJson(RequestBody input) { + return Response.ok(input).build(); } @GET diff --git a/dd-smoke-tests/jersey-3/src/test/groovy/datadog/smoketest/Jersey3AppsecSmokeTest.groovy b/dd-smoke-tests/jersey-3/src/test/groovy/datadog/smoketest/Jersey3AppsecSmokeTest.groovy index dc8b3bfceea..79efd0280b3 100644 --- a/dd-smoke-tests/jersey-3/src/test/groovy/datadog/smoketest/Jersey3AppsecSmokeTest.groovy +++ b/dd-smoke-tests/jersey-3/src/test/groovy/datadog/smoketest/Jersey3AppsecSmokeTest.groovy @@ -1,9 +1,16 @@ package datadog.smoketest import datadog.smoketest.appsec.AbstractAppSecServerSmokeTest +import datadog.trace.agent.test.utils.OkHttpUtils +import groovy.json.JsonOutput +import groovy.json.JsonSlurper +import okhttp3.MediaType import okhttp3.Request +import okhttp3.RequestBody import okhttp3.Response +import java.util.zip.GZIPInputStream + class Jersey3AppsecSmokeTest extends AbstractAppSecServerSmokeTest { @Override @@ -58,9 +65,14 @@ class Jersey3AppsecSmokeTest extends AbstractAppSecServerSmokeTest { void 'test response schema extraction'() { given: def url = "http://localhost:${httpPort}/hello/api_security/response" + def client = OkHttpUtils.clientBuilder().build() + def body = [ + "main" : [["key": "id001", "value": 1345.67], ["value": 1567.89, "key": "id002"]], + "nullable": null, + ] def request = new Request.Builder() .url(url) - .get() + .post(RequestBody.create(MediaType.get('application/json'), JsonOutput.toJson(body))) .build() when: @@ -72,5 +84,12 @@ class Jersey3AppsecSmokeTest extends AbstractAppSecServerSmokeTest { def span = rootSpans.first() span.meta.containsKey('_dd.appsec.s.res.headers') span.meta.containsKey('_dd.appsec.s.res.body') + final schema = new JsonSlurper().parse(unzip(span.meta.get('_dd.appsec.s.res.body'))) + assert schema == [["main": [[[["key": [8], "value": [16]]]], ["len": 2]], "nullable": [1]]] + } + + private static byte[] unzip(final String text) { + final inflaterStream = new GZIPInputStream(new ByteArrayInputStream(text.decodeBase64())) + return inflaterStream.getBytes() } } From fc1a8245c9fb8f10d9c7ffc214be92541b717204 Mon Sep 17 00:00:00 2001 From: "alejandro.gonzalez" Date: Fri, 27 Jun 2025 07:41:00 +0200 Subject: [PATCH 3/7] WIP --- .../main/groovy/datadog/trace/agent/test/utils/OkHttpUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/utils/OkHttpUtils.java b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/utils/OkHttpUtils.java index d93ad269cc2..361aab3845c 100644 --- a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/utils/OkHttpUtils.java +++ b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/utils/OkHttpUtils.java @@ -52,7 +52,7 @@ public class OkHttpUtils { } public static OkHttpClient.Builder clientBuilder() { - final TimeUnit unit = TimeUnit.HOURS; + final TimeUnit unit = TimeUnit.MINUTES; return new OkHttpClient.Builder() .addInterceptor(EXPECT_CONTINUE_INTERCEPTOR) .addInterceptor(LOGGING_INTERCEPTOR) From 51304cdfdd4601bb4d295affa0ede8c08e603208 Mon Sep 17 00:00:00 2001 From: "alejandro.gonzalez" Date: Fri, 27 Jun 2025 07:41:56 +0200 Subject: [PATCH 4/7] WIP --- .../src/main/java/smoketest/TestEntity.java | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 dd-smoke-tests/jersey-3/src/main/java/smoketest/TestEntity.java diff --git a/dd-smoke-tests/jersey-3/src/main/java/smoketest/TestEntity.java b/dd-smoke-tests/jersey-3/src/main/java/smoketest/TestEntity.java deleted file mode 100644 index 18d6693760b..00000000000 --- a/dd-smoke-tests/jersey-3/src/main/java/smoketest/TestEntity.java +++ /dev/null @@ -1,15 +0,0 @@ -package smoketest; - -public class TestEntity { - public String param1; - public String param2; - - public TestEntity() { - super(); - } - - public TestEntity(String param1, String param2) { - this.param1 = param1; - this.param2 = param2; - } -} From caadb19ef1304bf71ab5a223b0956d6a1c13b506 Mon Sep 17 00:00:00 2001 From: "alejandro.gonzalez" Date: Fri, 27 Jun 2025 13:39:35 +0200 Subject: [PATCH 5/7] change to onMethod enter --- .../jakarta3/MessageBodyWriterInstrumentation.java | 4 ++-- .../jaxrs2/MessageBodyWriterInstrumentation.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dd-java-agent/instrumentation/jakarta-rs-annotations-3/src/main/java/datadog/trace/instrumentation/jakarta3/MessageBodyWriterInstrumentation.java b/dd-java-agent/instrumentation/jakarta-rs-annotations-3/src/main/java/datadog/trace/instrumentation/jakarta3/MessageBodyWriterInstrumentation.java index 09c016d8c3a..351baa5302f 100644 --- a/dd-java-agent/instrumentation/jakarta-rs-annotations-3/src/main/java/datadog/trace/instrumentation/jakarta3/MessageBodyWriterInstrumentation.java +++ b/dd-java-agent/instrumentation/jakarta-rs-annotations-3/src/main/java/datadog/trace/instrumentation/jakarta3/MessageBodyWriterInstrumentation.java @@ -49,8 +49,8 @@ public void methodAdvice(MethodTransformer transformer) { @RequiresRequestContext(RequestContextSlot.APPSEC) public static class MessageBodyWriterAdvice { - @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) - static void after( + @Advice.OnMethodEnter(suppress = Throwable.class) + static void before( @Advice.Argument(0) Object entity, @Advice.Argument(4) MediaType mediaType, @ActiveRequestContext RequestContext reqCtx, diff --git a/dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/MessageBodyWriterInstrumentation.java b/dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/MessageBodyWriterInstrumentation.java index e72631feadf..f94766b51c6 100644 --- a/dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/MessageBodyWriterInstrumentation.java +++ b/dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/MessageBodyWriterInstrumentation.java @@ -54,8 +54,8 @@ public void methodAdvice(MethodTransformer transformer) { @RequiresRequestContext(RequestContextSlot.APPSEC) public static class MessageBodyWriterAdvice { - @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) - static void after( + @Advice.OnMethodEnter(suppress = Throwable.class) + static void before( @Advice.Argument(0) Object entity, @Advice.Argument(4) MediaType mediaType, @ActiveRequestContext RequestContext reqCtx, From 741f50a8e4e0c278f474bebf5ce455dd73d7e0f1 Mon Sep 17 00:00:00 2001 From: "alejandro.gonzalez" Date: Fri, 27 Jun 2025 13:49:09 +0200 Subject: [PATCH 6/7] remove todos --- .../jakarta3/MessageBodyWriterInstrumentation.java | 1 - .../instrumentation/jaxrs2/MessageBodyWriterInstrumentation.java | 1 - 2 files changed, 2 deletions(-) diff --git a/dd-java-agent/instrumentation/jakarta-rs-annotations-3/src/main/java/datadog/trace/instrumentation/jakarta3/MessageBodyWriterInstrumentation.java b/dd-java-agent/instrumentation/jakarta-rs-annotations-3/src/main/java/datadog/trace/instrumentation/jakarta3/MessageBodyWriterInstrumentation.java index 351baa5302f..9907884c6e2 100644 --- a/dd-java-agent/instrumentation/jakarta-rs-annotations-3/src/main/java/datadog/trace/instrumentation/jakarta3/MessageBodyWriterInstrumentation.java +++ b/dd-java-agent/instrumentation/jakarta-rs-annotations-3/src/main/java/datadog/trace/instrumentation/jakarta3/MessageBodyWriterInstrumentation.java @@ -59,7 +59,6 @@ static void before( return; } - // TODO check if this works or is better to use JSON MediaType if (!MediaType.APPLICATION_JSON_TYPE.isCompatible(mediaType)) { return; } diff --git a/dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/MessageBodyWriterInstrumentation.java b/dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/MessageBodyWriterInstrumentation.java index f94766b51c6..3e325e895d9 100644 --- a/dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/MessageBodyWriterInstrumentation.java +++ b/dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/MessageBodyWriterInstrumentation.java @@ -64,7 +64,6 @@ static void before( return; } - // TODO check if this works or is better to use JSON MediaType if (!MediaType.APPLICATION_JSON_TYPE.isCompatible(mediaType)) { return; } From 63ac1644d817a86afe711c2639f64b521e53ed5b Mon Sep 17 00:00:00 2001 From: "alejandro.gonzalez" Date: Fri, 27 Jun 2025 14:57:17 +0200 Subject: [PATCH 7/7] fix --- .../jakarta3/MessageBodyWriterInstrumentation.java | 6 +----- .../jaxrs2/MessageBodyWriterInstrumentation.java | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/dd-java-agent/instrumentation/jakarta-rs-annotations-3/src/main/java/datadog/trace/instrumentation/jakarta3/MessageBodyWriterInstrumentation.java b/dd-java-agent/instrumentation/jakarta-rs-annotations-3/src/main/java/datadog/trace/instrumentation/jakarta3/MessageBodyWriterInstrumentation.java index 9907884c6e2..9604b5ceac6 100644 --- a/dd-java-agent/instrumentation/jakarta-rs-annotations-3/src/main/java/datadog/trace/instrumentation/jakarta3/MessageBodyWriterInstrumentation.java +++ b/dd-java-agent/instrumentation/jakarta-rs-annotations-3/src/main/java/datadog/trace/instrumentation/jakarta3/MessageBodyWriterInstrumentation.java @@ -53,11 +53,7 @@ public static class MessageBodyWriterAdvice { static void before( @Advice.Argument(0) Object entity, @Advice.Argument(4) MediaType mediaType, - @ActiveRequestContext RequestContext reqCtx, - @Advice.Thrown Throwable t) { - if (t != null) { - return; - } + @ActiveRequestContext RequestContext reqCtx) { if (!MediaType.APPLICATION_JSON_TYPE.isCompatible(mediaType)) { return; diff --git a/dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/MessageBodyWriterInstrumentation.java b/dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/MessageBodyWriterInstrumentation.java index 3e325e895d9..c546f5fbda3 100644 --- a/dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/MessageBodyWriterInstrumentation.java +++ b/dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/MessageBodyWriterInstrumentation.java @@ -58,11 +58,7 @@ public static class MessageBodyWriterAdvice { static void before( @Advice.Argument(0) Object entity, @Advice.Argument(4) MediaType mediaType, - @ActiveRequestContext RequestContext reqCtx, - @Advice.Thrown Throwable t) { - if (t != null) { - return; - } + @ActiveRequestContext RequestContext reqCtx) { if (!MediaType.APPLICATION_JSON_TYPE.isCompatible(mediaType)) { return;