diff --git a/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/build.gradle b/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/build.gradle index b0c49f3eb4f..a6bde8bce05 100644 --- a/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/build.gradle +++ b/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/build.gradle @@ -1,5 +1,6 @@ plugins { id 'dd-trace-java.module.instrumentation' + id 'dd-trace-java.jmh-conventions' } muzzle { @@ -15,4 +16,6 @@ addTestSuiteForDir('latestDepTest', 'test') dependencies { compileOnly group: 'com.amazonaws', name: 'aws-lambda-java-core', version: '1.2.1' testImplementation group: 'com.amazonaws', name: 'aws-lambda-java-core', version: '1.2.1' + testImplementation project(':utils:test-utils') + testImplementation libs.jackson.databind } diff --git a/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/gradle.lockfile b/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/gradle.lockfile index 4e36b31be18..9b11bd80363 100644 --- a/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/gradle.lockfile +++ b/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/gradle.lockfile @@ -2,69 +2,75 @@ # Manual edits can break the build and are not advised. # This file is expected to be part of source control. # To regenerate this file, run: ./gradlew :dd-java-agent:instrumentation:aws-java:aws-java-lambda-handler-1.2:dependencies --write-locks -cafe.cryptography:curve25519-elisabeth:0.1.0=latestDepTestRuntimeClasspath,testRuntimeClasspath -cafe.cryptography:ed25519-elisabeth:0.1.0=latestDepTestRuntimeClasspath,testRuntimeClasspath -ch.qos.logback:logback-classic:1.2.13=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.2.13=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -com.amazonaws:aws-lambda-java-core:1.2.1=compileClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -com.blogspot.mydailyjava:weak-lock-free:0.17=buildTimeInstrumentationPlugin,compileClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.datadoghq.okhttp3:okhttp:3.12.15=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -com.datadoghq.okio:okio:1.17.6=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -com.datadoghq:dd-instrument-java:0.0.6=buildTimeInstrumentationPlugin,compileClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,muzzleBootstrap,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.datadoghq:dd-javac-plugin-client:0.2.2=buildTimeInstrumentationPlugin,compileClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,muzzleBootstrap,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.datadoghq:java-dogstatsd-client:4.4.5=latestDepTestRuntimeClasspath,testRuntimeClasspath -com.datadoghq:sketches-java:0.8.3=latestDepTestRuntimeClasspath,testRuntimeClasspath +cafe.cryptography:curve25519-elisabeth:0.1.0=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +cafe.cryptography:ed25519-elisabeth:0.1.0=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.2.13=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.2.13=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +com.amazonaws:aws-lambda-java-core:1.2.1=compileClasspath,jmhCompileClasspath,jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +com.blogspot.mydailyjava:weak-lock-free:0.17=buildTimeInstrumentationPlugin,compileClasspath,jmhCompileClasspath,jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.datadoghq.okhttp3:okhttp:3.12.15=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +com.datadoghq.okio:okio:1.17.6=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +com.datadoghq:dd-instrument-java:0.0.6=buildTimeInstrumentationPlugin,compileClasspath,jmhCompileClasspath,jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,muzzleBootstrap,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.datadoghq:dd-javac-plugin-client:0.2.2=buildTimeInstrumentationPlugin,compileClasspath,jmhCompileClasspath,jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,muzzleBootstrap,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.datadoghq:java-dogstatsd-client:4.4.5=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +com.datadoghq:sketches-java:0.8.3=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +com.fasterxml.jackson.core:jackson-annotations:2.20=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +com.fasterxml.jackson.core:jackson-core:2.20.0=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +com.fasterxml.jackson.core:jackson-databind:2.20.0=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +com.fasterxml.jackson:jackson-bom:2.20.0=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath com.github.javaparser:javaparser-core:3.25.6=codenarc -com.github.jnr:jffi:1.3.15=latestDepTestRuntimeClasspath,testRuntimeClasspath -com.github.jnr:jnr-a64asm:1.0.0=latestDepTestRuntimeClasspath,testRuntimeClasspath -com.github.jnr:jnr-constants:0.10.4=latestDepTestRuntimeClasspath,testRuntimeClasspath -com.github.jnr:jnr-enxio:0.32.20=latestDepTestRuntimeClasspath,testRuntimeClasspath -com.github.jnr:jnr-ffi:2.2.19=latestDepTestRuntimeClasspath,testRuntimeClasspath -com.github.jnr:jnr-posix:3.1.22=latestDepTestRuntimeClasspath,testRuntimeClasspath -com.github.jnr:jnr-unixsocket:0.38.25=latestDepTestRuntimeClasspath,testRuntimeClasspath -com.github.jnr:jnr-x86asm:1.0.2=latestDepTestRuntimeClasspath,testRuntimeClasspath -com.github.spotbugs:spotbugs-annotations:4.10.4=compileClasspath,spotbugs +com.github.jnr:jffi:1.3.15=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +com.github.jnr:jnr-a64asm:1.0.0=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +com.github.jnr:jnr-constants:0.10.4=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +com.github.jnr:jnr-enxio:0.32.20=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +com.github.jnr:jnr-ffi:2.2.19=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +com.github.jnr:jnr-posix:3.1.22=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +com.github.jnr:jnr-unixsocket:0.38.25=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +com.github.jnr:jnr-x86asm:1.0.2=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +com.github.spotbugs:spotbugs-annotations:4.10.4=compileClasspath,jmhCompileClasspath,spotbugs com.github.spotbugs:spotbugs:4.10.4=spotbugs com.github.stephenc.jcip:jcip-annotations:1.0-1=spotbugs -com.google.auto.service:auto-service-annotations:1.1.1=annotationProcessor,compileClasspath,latestDepTestAnnotationProcessor,latestDepTestCompileClasspath,testAnnotationProcessor,testCompileClasspath +com.google.auto.service:auto-service-annotations:1.1.1=annotationProcessor,compileClasspath,jmhCompileClasspath,latestDepTestAnnotationProcessor,latestDepTestCompileClasspath,testAnnotationProcessor,testCompileClasspath com.google.auto.service:auto-service:1.1.1=annotationProcessor,latestDepTestAnnotationProcessor,testAnnotationProcessor com.google.auto:auto-common:1.2.1=annotationProcessor,latestDepTestAnnotationProcessor,testAnnotationProcessor -com.google.code.findbugs:jsr305:3.0.2=annotationProcessor,compileClasspath,latestDepTestAnnotationProcessor,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,spotbugs,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath +com.google.code.findbugs:jsr305:3.0.2=annotationProcessor,compileClasspath,jmhCompileClasspath,jmhRuntimeClasspath,latestDepTestAnnotationProcessor,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,spotbugs,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath com.google.code.gson:gson:2.14.0=spotbugs com.google.errorprone:error_prone_annotations:2.18.0=annotationProcessor,latestDepTestAnnotationProcessor,testAnnotationProcessor -com.google.errorprone:error_prone_annotations:2.47.0=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.47.0=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.48.0=spotbugs com.google.guava:failureaccess:1.0.1=annotationProcessor,latestDepTestAnnotationProcessor,testAnnotationProcessor -com.google.guava:failureaccess:1.0.3=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +com.google.guava:failureaccess:1.0.3=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath com.google.guava:guava:32.0.1-jre=annotationProcessor,latestDepTestAnnotationProcessor,testAnnotationProcessor -com.google.guava:guava:33.6.0-jre=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=annotationProcessor,latestDepTestAnnotationProcessor,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath +com.google.guava:guava:33.6.0-jre=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=annotationProcessor,jmhRuntimeClasspath,latestDepTestAnnotationProcessor,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath com.google.j2objc:j2objc-annotations:2.8=annotationProcessor,latestDepTestAnnotationProcessor,testAnnotationProcessor -com.google.j2objc:j2objc-annotations:3.1=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -com.google.re2j:re2j:1.8=latestDepTestRuntimeClasspath,testRuntimeClasspath -com.squareup.moshi:moshi:1.11.0=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -com.squareup.okhttp3:logging-interceptor:3.12.12=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -com.squareup.okhttp3:okhttp:3.12.12=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -com.squareup.okio:okio:1.17.5=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.1=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +com.google.re2j:re2j:1.8=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +com.squareup.moshi:moshi:1.11.0=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +com.squareup.okhttp3:logging-interceptor:3.12.12=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +com.squareup.okhttp3:okhttp:3.12.12=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +com.squareup.okio:okio:1.17.5=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath com.thoughtworks.qdox:qdox:1.12.1=codenarc -commons-fileupload:commons-fileupload:1.5=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.11.0=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-fileupload:commons-fileupload:1.5=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.11.0=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath commons-io:commons-io:2.21.0=spotbugs -de.thetaphi:forbiddenapis:3.11=compileClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -io.leangen.geantyref:geantyref:1.3.16=latestDepTestRuntimeClasspath,testRuntimeClasspath -io.sqreen:libsqreen:17.5.0=latestDepTestRuntimeClasspath,testRuntimeClasspath -javax.servlet:javax.servlet-api:3.1.0=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +de.thetaphi:forbiddenapis:3.11=compileClasspath,jmhCompileClasspath,jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +io.leangen.geantyref:geantyref:1.3.16=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +io.sqreen:libsqreen:17.5.0=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +javax.servlet:javax.servlet-api:3.1.0=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath jaxen:jaxen:2.0.6=spotbugs -junit:junit:4.13.2=latestDepTestRuntimeClasspath,testRuntimeClasspath -net.bytebuddy:byte-buddy-agent:1.18.12=buildTimeInstrumentationPlugin,compileClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -net.bytebuddy:byte-buddy:1.18.12=buildTimeInstrumentationPlugin,compileClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -net.java.dev.jna:jna-platform:5.8.0=latestDepTestRuntimeClasspath,testRuntimeClasspath -net.java.dev.jna:jna:5.8.0=latestDepTestRuntimeClasspath,testRuntimeClasspath +junit:junit:4.13.2=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +net.bytebuddy:byte-buddy-agent:1.18.12=buildTimeInstrumentationPlugin,compileClasspath,jmhCompileClasspath,jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +net.bytebuddy:byte-buddy:1.18.12=buildTimeInstrumentationPlugin,compileClasspath,jmhCompileClasspath,jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +net.java.dev.jna:jna-platform:5.8.0=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +net.java.dev.jna:jna:5.8.0=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +net.sf.jopt-simple:jopt-simple:5.0.4=jmh,jmhCompileClasspath,jmhRuntimeClasspath net.sf.saxon:Saxon-HE:12.10=spotbugs org.apache.ant:ant-antlr:1.10.14=codenarc org.apache.ant:ant-junit:1.10.14=codenarc org.apache.bcel:bcel:6.12.0=spotbugs org.apache.commons:commons-lang3:3.20.0=spotbugs +org.apache.commons:commons-math3:3.2=jmh,jmhCompileClasspath,jmhRuntimeClasspath org.apache.commons:commons-text:1.15.0=spotbugs org.apache.logging.log4j:log4j-api:2.26.1=spotbugs org.apache.logging.log4j:log4j-core:2.26.1=spotbugs @@ -74,52 +80,57 @@ org.codehaus.groovy:groovy-ant:3.0.23=codenarc org.codehaus.groovy:groovy-docgenerator:3.0.23=codenarc org.codehaus.groovy:groovy-groovydoc:3.0.23=codenarc org.codehaus.groovy:groovy-json:3.0.23=codenarc -org.codehaus.groovy:groovy-json:3.0.25=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.codehaus.groovy:groovy-json:3.0.25=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath org.codehaus.groovy:groovy-templates:3.0.23=codenarc org.codehaus.groovy:groovy-xml:3.0.23=codenarc org.codehaus.groovy:groovy:3.0.23=codenarc -org.codehaus.groovy:groovy:3.0.25=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.codehaus.groovy:groovy:3.0.25=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath org.codenarc:CodeNarc:3.7.0=codenarc org.dom4j:dom4j:2.2.0=spotbugs org.gmetrics:GMetrics:2.1.0=codenarc -org.hamcrest:hamcrest-core:1.3=latestDepTestRuntimeClasspath,testRuntimeClasspath -org.hamcrest:hamcrest:3.0=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -org.jctools:jctools-core-jdk11:4.0.6=latestDepTestRuntimeClasspath,testRuntimeClasspath -org.jctools:jctools-core:4.0.6=latestDepTestRuntimeClasspath,testRuntimeClasspath -org.jspecify:jspecify:1.0.0=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -org.junit.jupiter:junit-jupiter-api:5.14.1=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -org.junit.jupiter:junit-jupiter-engine:5.14.1=latestDepTestRuntimeClasspath,testRuntimeClasspath -org.junit.jupiter:junit-jupiter-params:5.14.1=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -org.junit.jupiter:junit-jupiter:5.14.1=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -org.junit.platform:junit-platform-commons:1.14.1=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -org.junit.platform:junit-platform-engine:1.14.1=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -org.junit.platform:junit-platform-launcher:1.14.1=latestDepTestRuntimeClasspath,testRuntimeClasspath -org.junit.platform:junit-platform-runner:1.14.1=latestDepTestRuntimeClasspath,testRuntimeClasspath -org.junit.platform:junit-platform-suite-api:1.14.1=latestDepTestRuntimeClasspath,testRuntimeClasspath -org.junit.platform:junit-platform-suite-commons:1.14.1=latestDepTestRuntimeClasspath,testRuntimeClasspath -org.junit:junit-bom:5.14.1=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -org.mockito:mockito-core:4.4.0=latestDepTestRuntimeClasspath,testRuntimeClasspath -org.objenesis:objenesis:3.3=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -org.opentest4j:opentest4j:1.3.0=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hamcrest:hamcrest-core:1.3=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +org.hamcrest:hamcrest:3.0=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.jctools:jctools-core-jdk11:4.0.6=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +org.jctools:jctools-core:4.0.6=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +org.jspecify:jspecify:1.0.0=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.junit.jupiter:junit-jupiter-api:5.14.1=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.junit.jupiter:junit-jupiter-engine:5.14.1=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +org.junit.jupiter:junit-jupiter-params:5.14.1=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.junit.jupiter:junit-jupiter:5.14.1=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.junit.platform:junit-platform-commons:1.14.1=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.junit.platform:junit-platform-engine:1.14.1=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.junit.platform:junit-platform-launcher:1.14.1=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +org.junit.platform:junit-platform-runner:1.14.1=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +org.junit.platform:junit-platform-suite-api:1.14.1=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +org.junit.platform:junit-platform-suite-commons:1.14.1=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +org.junit:junit-bom:5.14.1=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.mockito:mockito-core:4.4.0=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +org.objenesis:objenesis:3.3=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.openjdk.jmh:jmh-core:1.36=jmh,jmhCompileClasspath,jmhRuntimeClasspath +org.openjdk.jmh:jmh-generator-asm:1.36=jmh,jmhCompileClasspath,jmhRuntimeClasspath +org.openjdk.jmh:jmh-generator-bytecode:1.36=jmh,jmhCompileClasspath,jmhRuntimeClasspath +org.openjdk.jmh:jmh-generator-reflection:1.36=jmh,jmhCompileClasspath,jmhRuntimeClasspath +org.opentest4j:opentest4j:1.3.0=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-analysis:9.10.1=spotbugs -org.ow2.asm:asm-analysis:9.7.1=latestDepTestRuntimeClasspath,testRuntimeClasspath -org.ow2.asm:asm-commons:9.10.1=latestDepTestRuntimeClasspath,spotbugs,testRuntimeClasspath -org.ow2.asm:asm-tree:9.10.1=latestDepTestRuntimeClasspath,spotbugs,testRuntimeClasspath +org.ow2.asm:asm-analysis:9.7.1=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +org.ow2.asm:asm-commons:9.10.1=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,spotbugs,testRuntimeClasspath +org.ow2.asm:asm-tree:9.10.1=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,spotbugs,testRuntimeClasspath org.ow2.asm:asm-util:9.10.1=spotbugs -org.ow2.asm:asm-util:9.7.1=latestDepTestRuntimeClasspath,testRuntimeClasspath -org.ow2.asm:asm:9.10.1=buildTimeInstrumentationPlugin,compileClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,muzzleTooling,runtimeClasspath,spotbugs,testCompileClasspath,testRuntimeClasspath -org.slf4j:jcl-over-slf4j:1.7.30=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -org.slf4j:jul-to-slf4j:1.7.30=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -org.slf4j:log4j-over-slf4j:1.7.30=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -org.slf4j:slf4j-api:1.7.30=buildTimeInstrumentationPlugin,compileClasspath,muzzleBootstrap,muzzleTooling,runtimeClasspath -org.slf4j:slf4j-api:1.7.32=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.ow2.asm:asm-util:9.7.1=jmhRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath +org.ow2.asm:asm:9.0=jmh +org.ow2.asm:asm:9.10.1=buildTimeInstrumentationPlugin,compileClasspath,jmhCompileClasspath,jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,muzzleTooling,runtimeClasspath,spotbugs,testCompileClasspath,testRuntimeClasspath +org.slf4j:jcl-over-slf4j:1.7.30=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.slf4j:jul-to-slf4j:1.7.30=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.slf4j:log4j-over-slf4j:1.7.30=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.slf4j:slf4j-api:1.7.30=buildTimeInstrumentationPlugin,compileClasspath,jmhCompileClasspath,muzzleBootstrap,muzzleTooling,runtimeClasspath +org.slf4j:slf4j-api:1.7.32=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.17=spotbugsSlf4j org.slf4j:slf4j-api:2.0.18=spotbugs org.slf4j:slf4j-simple:2.0.17=spotbugsSlf4j -org.snakeyaml:snakeyaml-engine:2.9=buildTimeInstrumentationPlugin,latestDepTestRuntimeClasspath,muzzleTooling,runtimeClasspath,testRuntimeClasspath -org.spockframework:spock-bom:2.4-groovy-3.0=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -org.spockframework:spock-core:2.4-groovy-3.0=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -org.tabletest:tabletest-junit:1.2.2=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -org.tabletest:tabletest-parser:1.2.1=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.snakeyaml:snakeyaml-engine:2.9=buildTimeInstrumentationPlugin,jmhRuntimeClasspath,latestDepTestRuntimeClasspath,muzzleTooling,runtimeClasspath,testRuntimeClasspath +org.spockframework:spock-bom:2.4-groovy-3.0=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.spockframework:spock-core:2.4-groovy-3.0=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.tabletest:tabletest-junit:1.2.2=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.tabletest:tabletest-parser:1.2.1=jmhRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlresolver:xmlresolver:5.3.3=spotbugs -empty=spotbugsPlugins +empty=jmhAnnotationProcessor,spotbugsPlugins diff --git a/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/jmh/java/StripInjectedContextBenchmark.java b/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/jmh/java/StripInjectedContextBenchmark.java new file mode 100644 index 00000000000..110501322cf --- /dev/null +++ b/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/jmh/java/StripInjectedContextBenchmark.java @@ -0,0 +1,82 @@ +package datadog.trace.instrumentation.aws.v1.lambda; + +import static java.util.concurrent.TimeUnit.MICROSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.nio.charset.StandardCharsets; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +@State(Scope.Benchmark) +@Warmup(iterations = 3, time = 5, timeUnit = SECONDS) +@Measurement(iterations = 3, time = 5, timeUnit = SECONDS) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(MICROSECONDS) +@Fork(value = 1) +public class StripInjectedContextBenchmark { + + @Param({"true", "false"}) + boolean containsDatadogCarrier; + + // Event shapes: "eventbridge", "sqs", "sns" + @Param({"eventbridge", "sqs", "sns"}) + String payloadShape; + + byte[] payload; + + @Setup(Level.Trial) + public void setUp() { + String carrier = "{\"x-datadog-trace-id\":\"123\",\"x-datadog-parent-id\":\"456\"}"; + + switch (payloadShape) { + case "sqs": + { + // SQS-style: _datadog appears as a direct top-level key. + String body = + containsDatadogCarrier + ? "{\"orderId\":42,\"customer\":\"acme\",\"_datadog\":" + carrier + "}" + : "{\"orderId\":42,\"customer\":\"acme\"}"; + payload = body.getBytes(StandardCharsets.UTF_8); + break; + } + case "sns": + { + // SNS-style: _datadog is embedded inside a string-encoded "Message" field. + String inner = + containsDatadogCarrier + ? "{\\\"orderId\\\":42,\\\"_datadog\\\":" + carrier.replace("\"", "\\\"") + "}" + : "{\\\"orderId\\\":42}"; + String envelope = "{\"Type\":\"Notification\",\"Message\":\"" + inner + "\"}"; + payload = envelope.getBytes(StandardCharsets.UTF_8); + break; + } + default: + { + // EventBridge-style: _datadog is inside the "detail" object. + String detail = + containsDatadogCarrier + ? "{\"orderId\":42,\"customer\":\"acme\",\"_datadog\":" + carrier + "}" + : "{\"orderId\":42,\"customer\":\"acme\"}"; + String envelope = "{\"detail-type\":\"order.created\",\"detail\":" + detail + "}"; + payload = envelope.getBytes(StandardCharsets.UTF_8); + break; + } + } + } + + @Benchmark + public void stripInternal(Blackhole blackhole) { + blackhole.consume(StripInjectedContext.stripInternal(payload)); + } +} diff --git a/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/main/java/datadog/trace/instrumentation/aws/v1/lambda/LambdaHandlerInstrumentation.java b/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/main/java/datadog/trace/instrumentation/aws/v1/lambda/LambdaHandlerInstrumentation.java index 7f62f4337d9..33f86d2935c 100644 --- a/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/main/java/datadog/trace/instrumentation/aws/v1/lambda/LambdaHandlerInstrumentation.java +++ b/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/main/java/datadog/trace/instrumentation/aws/v1/lambda/LambdaHandlerInstrumentation.java @@ -12,7 +12,9 @@ import static net.bytebuddy.asm.Advice.Origin; import static net.bytebuddy.asm.Advice.This; import static net.bytebuddy.matcher.ElementMatchers.isMethod; +import static net.bytebuddy.matcher.ElementMatchers.isSubTypeOf; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; +import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; @@ -20,6 +22,7 @@ import datadog.context.ContextScope; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.api.Config; import datadog.trace.bootstrap.CallDepthThreadLocalMap; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.AgentSpanContext; @@ -27,8 +30,10 @@ import datadog.trace.bootstrap.instrumentation.api.InternalSpanTypes; import datadog.trace.bootstrap.instrumentation.api.ResourceNamePriorities; import datadog.trace.config.inversion.ConfigHelper; +import java.io.InputStream; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.implementation.bytecode.assign.Assigner; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumenterModule.class) @@ -68,6 +73,10 @@ public void methodAdvice(MethodTransformer transformer) { transformer.applyAdvice( isMethod() .and(named("handleRequest")) + .and(takesArguments(3)) + // Constrain arg0 to InputStream so an unrelated 3-arg "handleRequest" overload + // with a non-InputStream first parameter isn't matched by mistake. + .and(takesArgument(0, isSubTypeOf(InputStream.class))) .and(takesArgument(2, named("com.amazonaws.services.lambda.runtime.Context"))), getClass().getName() + "$ExtensionCommunicationAdvice"); } @@ -76,16 +85,32 @@ public static class ExtensionCommunicationAdvice { @OnMethodEnter static ContextScope enter( @This final Object that, - @Advice.Argument(0) final Object in, + // Bound as Object (not InputStream) so Byte Buddy can always bind this argument for + // writing back, even if the matcher's arg0 constraint is ever loosened or bypassed. + @Advice.Argument(value = 0, readOnly = false, typing = Assigner.Typing.DYNAMIC) Object in, @Advice.Argument(1) final Object out, @Advice.Argument(2) final Context awsContext, @Origin("#m") final String methodName) { - if (CallDepthThreadLocalMap.incrementCallDepth(RequestHandler.class) > 0) { return null; } + if (!(in instanceof InputStream)) { + // Defensive guard: should never happen given the matcher's arg0 constraint. + return null; + } + InputStream inputStream = (InputStream) in; String lambdaRequestId = awsContext.getAwsRequestId(); - AgentSpanContext lambdaContext = AgentTracer.get().notifyLambdaStart(in, lambdaRequestId); + AgentSpanContext lambdaContext = + AgentTracer.get().notifyLambdaStart(inputStream, lambdaRequestId); + // Skip the strip pass entirely (extra read/parse/re-serialize) unless explicitly enabled. + if (Config.get().isLambdaStripInjectedContextEnabled()) { + InputStream stripped = StripInjectedContext.replaceInputStream(inputStream); + if (stripped != null) { + inputStream = stripped; + } + } + in = inputStream; + final AgentSpan span; if (null == lambdaContext) { span = startSpan("java-aws-sdk", INVOCATION_SPAN_NAME); diff --git a/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/main/java/datadog/trace/instrumentation/aws/v1/lambda/StripInjectedContext.java b/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/main/java/datadog/trace/instrumentation/aws/v1/lambda/StripInjectedContext.java new file mode 100644 index 00000000000..0042a30c673 --- /dev/null +++ b/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/main/java/datadog/trace/instrumentation/aws/v1/lambda/StripInjectedContext.java @@ -0,0 +1,267 @@ +package datadog.trace.instrumentation.aws.v1.lambda; + +import datadog.json.JsonMapper; +import datadog.json.JsonReader; +import datadog.trace.api.Config; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Removes {@code "_datadog":{...}} trace-context carriers injected by Datadog into Lambda events + * (EventBridge, SNS, SQS, ...) before the customer handler reads them. + * + *
Carriers are cut out of the JSON text instead of parsing and re-serializing the payload, so
+ * numbers, key order and formatting of customer data are kept. Carriers inside string-encoded JSON
+ * values (an SNS {@code Message}, an SQS {@code body}) are handled by decoding that string,
+ * stripping it recursively up to {@link #MAX_DEPTH} levels, and re-encoding it. Object keys are
+ * never rewritten, and a {@code _datadog} key whose value is not an object is customer data and is
+ * kept. Fail-open: on any error the original payload is used.
+ */
+public final class StripInjectedContext {
+
+ private static final Logger log = LoggerFactory.getLogger(StripInjectedContext.class);
+
+ /** SNS-to-SQS fan-out needs 2 levels of string-encoded JSON; one more is a safety margin. */
+ static final int MAX_DEPTH = 3;
+
+ private static final String CARRIER_KEY = "_datadog";
+ private static final String QUOTED_CARRIER_KEY = "\"" + CARRIER_KEY + "\"";
+ private static final byte[] CARRIER_KEY_BYTES = CARRIER_KEY.getBytes(StandardCharsets.UTF_8);
+
+ /** Returned by {@link #carrierRange} when the carrier object never closes (malformed JSON). */
+ private static final int[] UNCLOSED = new int[0];
+
+ private StripInjectedContext() {}
+
+ /**
+ * Returns a stream over the stripped payload, or {@code null} to keep {@code in}. Like the other
+ * Lambda event consumers, only {@link ByteArrayInputStream} is supported, because it can be read
+ * with mark/reset without consuming the customer's input.
+ */
+ public static ByteArrayInputStream replaceInputStream(InputStream in) {
+ if (!(in instanceof ByteArrayInputStream)) {
+ return null;
+ }
+ byte[] original = readAllBytes((ByteArrayInputStream) in);
+ try {
+ return new ByteArrayInputStream(strip(original));
+ } catch (RuntimeException e) {
+ log.debug("Unable to strip _datadog from Lambda payload", e);
+ return new ByteArrayInputStream(original);
+ }
+ }
+
+ /** Strips "_datadog" from {@code payload} when the config is enabled. */
+ public static byte[] strip(byte[] payload) {
+ if (!Config.get().isLambdaStripInjectedContextEnabled()) {
+ return payload;
+ }
+ return stripInternal(payload);
+ }
+
+ /** Unconditional strip logic, package-private so tests can call it directly. */
+ static byte[] stripInternal(byte[] payload) {
+ if (payload == null || !containsCarrierKey(payload)) {
+ return payload;
+ }
+ String json = new String(payload, StandardCharsets.UTF_8);
+ // Invalid UTF-8 decodes to U+FFFD and would be re-encoded as such, so keep the payload as is.
+ if (json.indexOf('\uFFFD') >= 0) {
+ return payload;
+ }
+ String stripped = stripJson(json, 0);
+ return stripped.equals(json) ? payload : stripped.getBytes(StandardCharsets.UTF_8);
+ }
+
+ /**
+ * Walks the string tokens of {@code json} once. A {@code "_datadog"} key with an object value is
+ * cut out; any other string value containing {@code _datadog} is treated as encoded JSON and
+ * stripped recursively. Returns {@code json} itself when nothing changed.
+ */
+ private static String stripJson(String json, int depth) {
+ StringBuilder out = null;
+ int copyFrom = 0;
+ int nextKey = -1;
+ int start = json.indexOf('"');
+ while (start >= 0) {
+ if (nextKey < start) {
+ nextKey = json.indexOf(CARRIER_KEY, start);
+ if (nextKey < 0) {
+ break;
+ }
+ }
+ int end = stringEnd(json, start);
+ if (end < 0) {
+ break;
+ }
+ int[] carrier = carrierRange(json, start, end, copyFrom);
+ if (carrier == UNCLOSED) {
+ break;
+ }
+ if (carrier != null) {
+ if (out == null) {
+ out = new StringBuilder(json.length());
+ }
+ out.append(json, copyFrom, carrier[0]);
+ copyFrom = carrier[1];
+ end = carrier[1];
+ } else if (nextKey < end && depth < MAX_DEPTH && !isKey(json, end)) {
+ String replacement = stripEncodedJson(json.substring(start, end), depth);
+ if (replacement != null) {
+ if (out == null) {
+ out = new StringBuilder(json.length());
+ }
+ out.append(json, copyFrom, start).append(replacement);
+ copyFrom = end;
+ }
+ }
+ start = json.indexOf('"', end);
+ }
+ if (out == null) {
+ return json;
+ }
+ return out.append(json, copyFrom, json.length()).toString();
+ }
+
+ /**
+ * If the string token {@code [keyStart, keyEnd)} is a {@code "_datadog"} key with an object
+ * value, returns the {@code [start, end)} range to cut, including one adjacent comma so the JSON
+ * stays valid. A preceding comma before {@code copyFrom} was already cut and is not reused.
+ * Returns {@link #UNCLOSED} if the value object never closes.
+ */
+ private static int[] carrierRange(String json, int keyStart, int keyEnd, int copyFrom) {
+ if (keyEnd - keyStart != QUOTED_CARRIER_KEY.length()
+ || !json.startsWith(QUOTED_CARRIER_KEY, keyStart)) {
+ return null;
+ }
+ int colon = skipWhitespace(json, keyEnd);
+ if (colon >= json.length() || json.charAt(colon) != ':') {
+ return null;
+ }
+ int valueStart = skipWhitespace(json, colon + 1);
+ if (valueStart >= json.length() || json.charAt(valueStart) != '{') {
+ return null;
+ }
+ int valueEnd = objectEnd(json, valueStart);
+ if (valueEnd < 0) {
+ return UNCLOSED;
+ }
+ int before = skipWhitespaceBackward(json, keyStart - 1);
+ if (before >= copyFrom && json.charAt(before) == ',') {
+ return new int[] {before, valueEnd};
+ }
+ int after = skipWhitespace(json, valueEnd);
+ if (after < json.length() && json.charAt(after) == ',') {
+ return new int[] {keyStart, after + 1};
+ }
+ return new int[] {keyStart, valueEnd};
+ }
+
+ /**
+ * Decodes the JSON string literal {@code literal}, strips it if it looks like a JSON object
+ * (starts with '{' and ends with '}'), and returns the re-encoded literal, or {@code null} if
+ * nothing changed.
+ */
+ private static String stripEncodedJson(String literal, int depth) {
+ String decoded;
+ try {
+ decoded = new JsonReader(literal).nextString();
+ } catch (IOException e) {
+ return null;
+ }
+ int first = skipWhitespace(decoded, 0);
+ if (first >= decoded.length() || decoded.charAt(first) != '{') {
+ return null;
+ }
+ int last = skipWhitespaceBackward(decoded, decoded.length() - 1);
+ if (decoded.charAt(last) != '}') {
+ return null;
+ }
+ String stripped = stripJson(decoded, depth + 1);
+ return stripped.equals(decoded) ? null : JsonMapper.toJson(stripped);
+ }
+
+ /** Returns the index just past the closing quote of the string opening at {@code start}. */
+ private static int stringEnd(String json, int start) {
+ for (int i = start + 1; i < json.length(); i++) {
+ char c = json.charAt(i);
+ if (c == '\\') {
+ i++;
+ } else if (c == '"') {
+ return i + 1;
+ }
+ }
+ return -1;
+ }
+
+ /** Returns the index just past the closing brace of the object opening at {@code start}. */
+ private static int objectEnd(String json, int start) {
+ int depth = 0;
+ for (int i = start; i < json.length(); i++) {
+ char c = json.charAt(i);
+ if (c == '"') {
+ int end = stringEnd(json, i);
+ if (end < 0) {
+ return -1;
+ }
+ i = end - 1;
+ } else if (c == '{') {
+ depth++;
+ } else if (c == '}' && --depth == 0) {
+ return i + 1;
+ }
+ }
+ return -1;
+ }
+
+ /** Object keys are customer property names and are never rewritten. */
+ private static boolean isKey(String json, int stringEnd) {
+ int next = skipWhitespace(json, stringEnd);
+ return next < json.length() && json.charAt(next) == ':';
+ }
+
+ private static int skipWhitespace(String json, int i) {
+ while (i < json.length() && isWhitespace(json.charAt(i))) {
+ i++;
+ }
+ return i;
+ }
+
+ private static int skipWhitespaceBackward(String json, int i) {
+ while (i >= 0 && isWhitespace(json.charAt(i))) {
+ i--;
+ }
+ return i;
+ }
+
+ private static boolean isWhitespace(char c) {
+ return c == ' ' || c == '\t' || c == '\n' || c == '\r';
+ }
+
+ private static boolean containsCarrierKey(byte[] payload) {
+ outer:
+ for (int i = 0; i <= payload.length - CARRIER_KEY_BYTES.length; i++) {
+ for (int j = 0; j < CARRIER_KEY_BYTES.length; j++) {
+ if (payload[i + j] != CARRIER_KEY_BYTES[j]) {
+ continue outer;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /** Reads all bytes from {@code in} and restores its position, so the stream is not consumed. */
+ private static byte[] readAllBytes(ByteArrayInputStream in) {
+ in.mark(Integer.MAX_VALUE);
+ byte[] bytes = new byte[in.available()];
+ int read = in.read(bytes, 0, bytes.length);
+ in.reset();
+ return read == bytes.length ? bytes : Arrays.copyOf(bytes, Math.max(read, 0));
+ }
+}
diff --git a/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/test/java/LambdaHandlerInstrumentationTest.java b/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/test/java/LambdaHandlerInstrumentationTest.java
index 0aff2114e51..a5a1563d2d5 100644
--- a/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/test/java/LambdaHandlerInstrumentationTest.java
+++ b/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/test/java/LambdaHandlerInstrumentationTest.java
@@ -15,9 +15,11 @@
import com.amazonaws.services.lambda.runtime.CognitoIdentity;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
+import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import datadog.trace.agent.test.AbstractInstrumentationTest;
import datadog.trace.api.DDSpanTypes;
import datadog.trace.api.DDTags;
+import datadog.trace.api.config.GeneralConfig;
import datadog.trace.api.function.TriConsumer;
import datadog.trace.api.function.TriFunction;
import datadog.trace.api.gateway.Flow;
@@ -34,6 +36,8 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
@@ -634,6 +638,46 @@ void responseCallbacksReceiveNoDataWhenHandlerThrows() {
error(Error.class, "Some error"))));
}
+ @WithConfig(key = GeneralConfig.LAMBDA_STRIP_INJECTED_CONTEXT, value = "true")
+ @Test
+ void stripsInjectedDatadogContextFromEventBridgeDetail() throws IOException {
+ String eventJson =
+ "{"
+ + "\"detail-type\": \"order.created\","
+ + "\"detail\": {"
+ + " \"orderId\":42,"
+ + " \"_datadog\":{\"x-datadog-trace-id\": \"123\"}"
+ + "}"
+ + "}";
+
+ ByteArrayInputStream input =
+ new ByteArrayInputStream(eventJson.getBytes(StandardCharsets.UTF_8));
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+
+ class CapturingHandler implements RequestStreamHandler {
+ String capturedBody;
+
+ @Override
+ public void handleRequest(InputStream in, OutputStream out, Context context)
+ throws IOException {
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ byte[] chunk = new byte[8192];
+ int n;
+ while ((n = in.read(chunk)) != -1) {
+ buffer.write(chunk, 0, n);
+ }
+ capturedBody = new String(buffer.toByteArray(), StandardCharsets.UTF_8);
+ out.write("{}".getBytes(StandardCharsets.UTF_8));
+ }
+ }
+
+ CapturingHandler handler = new CapturingHandler();
+ handler.handleRequest(input, output, newContext());
+
+ assertFalse(handler.capturedBody.contains("_datadog"));
+ assertTrue(handler.capturedBody.contains("\"orderId\":42"));
+ }
+
private static final class TestContext implements Context {
private final String requestId;
diff --git a/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/test/java/StripInjectedContextFuzzTest.java b/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/test/java/StripInjectedContextFuzzTest.java
new file mode 100644
index 00000000000..3b665d14d00
--- /dev/null
+++ b/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/test/java/StripInjectedContextFuzzTest.java
@@ -0,0 +1,380 @@
+package datadog.trace.instrumentation.aws.v1.lambda;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Random;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+
+/**
+ * Randomized invariant testing for {@link StripInjectedContext}, mirroring the repo's existing
+ * fuzz-style test pattern (see {@code TagMapFuzzTest}). Generates many random payloads in
+ * EventBridge, SQS, and SNS shapes instead of enumerating fixed cases by hand, and asserts core
+ * invariants hold for every one of them.
+ */
+public final class StripInjectedContextFuzzTest {
+
+ private static final long SEED = envLong("FUZZ_SEED", System.nanoTime());
+ private static final int ITERATIONS = (int) envLong("FUZZ_ITERATIONS", 5_000);
+
+ private static final ObjectMapper MAPPER = new ObjectMapper();
+
+ private static final String[] SEEDS = {
+ "{\"detail\":{\"_datadog\":{\"x-datadog-trace-id\":\"1\"},\"foo\":\"bar\"}}",
+ "{\"detail\":\"{\\\"foo\\\":\\\"bar\\\",\\\"_datadog\\\":{\\\"k\\\":\\\"v\\\"}}\"}",
+ "{\"foo\":\"a,}b\",\"_datadog\":{\"x\":1}}",
+ "{\"detail\":\"{\\\"foo\\\":\\\"bar\\\",\\\"_datadog\\\":{\\\"k\\\":\\\"v}z\\\"}}\"}",
+ "{\"_datadog\":{},\"_datadog\":{}}",
+ "not even json",
+ "{}",
+ ""
+ };
+
+ /** Inputs that once failed. Paste the input from a failure message here so it always runs. */
+ private static final String[] REGRESSIONS = {};
+
+ @BeforeAll
+ static void printSeed() {
+ System.out.println(
+ "StripInjectedContextFuzzTest FUZZ_SEED=" + SEED + " FUZZ_ITERATIONS=" + ITERATIONS);
+ }
+
+ static Stream