From b506f74ee3b2a82be4b08fa2ffe6462e32934a5d Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Wed, 31 Dec 2025 17:13:03 +0100 Subject: [PATCH 01/12] chore: Split play-2.6 into play-2.6, play-appsec-2.6, and play-appsec-2.7 modules --- .../play/play-2.6/build.gradle | 137 +------ .../play/play-appsec-2.6/.gitignore | 2 + .../play/play-appsec-2.6/build.gradle | 68 ++++ .../play26/server/PlayAsyncServerTest.groovy | 23 ++ ...PlayAsyncServerWithErrorHandlerTest.groovy | 21 ++ .../play26/server/PlayHttpServer.groovy | 84 +++++ .../play26/server/PlayRouters.groovy | 339 ++++++++++++++++++ .../play26/server/PlayServerTest.groovy | 178 +++++++++ .../PlayServerWithErrorHandlerTest.groovy | 46 +++ .../play26/server/TestHttpErrorHandler.java | 42 +++ .../appsec/ArgumentCaptureWrappers.java | 0 .../play26/appsec/BodyParserHelpers.java | 0 .../DelegatingBodyParserInstrumentation.java | 0 .../appsec/FormUrlEncodedInstrumentation.java | 0 .../HttpErrorHandlerInstrumentation.java | 0 .../JavaMultipartFormDataRegisterExcF.java | 0 .../appsec/NoDeclaredMethodMatcher.java | 0 .../play26/appsec/PathExtractionHelpers.java | 0 .../appsec/PathPatternInstrumentation.java | 0 .../PlayBodyParsersInstrumentation.java | 0 .../appsec/ResultsStatusInstrumentation.java | 0 .../appsec/RoutingDslInstrumentation.java | 0 .../SirdPathExtractorInstrumentation.java | 0 .../appsec/StatusHeaderInstrumentation.java | 0 .../appsec/TolerantJsonInstrumentation.java | 0 .../appsec/TolerantTextInstrumentation.java | 0 .../appsec/TolerantXmlInstrumentation.java | 0 .../play/play-appsec-2.7/.gitignore | 2 + .../play/play-appsec-2.7/build.gradle | 149 ++++++++ ...rverRoutesScalaWithErrorHandlerTest.groovy | 0 ...syncServerScalaWithErrorHandlerTest.groovy | 0 .../latestdep/PlayHttpServerScala.groovy | 0 .../server/latestdep/PlayRouters.groovy | 0 .../src/latestDepTest/routes/conf/routes | 0 .../latestdep/ImplicitConversions.scala | 0 .../server/latestdep/PlayController.scala | 0 .../server/latestdep/PlayRoutersScala.scala | 0 .../play27/appsec/ArgumentCaptureAdvice.java | 0 .../appsec/RoutingDsl27Instrumentation.java | 0 .../scala/generator/CompileRoutes.scala | 0 settings.gradle.kts | 2 + 41 files changed, 957 insertions(+), 136 deletions(-) create mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.6/.gitignore create mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle create mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy create mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy create mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy create mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy create mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy create mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy create mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/java/datadog/trace/instrumentation/play26/server/TestHttpErrorHandler.java rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.6}/src/main/java/datadog/trace/instrumentation/play26/appsec/ArgumentCaptureWrappers.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.6}/src/main/java/datadog/trace/instrumentation/play26/appsec/BodyParserHelpers.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.6}/src/main/java/datadog/trace/instrumentation/play26/appsec/DelegatingBodyParserInstrumentation.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.6}/src/main/java/datadog/trace/instrumentation/play26/appsec/FormUrlEncodedInstrumentation.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.6}/src/main/java/datadog/trace/instrumentation/play26/appsec/HttpErrorHandlerInstrumentation.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.6}/src/main/java/datadog/trace/instrumentation/play26/appsec/JavaMultipartFormDataRegisterExcF.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.6}/src/main/java/datadog/trace/instrumentation/play26/appsec/NoDeclaredMethodMatcher.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.6}/src/main/java/datadog/trace/instrumentation/play26/appsec/PathExtractionHelpers.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.6}/src/main/java/datadog/trace/instrumentation/play26/appsec/PathPatternInstrumentation.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.6}/src/main/java/datadog/trace/instrumentation/play26/appsec/PlayBodyParsersInstrumentation.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.6}/src/main/java/datadog/trace/instrumentation/play26/appsec/ResultsStatusInstrumentation.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.6}/src/main/java/datadog/trace/instrumentation/play26/appsec/RoutingDslInstrumentation.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.6}/src/main/java/datadog/trace/instrumentation/play26/appsec/SirdPathExtractorInstrumentation.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.6}/src/main/java/datadog/trace/instrumentation/play26/appsec/StatusHeaderInstrumentation.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.6}/src/main/java/datadog/trace/instrumentation/play26/appsec/TolerantJsonInstrumentation.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.6}/src/main/java/datadog/trace/instrumentation/play26/appsec/TolerantTextInstrumentation.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.6}/src/main/java/datadog/trace/instrumentation/play26/appsec/TolerantXmlInstrumentation.java (100%) create mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.7/.gitignore create mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.7}/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.7}/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerScalaWithErrorHandlerTest.groovy (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.7}/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayHttpServerScala.groovy (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.7}/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayRouters.groovy (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.7}/src/latestDepTest/routes/conf/routes (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.7}/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/ImplicitConversions.scala (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.7}/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayController.scala (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.7}/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayRoutersScala.scala (100%) rename dd-java-agent/instrumentation/play/{play-2.6/src/main/java_play27 => play-appsec-2.7/src/main/java}/datadog/trace/instrumentation/play27/appsec/ArgumentCaptureAdvice.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.7}/src/main/java/datadog/trace/instrumentation/play27/appsec/RoutingDsl27Instrumentation.java (100%) rename dd-java-agent/instrumentation/play/{play-2.6 => play-appsec-2.7}/src/routeGenerator/scala/generator/CompileRoutes.scala (100%) diff --git a/dd-java-agent/instrumentation/play/play-2.6/build.gradle b/dd-java-agent/instrumentation/play/play-2.6/build.gradle index 08c448d2e4f..570f934df6a 100644 --- a/dd-java-agent/instrumentation/play/play-2.6/build.gradle +++ b/dd-java-agent/instrumentation/play/play-2.6/build.gradle @@ -28,7 +28,6 @@ muzzle { assertInverse = true javaVersion = 11 } - pass { name = 'play26Only' group = 'com.typesafe.play' @@ -36,19 +35,11 @@ muzzle { versions = "[2.6.0,2.7.0)" assertInverse = true } - - pass { - name = 'play27' - group = 'com.typesafe.play' - module = 'play-java_2.13' - versions = "[2.7.0,)" - assertInverse = true - javaVersion = 11 - } } apply from: "$rootDir/gradle/java.gradle" apply plugin: 'scala' +apply plugin: 'java-test-fixtures' testJvmConstraints { // Play doesn't work with Java 9+ until 2.6.12 @@ -65,45 +56,11 @@ repositories { } addTestSuite('baseTest') -addTestSuite('latestDepTest') - -sourceSets { - main_play27 { - java.srcDirs "${project.projectDir}/src/main/java_play27" - } -} - -tasks.named("jar", Jar) { - from sourceSets.main_play27.output -} - -tasks.named("compileMain_play27Java", JavaCompile) { - dependsOn(compileJava) -} - -project.afterEvaluate { - tasks.named('instrumentJava') { dependsOn 'compileMain_play27Java' } - tasks.named('forbiddenApisMain_play27') { dependsOn 'instrumentMain_play27Java' } -} - -instrument { - additionalClasspath = [ - instrumentJava: compileMain_play27Java.destinationDirectory - ] -} dependencies { compileOnly group: 'com.typesafe.play', name: "play_$scalaVersion", version: playVersion compileOnly group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion - main_play27CompileOnly group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: '2.7.0' - main_play27CompileOnly project(':internal-api') - main_play27CompileOnly project(':dd-java-agent:agent-tooling') - main_play27CompileOnly project(':dd-java-agent:agent-bootstrap') - main_play27CompileOnly files("${project.buildDir}/classes/java/raw") { - builtBy = ['compileJava'] - } - baseTestImplementation group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion // TODO: Play WS is a separately versioned library starting with 2.6 and needs separate instrumentation. baseTestImplementation(group: 'com.typesafe.play', name: "play-test_$scalaVersion", version: playVersion) { @@ -117,96 +74,4 @@ dependencies { testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-concurrent-2.8') testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-promise:scala-promise-2.10') testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-promise:scala-promise-2.13') - - latestDepTestRuntimeOnly sourceSets.baseTest.output - latestDepTestImplementation libs.scala213 - latestDepTestImplementation group: 'com.typesafe.play', name: "play-java_2.13", version: '2.+' - latestDepTestImplementation(group: 'com.typesafe.play', name: "play-test_2.13", version: '2.+') { - exclude group: 'org.eclipse.jetty.websocket', module: 'websocket-client' - } - latestDepTestImplementation group: 'com.typesafe.play', name: 'play-akka-http-server_2.13', version: '2.+' -} - -configurations.matching({ it.name.startsWith('latestDepTest') }).configureEach({ - it.resolutionStrategy { - // logback-classic 1.4.11 doesn't like being loaded in the bootstrap classloader (NPE) - force group: 'ch.qos.logback', name: 'logback-classic', version: '1.4.5' - } -}) - -tasks.named("compileLatestDepTestJava", JavaCompile) { - configureCompiler(it, 11) -} - -tasks.named("compileLatestDepTestScala", ScalaCompile) { - configureCompiler(it, 11) - classpath = classpath + files(tasks.named('compileBaseTestJava').map { it.destinationDirectory }) -} - -tasks.named("latestDepTest", Test) { - javaLauncher = getJavaLauncherFor(11) - testClassesDirs = testClassesDirs + sourceSets.baseTest.output.classesDirs -} - -final generatedRoutes = layout.buildDirectory.dir('generated/sources/latestDepTestRoutes/scala') -sourceSets { - routeGenerator { - scala { - srcDir "${project.projectDir}/src/routeGenerator/scala" - } - } - latestDepTestGenerated { - scala { - srcDir generatedRoutes - } - } -} - -dependencies { - routeGeneratorImplementation libs.scala213 - routeGeneratorImplementation group: 'com.typesafe.play', name: "routes-compiler_2.13", version: '2.+' -} - -configurations { - latestDepTestGeneratedCompileClasspath.extendsFrom(latestDepTestCompileClasspath) -} - -tasks.register('buildLatestDepTestRoutes', JavaExec) { - String routesFile = "${project.projectDir}/src/latestDepTest/routes/conf/routes" - def outputDir = generatedRoutes - - it.inputs.file routesFile - it.outputs.dir outputDir - - it.mainClass = 'generator.CompileRoutes' - it.args routesFile, outputDir.get().asFile.absolutePath - - it.classpath configurations.named('routeGeneratorRuntimeClasspath') - it.classpath tasks.named('compileRouteGeneratorScala').map { it.destinationDirectory } - it.classpath tasks.named('compileLatestDepTestScala').map { it.destinationDirectory } - - it.javaLauncher = getJavaLauncherFor(11) -} - -tasks.named("compileLatestDepTestGeneratedScala", ScalaCompile) { - configureCompiler(it, 11) - classpath = classpath + files(tasks.named('compileLatestDepTestScala').map { it.destinationDirectory }) - dependsOn 'buildLatestDepTestRoutes' -} - -tasks.named("forbiddenApisLatestDepTestGenerated") { - enabled = false -} - -tasks.named("compileLatestDepTestGroovy", GroovyCompile) { - configureCompiler(it, 11) - classpath = classpath + - files(tasks.named('compileLatestDepTestScala').map { it.destinationDirectory }) + - files(tasks.named('compileBaseTestGroovy').map { it.destinationDirectory }) + - files(tasks.named('compileBaseTestJava').map { it.destinationDirectory }) + - files(tasks.named('compileLatestDepTestGeneratedScala').map { it.destinationDirectory }) -} - -dependencies { - latestDepTestRuntimeOnly sourceSets.latestDepTestGenerated.output } diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/.gitignore b/dd-java-agent/instrumentation/play/play-appsec-2.6/.gitignore new file mode 100644 index 00000000000..192221b47d1 --- /dev/null +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/.gitignore @@ -0,0 +1,2 @@ +.gradle/ +build/ \ No newline at end of file diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle b/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle new file mode 100644 index 00000000000..59cb3770f38 --- /dev/null +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle @@ -0,0 +1,68 @@ +def scalaVersion = '2.11' +def playVersion = '2.6.0' + +muzzle { + extraRepository("typesafe", "https://repo.typesafe.com/typesafe/maven-releases/") + + pass { + name = 'play26Only' + group = 'com.typesafe.play' + module = "play_$scalaVersion" + versions = "[2.6.0,2.7.0)" + assertInverse = true + javaVersion = 11 + } + pass { + name = 'play26Only' + group = 'com.typesafe.play' + module = 'play_2.12' + versions = "[2.6.0,2.7.0)" + assertInverse = true + javaVersion = 11 + } + pass { + name = 'play26Only' + group = 'com.typesafe.play' + module = 'play_2.13' + versions = "[2.6.0,2.7.0)" + assertInverse = true + javaVersion = 11 + } +} + +apply from: "$rootDir/gradle/java.gradle" +apply plugin: 'scala' + +testJvmConstraints { + // Play doesn't work with Java 9+ until 2.6.12 + maxJavaVersion = JavaVersion.VERSION_1_8 +} + +repositories { + maven { + name = 'typesafe' + url = 'https://repo.typesafe.com/typesafe/maven-releases/' + } +} + +addTestSuite('baseTest') + +dependencies { + compileOnly group: 'com.typesafe.play', name: "play_$scalaVersion", version: playVersion + compileOnly group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion + compileOnly project(':dd-java-agent:instrumentation:play:play-2.6') + + baseTestImplementation project(':dd-java-agent:instrumentation:play:play-2.6') + baseTestImplementation group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion + baseTestImplementation(group: 'com.typesafe.play', name: "play-test_$scalaVersion", version: playVersion) { + exclude group: 'org.eclipse.jetty.websocket', module: 'websocket-client' + } + + testRuntimeOnly project(':dd-java-agent:instrumentation:netty:netty-4.0') + testRuntimeOnly project(':dd-java-agent:instrumentation:netty:netty-4.1') + testRuntimeOnly project(':dd-java-agent:instrumentation:akka:akka-http:akka-http-10.0') + testRuntimeOnly project(':dd-java-agent:instrumentation:akka:akka-actor-2.5') + testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-concurrent-2.8') + testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-promise:scala-promise-2.10') + testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-promise:scala-promise-2.13') +} \ No newline at end of file diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy new file mode 100644 index 00000000000..4d9e443369d --- /dev/null +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy @@ -0,0 +1,23 @@ +package datadog.trace.instrumentation.play26.server + +import datadog.trace.agent.test.base.HttpServer +import groovy.transform.CompileStatic +import spock.lang.Shared + +import java.util.concurrent.Executors + +class PlayAsyncServerTest extends PlayServerTest { + @Shared + def executor + + def cleanupSpec() { + executor.shutdown() + } + + @CompileStatic + @Override + HttpServer server() { + executor = Executors.newCachedThreadPool() + return new PlayHttpServer(PlayRouters.&async.curry(executor)) + } +} diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy new file mode 100644 index 00000000000..8e84b25e8cf --- /dev/null +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy @@ -0,0 +1,21 @@ +package datadog.trace.instrumentation.play26.server + +import datadog.trace.agent.test.base.HttpServer +import spock.lang.Shared + +import java.util.concurrent.Executors + +class PlayAsyncServerWithErrorHandlerTest extends PlayServerWithErrorHandlerTest { + @Shared + def executor + + def cleanupSpec() { + executor.shutdown() + } + + @Override + HttpServer server() { + executor = Executors.newCachedThreadPool() + return new PlayHttpServer(PlayRouters.&async.curry(executor), new TestHttpErrorHandler()) + } +} diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy new file mode 100644 index 00000000000..e4fac0aeb7b --- /dev/null +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy @@ -0,0 +1,84 @@ +package datadog.trace.instrumentation.play26.server + +import datadog.trace.agent.test.base.HttpServer +import play.ApplicationLoader +import play.BuiltInComponents +import play.BuiltInComponentsFromContext +import play.Environment +import play.Mode +import play.api.Configuration +import play.api.Play +import play.core.server.AkkaHttpServerProvider +import play.core.server.ServerConfig +import play.http.HttpErrorHandler +import play.mvc.EssentialFilter +import play.routing.Router +import scala.Option + +import java.util.concurrent.TimeoutException +import java.util.function.Function + +class PlayHttpServer implements HttpServer { + final Function router + HttpErrorHandler httpErrorHandler + def application + def server + def port + + PlayHttpServer(Function router) { + this(router, null) + } + + PlayHttpServer(Function router, HttpErrorHandler httpErrorHandler) { + this.router = router + this.httpErrorHandler = httpErrorHandler + } + + @Override + void start() throws TimeoutException { + def environment = Environment.simple() + def context = ApplicationLoader.create(environment) + application = new BuiltInComponentsFromContext(context) { + @Override + Router router() { + router.apply(this) + } + + @Override + List httpFilters() { + Collections.emptyList() + } + + @Override + HttpErrorHandler httpErrorHandler() { + if (httpErrorHandler != null) { + return httpErrorHandler + } + return super.httpErrorHandler() + } + }.application().asScala() + Play.start(application) + + def config = new ServerConfig( + new File("."), + Option.apply(0), + Option.empty(), + "0.0.0.0", + Mode.PROD.asScala(), + System.getProperties(), + Configuration.load(environment.asScala()) + ) + server = new AkkaHttpServerProvider().createServer(config, application) + port = server.httpPort().get() + } + + @Override + void stop() { + server.stop() + } + + @Override + URI address() { + return new URI("http://localhost:$port/") + } +} diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy new file mode 100644 index 00000000000..c2226b78f6d --- /dev/null +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy @@ -0,0 +1,339 @@ +package datadog.trace.instrumentation.play26.server + +import com.fasterxml.jackson.databind.ObjectMapper +import datadog.appsec.api.blocking.Blocking +import datadog.trace.agent.test.base.HttpServerTest +import groovy.transform.CompileStatic +import play.BuiltInComponents +import play.api.libs.json.JsValue +import play.api.mvc.AnyContent +import play.libs.concurrent.HttpExecution +import play.mvc.Http +import play.mvc.Result +import play.mvc.Results +import play.routing.Router +import play.routing.RoutingDsl +import scala.collection.JavaConverters +import scala.concurrent.ExecutionContextExecutor +import scala.xml.NodeSeq + +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CompletionStage +import java.util.concurrent.Executor +import java.util.concurrent.ExecutorService +import java.util.function.Function +import java.util.function.Supplier + +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_JSON +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_MULTIPART +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_URLENCODED +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_XML +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CREATED +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CUSTOM_EXCEPTION +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.ERROR +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.EXCEPTION +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.FORWARDED +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.PATH_PARAM +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.QUERY_ENCODED_BOTH +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.QUERY_ENCODED_QUERY +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.QUERY_PARAM +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.REDIRECT +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.USER_BLOCK +import static datadog.trace.agent.test.base.HttpServerTest.controller +import static java.lang.Class.forName + +class PlayRouters { + static Router sync(BuiltInComponents components) { + try { + forName("datadog.trace.instrumentation.play26.server.latestdep.PlayRouters").sync components + } catch (ClassNotFoundException cnf) { + sync26(components) + } + } + + static Router async(ExecutorService executor, BuiltInComponents components) { + try { + forName("datadog.trace.instrumentation.play26.server.latestdep.PlayRouters").async executor, components + } catch (ClassNotFoundException cnf) { + async26(executor, components) + } + } + + private static Router sync26(BuiltInComponents components) { + RoutingDsl.fromComponents(components) + .GET(SUCCESS.path).routeTo({ + controller(SUCCESS) { + Results.status(SUCCESS.status, SUCCESS.body) + } + } as Supplier) + .GET(FORWARDED.path).routeTo({ + controller(FORWARDED) { + Results.status(FORWARDED.status, FORWARDED.body) + } + } as Supplier) + .GET(QUERY_PARAM.path).routeTo({ + controller(QUERY_PARAM) { + Results.status(QUERY_PARAM.status, QUERY_PARAM.body) + } + } as Supplier) + .GET(QUERY_ENCODED_QUERY.path).routeTo({ + controller(QUERY_ENCODED_QUERY) { + Results.status(QUERY_ENCODED_QUERY.status, QUERY_ENCODED_QUERY.body) + } + } as Supplier) + .GET(QUERY_ENCODED_BOTH.rawPath).routeTo({ + controller(QUERY_ENCODED_BOTH) { + Results.status(QUERY_ENCODED_BOTH.status, QUERY_ENCODED_BOTH.body). + withHeader(HttpServerTest.IG_RESPONSE_HEADER, HttpServerTest.IG_RESPONSE_HEADER_VALUE) + } + } as Supplier) + .GET(REDIRECT.path).routeTo({ + controller(REDIRECT) { + Results.found(REDIRECT.body) + } + } as Supplier) + .GET(ERROR.path).routeTo({ + controller(ERROR) { + Results.status(ERROR.status, ERROR.body) + } + } as Supplier) + .GET(EXCEPTION.path).routeTo({ + controller(EXCEPTION) { + throw new RuntimeException(EXCEPTION.body) + } + } as Supplier) + .GET(CUSTOM_EXCEPTION.path).routeAsync({ + controller(CUSTOM_EXCEPTION) { + throw new TestHttpErrorHandler.CustomRuntimeException(CUSTOM_EXCEPTION.body) + } + } as Supplier) + .GET("/path/:id/param").routeTo(PathParamSyncFunction.INSTANCE) + .GET(USER_BLOCK.path).routeTo({ + controller(USER_BLOCK) { + controller(USER_BLOCK) { + Blocking.forUser('user-to-block').blockIfMatch() + Results.status(200, "should never be reached") + } + } + } as Supplier) + .POST(CREATED.path).routeTo({ + -> + controller(CREATED) { + def body = body().asText().get() + Results.status(CREATED.status, "created: $body") + } + } as Supplier) + .POST(BODY_URLENCODED.path).routeTo({ + -> + controller(BODY_URLENCODED) { + def body = body().asFormUrlEncoded().get() + def javaMap = JavaConverters.mapAsJavaMapConverter(body).asJava() + def res = javaMap.collectEntries { + [it.key, JavaConverters.asJavaCollectionConverter(it.value).asJavaCollection()] + } + Results.status(BODY_URLENCODED.status, res as String) + } + } as Supplier) + .POST(BODY_MULTIPART.path).routeTo({ + -> + controller(BODY_MULTIPART) { + def body = body().asMultipartFormData().get().asFormUrlEncoded() + def javaMap = JavaConverters.mapAsJavaMapConverter(body).asJava() + def res = javaMap.collectEntries { + [it.key, JavaConverters.asJavaCollectionConverter(it.value).asJavaCollection()] + } + Results.status(BODY_MULTIPART.status, res as String) + } + } as Supplier) + .POST(BODY_JSON.path).routeTo({ + -> + controller(BODY_JSON) { + JsValue json = body().asJson().get() + Results.status(BODY_JSON.status, new ObjectMapper().readTree(json.toString())) + } + } as Supplier) + .POST(BODY_XML.path).routeTo({ + -> + controller(BODY_XML) { + NodeSeq node = body().asXml().get() + Results.status(BODY_XML.status, node.toString()) + } + } as Supplier) + .build() + } + + static Router async26(ExecutorService executor, BuiltInComponents components) { + ExecutionContextExecutor execContext = HttpExecution.fromThread(executor) + RoutingDsl.fromComponents(components) + .GET(SUCCESS.getPath()).routeAsync({ + CompletableFuture.supplyAsync({ + controller(SUCCESS) { + Results.status(SUCCESS.getStatus(), SUCCESS.getBody()) + } + }, execContext) + } as Supplier) + .GET(FORWARDED.getPath()).routeAsync({ + CompletableFuture.supplyAsync({ + controller(FORWARDED) { + Results.status(FORWARDED.getStatus(), FORWARDED.getBody()) // cheating + } + }, execContext) + } as Supplier) + .GET(QUERY_PARAM.getPath()).routeAsync({ + CompletableFuture.supplyAsync({ + controller(QUERY_PARAM) { + Results.status(QUERY_PARAM.getStatus(), QUERY_PARAM.getBody()) // cheating + } + }, execContext) + } as Supplier) + .GET(QUERY_ENCODED_QUERY.getPath()).routeAsync({ + CompletableFuture.supplyAsync({ + controller(QUERY_ENCODED_QUERY) { + Results.status(QUERY_ENCODED_QUERY.getStatus(), QUERY_ENCODED_QUERY.getBody()) // cheating + } + }, execContext) + } as Supplier) + .GET(QUERY_ENCODED_BOTH.getRawPath()).routeAsync({ + CompletableFuture.supplyAsync({ + controller(QUERY_ENCODED_BOTH) { + Results.status(QUERY_ENCODED_BOTH.getStatus(), QUERY_ENCODED_BOTH.getBody()). + withHeader(HttpServerTest.IG_RESPONSE_HEADER, HttpServerTest.IG_RESPONSE_HEADER_VALUE) // cheating + } + }, execContext) + } as Supplier) + .GET(REDIRECT.getPath()).routeAsync({ + CompletableFuture.supplyAsync({ + controller(REDIRECT) { + Results.found(REDIRECT.getBody()) + } + }, execContext) + } as Supplier) + .GET(ERROR.getPath()).routeAsync({ + CompletableFuture.supplyAsync({ + controller(ERROR) { + Results.status(ERROR.getStatus(), ERROR.getBody()) + } + }, execContext) + } as Supplier) + .GET(EXCEPTION.getPath()).routeAsync({ + CompletableFuture.supplyAsync({ + controller(EXCEPTION) { + throw new RuntimeException(EXCEPTION.getBody()) + } + }, execContext) + } as Supplier) + .GET(CUSTOM_EXCEPTION.path).routeAsync({ + CompletableFuture.supplyAsync({ + controller(CUSTOM_EXCEPTION) { + throw new TestHttpErrorHandler.CustomRuntimeException(CUSTOM_EXCEPTION.body) + } + }, execContext) + } as Supplier) + .GET("/path/:id/param").routeAsync(new PathParamAsyncFunction(execContext)) + .GET(USER_BLOCK.path).routeAsync({ + CompletableFuture.supplyAsync({ + -> + controller(USER_BLOCK) { + controller(USER_BLOCK) { + Blocking.forUser('user-to-block').blockIfMatch() + Results.status(200, "should never be reached") + } + } + }, execContext) + } as Supplier) + .POST(CREATED.path).routeAsync({ + -> + def body = body().asText().get() + CompletableFuture.supplyAsync({ + -> + controller(CREATED) { + Results.status(CREATED.status, "created: $body") + } + }, execContext) + } as Supplier) + .POST(BODY_URLENCODED.path).routeAsync({ + -> + def body = body().asFormUrlEncoded().get() + CompletableFuture.supplyAsync({ + -> + controller(BODY_URLENCODED) { + def javaMap = JavaConverters.mapAsJavaMapConverter(body).asJava() + def res = javaMap.collectEntries { + [it.key, JavaConverters.asJavaCollectionConverter(it.value).asJavaCollection()] + } + Results.status(BODY_URLENCODED.status, res as String) + } + }, execContext) + } as Supplier) + .POST(BODY_MULTIPART.path).routeAsync({ + -> + def body = body().asMultipartFormData().get().asFormUrlEncoded() + CompletableFuture.supplyAsync({ + -> + controller(BODY_MULTIPART) { + def javaMap = JavaConverters.mapAsJavaMapConverter(body).asJava() + def res = javaMap.collectEntries { + [it.key, JavaConverters.asJavaCollectionConverter(it.value).asJavaCollection()] + } + Results.status(BODY_MULTIPART.status, res as String) + } + }, execContext) + } as Supplier) + .POST(BODY_JSON.path).routeAsync({ + -> + JsValue json = body().asJson().get() + CompletableFuture.supplyAsync({ + -> + controller(BODY_JSON) { + Results.status(BODY_JSON.status, new ObjectMapper().readTree(json.toString())) + } + }, execContext) + } as Supplier) + .POST(BODY_XML.path).routeAsync({ + -> + NodeSeq node = body().asXml().get() + CompletableFuture.supplyAsync({ + -> + controller(BODY_XML) { + Results.status(BODY_XML.status, node.toString()) + } + }, execContext) + } as Supplier) + .build() + } + + private static AnyContent body() { + Http.Context.current()._requestHeader().body + } + + @CompileStatic + static enum PathParamSyncFunction implements Function { + INSTANCE + + @Override + Result apply(Integer i) { + controller(PATH_PARAM) { + Results.ok(i as String) + } + } + } + + @CompileStatic + static class PathParamAsyncFunction implements Function> { + private final Executor executor + + PathParamAsyncFunction(Executor executor) { + this.executor = executor + } + + @Override + CompletionStage apply(Integer i) { + CompletableFuture.supplyAsync({ + controller(PATH_PARAM) { + Results.ok(i as String) + } + }, executor) + } + } +} diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy new file mode 100644 index 00000000000..2f5b1f27f96 --- /dev/null +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy @@ -0,0 +1,178 @@ +package datadog.trace.instrumentation.play26.server + +import datadog.trace.agent.test.asserts.TraceAssert +import datadog.trace.agent.test.base.HttpServer +import datadog.trace.agent.test.base.HttpServerTest +import datadog.trace.api.DDSpanTypes +import datadog.trace.api.DDTags +import datadog.trace.bootstrap.instrumentation.api.Tags +import datadog.trace.instrumentation.play26.PlayHttpServerDecorator +import groovy.transform.CompileStatic +import okhttp3.MediaType +import okhttp3.RequestBody +import play.server.Server + +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_XML +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CUSTOM_EXCEPTION +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.EXCEPTION +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.FORWARDED +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS + +class PlayServerTest extends HttpServerTest { + + @Override + @CompileStatic + HttpServer server() { + new PlayHttpServer(PlayRouters.&sync) + } + + @Override + void stopServer(Server server) { + server.stop() + } + + @Override + String component() { + 'akka-http-server' + } + + @Override + String expectedOperationName() { + 'akka-http.request' + } + + @Override + boolean hasHandlerSpan() { + true + } + + @Override + boolean hasExtraErrorInformation() { + true + } + + @Override + boolean changesAll404s() { + true + } + + boolean testExceptionBody() { + // I can't figure out how to set a proper exception handler to customize the response body. + false + } + + @Override + boolean testRequestBody() { + true + } + + @Override + boolean isRequestBodyNoStreaming() { + true + } + + @Override + boolean testBodyUrlencoded() { + true + } + + @Override + boolean testBodyMultipart() { + true + } + + @Override + boolean testBodyJson() { + true + } + + @Override + boolean testBlocking() { + true + } + + @Override + boolean testBlockingOnResponse() { + true + } + + @Override + boolean testResponseBodyJson() { + true + } + + @Override + String testPathParam() { + '/path/?/param' + } + + @Override + Map expectedIGPathParams() { + ['0': 123] + } + + @Override + Class expectedExceptionType() { + RuntimeException + } + + @Override + Class expectedCustomExceptionType() { + TestHttpErrorHandler.CustomRuntimeException + } + + @Override + void handlerSpan(TraceAssert trace, ServerEndpoint endpoint = SUCCESS) { + def expectedQueryTag = expectedQueryTag(endpoint) + trace.span { + serviceName expectedServiceName() + operationName "play.request" + spanType DDSpanTypes.HTTP_SERVER + errored endpoint == EXCEPTION || endpoint == CUSTOM_EXCEPTION + childOfPrevious() + tags { + "$Tags.COMPONENT" PlayHttpServerDecorator.DECORATE.component() + "$Tags.SPAN_KIND" Tags.SPAN_KIND_SERVER + "$Tags.PEER_HOST_IPV4" '127.0.0.1' + "$Tags.HTTP_CLIENT_IP" (endpoint == FORWARDED ? endpoint.body : '127.0.0.1') + "$Tags.HTTP_URL" String + "$Tags.HTTP_HOSTNAME" address.host + "$Tags.HTTP_METHOD" String + // BUG + // "$Tags.HTTP_ROUTE" String + if (endpoint == EXCEPTION || endpoint == CUSTOM_EXCEPTION) { + errorTags(endpoint == CUSTOM_EXCEPTION ? TestHttpErrorHandler.CustomRuntimeException : RuntimeException, endpoint.body) + } + if (endpoint.query) { + "$DDTags.HTTP_QUERY" expectedQueryTag + } + defaultTags() + } + } + } + + def 'test instrumentation gateway xml request body'() { + setup: + def request = request( + BODY_XML, 'POST', + RequestBody.create(MediaType.get('text/xml'), 'mytext')) + .build() + def response = client.newCall(request).execute() + if (isDataStreamsEnabled()) { + TEST_DATA_STREAMS_WRITER.waitForGroups(1) + } + String body = response.body().charStream().text + + + expect: + body == BODY_XML.body || body == 'mytext' + + when: + TEST_WRITER.waitForTraces(1) + + then: + TEST_WRITER.get(0).any { + it.getTag('request.body.converted') == '[[children:[mytext, [:]], attributes:[attr:attr_value]]]' + } + } +} diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy new file mode 100644 index 00000000000..6221c5681ce --- /dev/null +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy @@ -0,0 +1,46 @@ +package datadog.trace.instrumentation.play26.server + +import datadog.trace.agent.test.base.HttpServer +import spock.lang.IgnoreIf + +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CUSTOM_EXCEPTION + +class PlayServerWithErrorHandlerTest extends PlayServerTest { + @Override + HttpServer server() { + new PlayHttpServer(PlayRouters.&sync, new TestHttpErrorHandler()) + } + + @Override + boolean testExceptionBody() { + true + } + + @IgnoreIf({ !instance.testException() }) + def "test exception with custom status"() { + setup: + def request = request(CUSTOM_EXCEPTION, 'GET', null).build() + def response = client.newCall(request).execute() + + expect: + response.code() == CUSTOM_EXCEPTION.status + if (testExceptionBody()) { + assert response.body().string() == CUSTOM_EXCEPTION.body + } + + and: + assertTraces(1) { + trace(spanCount(CUSTOM_EXCEPTION)) { + sortSpansByStart() + serverSpan(it, null, null, 'GET', CUSTOM_EXCEPTION) + if (hasHandlerSpan()) { + handlerSpan(it, CUSTOM_EXCEPTION) + } + controllerSpan(it, CUSTOM_EXCEPTION) + if (hasResponseSpan(CUSTOM_EXCEPTION)) { + responseSpan(it, CUSTOM_EXCEPTION) + } + } + } + } +} diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/java/datadog/trace/instrumentation/play26/server/TestHttpErrorHandler.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/java/datadog/trace/instrumentation/play26/server/TestHttpErrorHandler.java new file mode 100644 index 00000000000..f4a4055480c --- /dev/null +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/java/datadog/trace/instrumentation/play26/server/TestHttpErrorHandler.java @@ -0,0 +1,42 @@ +package datadog.trace.instrumentation.play26.server; + +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CUSTOM_EXCEPTION; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import play.http.HttpErrorHandler; +import play.mvc.Http.RequestHeader; +import play.mvc.Result; +import play.mvc.Results; + +public class TestHttpErrorHandler implements HttpErrorHandler { + private static final Logger log = LoggerFactory.getLogger(TestHttpErrorHandler.class); + + public static class CustomRuntimeException extends RuntimeException { + public CustomRuntimeException(String message) { + super(message); + } + } + + public CompletionStage onClientError( + RequestHeader request, int statusCode, String message) { + return CompletableFuture.completedFuture(Results.status(statusCode, message)); + } + + public CompletionStage onServerError(RequestHeader request, Throwable exception) { + log.warn("server error", exception); + + Throwable cause = exception.getCause(); + if (cause != null) { + exception = cause; + } + if (exception instanceof CustomRuntimeException) { + return CompletableFuture.completedFuture( + Results.status(CUSTOM_EXCEPTION.getStatus(), exception.getMessage())); + } + + return CompletableFuture.completedFuture(Results.internalServerError(exception.getMessage())); + } +} diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/ArgumentCaptureWrappers.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/ArgumentCaptureWrappers.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/ArgumentCaptureWrappers.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/ArgumentCaptureWrappers.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/BodyParserHelpers.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/BodyParserHelpers.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/BodyParserHelpers.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/BodyParserHelpers.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/DelegatingBodyParserInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/DelegatingBodyParserInstrumentation.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/DelegatingBodyParserInstrumentation.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/DelegatingBodyParserInstrumentation.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/FormUrlEncodedInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/FormUrlEncodedInstrumentation.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/FormUrlEncodedInstrumentation.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/FormUrlEncodedInstrumentation.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/HttpErrorHandlerInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/HttpErrorHandlerInstrumentation.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/HttpErrorHandlerInstrumentation.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/HttpErrorHandlerInstrumentation.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/JavaMultipartFormDataRegisterExcF.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/JavaMultipartFormDataRegisterExcF.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/JavaMultipartFormDataRegisterExcF.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/JavaMultipartFormDataRegisterExcF.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/NoDeclaredMethodMatcher.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/NoDeclaredMethodMatcher.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/NoDeclaredMethodMatcher.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/NoDeclaredMethodMatcher.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PathExtractionHelpers.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PathExtractionHelpers.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PathExtractionHelpers.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PathExtractionHelpers.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PathPatternInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PathPatternInstrumentation.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PathPatternInstrumentation.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PathPatternInstrumentation.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PlayBodyParsersInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PlayBodyParsersInstrumentation.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PlayBodyParsersInstrumentation.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PlayBodyParsersInstrumentation.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/ResultsStatusInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/ResultsStatusInstrumentation.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/ResultsStatusInstrumentation.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/ResultsStatusInstrumentation.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/RoutingDslInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/RoutingDslInstrumentation.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/RoutingDslInstrumentation.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/RoutingDslInstrumentation.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/SirdPathExtractorInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/SirdPathExtractorInstrumentation.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/SirdPathExtractorInstrumentation.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/SirdPathExtractorInstrumentation.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/StatusHeaderInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/StatusHeaderInstrumentation.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/StatusHeaderInstrumentation.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/StatusHeaderInstrumentation.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/TolerantJsonInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/TolerantJsonInstrumentation.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/TolerantJsonInstrumentation.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/TolerantJsonInstrumentation.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/TolerantTextInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/TolerantTextInstrumentation.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/TolerantTextInstrumentation.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/TolerantTextInstrumentation.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/TolerantXmlInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/TolerantXmlInstrumentation.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/TolerantXmlInstrumentation.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/TolerantXmlInstrumentation.java diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/.gitignore b/dd-java-agent/instrumentation/play/play-appsec-2.7/.gitignore new file mode 100644 index 00000000000..192221b47d1 --- /dev/null +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/.gitignore @@ -0,0 +1,2 @@ +.gradle/ +build/ \ No newline at end of file diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle b/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle new file mode 100644 index 00000000000..4d8ef6fc8e2 --- /dev/null +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle @@ -0,0 +1,149 @@ +def scalaVersion = '2.11' +def playVersion = '2.7.0' + +muzzle { + extraRepository("typesafe", "https://repo.typesafe.com/typesafe/maven-releases/") + + pass { + name = 'play27' + group = 'com.typesafe.play' + module = 'play-java_2.11' + versions = "[2.7.0,)" + assertInverse = true + javaVersion = 11 + } + pass { + name = 'play27' + group = 'com.typesafe.play' + module = 'play-java_2.12' + versions = "[2.7.0,)" + assertInverse = true + javaVersion = 11 + } + pass { + name = 'play27' + group = 'com.typesafe.play' + module = 'play-java_2.13' + versions = "[2.7.0,)" + assertInverse = true + javaVersion = 11 + } +} + +apply from: "$rootDir/gradle/java.gradle" +apply plugin: 'scala' + +testJvmConstraints { + minJavaVersion = JavaVersion.VERSION_11 +} + +repositories { + maven { + name = 'typesafe' + url = 'https://repo.typesafe.com/typesafe/maven-releases/' + } +} + +addTestSuite('latestDepTest') + +dependencies { + compileOnly group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion + compileOnly project(':dd-java-agent:instrumentation:play:play-2.6') + + latestDepTestImplementation libs.scala213 + latestDepTestImplementation project(':dd-java-agent:instrumentation:play:play-2.6') + latestDepTestImplementation project(':dd-java-agent:instrumentation:play:play-2.6').sourceSets.baseTest.output + latestDepTestImplementation group: 'com.typesafe.play', name: "play-java_2.13", version: '2.+' + latestDepTestImplementation(group: 'com.typesafe.play', name: "play-test_2.13", version: '2.+') { + exclude group: 'org.eclipse.jetty.websocket', module: 'websocket-client' + } + latestDepTestImplementation group: 'com.typesafe.play', name: 'play-akka-http-server_2.13', version: '2.+' + + testRuntimeOnly project(':dd-java-agent:instrumentation:netty:netty-4.0') + testRuntimeOnly project(':dd-java-agent:instrumentation:netty:netty-4.1') + testRuntimeOnly project(':dd-java-agent:instrumentation:akka:akka-http:akka-http-10.0') + testRuntimeOnly project(':dd-java-agent:instrumentation:akka:akka-actor-2.5') + testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-concurrent-2.8') + testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-promise:scala-promise-2.10') + testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-promise:scala-promise-2.13') +} + +configurations.matching({ it.name.startsWith('latestDepTest') }).configureEach({ + it.resolutionStrategy { + // logback-classic 1.4.11 doesn't like being loaded in the bootstrap classloader (NPE) + force group: 'ch.qos.logback', name: 'logback-classic', version: '1.4.5' + } +}) + +tasks.named("compileLatestDepTestJava", JavaCompile) { + configureCompiler(it, 11) +} + +tasks.named("compileLatestDepTestScala", ScalaCompile) { + configureCompiler(it, 11) +} + +tasks.named("latestDepTest", Test) { + javaLauncher = getJavaLauncherFor(11) +} + +final generatedRoutes = layout.buildDirectory.dir('generated/sources/latestDepTestRoutes/scala') +sourceSets { + routeGenerator { + scala { + srcDir "${project.projectDir}/src/routeGenerator/scala" + } + } + latestDepTestGenerated { + scala { + srcDir generatedRoutes + } + } +} + +dependencies { + routeGeneratorImplementation libs.scala213 + routeGeneratorImplementation group: 'com.typesafe.play', name: "routes-compiler_2.13", version: '2.+' +} + +configurations { + latestDepTestGeneratedCompileClasspath.extendsFrom(latestDepTestCompileClasspath) +} + +tasks.register('buildLatestDepTestRoutes', JavaExec) { + String routesFile = "${project.projectDir}/src/latestDepTest/routes/conf/routes" + def outputDir = generatedRoutes + + it.inputs.file routesFile + it.outputs.dir outputDir + + it.mainClass = 'generator.CompileRoutes' + it.args routesFile, outputDir.get().asFile.absolutePath + + it.classpath configurations.named('routeGeneratorRuntimeClasspath') + it.classpath tasks.named('compileRouteGeneratorScala').map { it.destinationDirectory } + it.classpath tasks.named('compileLatestDepTestScala').map { it.destinationDirectory } + + it.javaLauncher = getJavaLauncherFor(11) +} + +tasks.named("compileLatestDepTestGeneratedScala", ScalaCompile) { + configureCompiler(it, 11) + classpath = classpath + files(tasks.named('compileLatestDepTestScala').map { it.destinationDirectory }) + dependsOn 'buildLatestDepTestRoutes' +} + +tasks.named("forbiddenApisLatestDepTestGenerated") { + enabled = false +} + +tasks.named("compileLatestDepTestGroovy", GroovyCompile) { + configureCompiler(it, 11) + classpath = classpath + + files(tasks.named('compileLatestDepTestScala').map { it.destinationDirectory }) + + files(tasks.named('compileLatestDepTestGeneratedScala').map { it.destinationDirectory }) +} + +dependencies { + latestDepTestRuntimeOnly sourceSets.latestDepTestGenerated.output +} \ No newline at end of file diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerScalaWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerScalaWithErrorHandlerTest.groovy similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerScalaWithErrorHandlerTest.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerScalaWithErrorHandlerTest.groovy diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayHttpServerScala.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayHttpServerScala.groovy similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayHttpServerScala.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayHttpServerScala.groovy diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayRouters.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayRouters.groovy similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayRouters.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayRouters.groovy diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/latestDepTest/routes/conf/routes b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/routes/conf/routes similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/latestDepTest/routes/conf/routes rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/routes/conf/routes diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/ImplicitConversions.scala b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/ImplicitConversions.scala similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/ImplicitConversions.scala rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/ImplicitConversions.scala diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayController.scala b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayController.scala similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayController.scala rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayController.scala diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayRoutersScala.scala b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayRoutersScala.scala similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayRoutersScala.scala rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayRoutersScala.scala diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java_play27/datadog/trace/instrumentation/play27/appsec/ArgumentCaptureAdvice.java b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/main/java/datadog/trace/instrumentation/play27/appsec/ArgumentCaptureAdvice.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java_play27/datadog/trace/instrumentation/play27/appsec/ArgumentCaptureAdvice.java rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/main/java/datadog/trace/instrumentation/play27/appsec/ArgumentCaptureAdvice.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play27/appsec/RoutingDsl27Instrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/main/java/datadog/trace/instrumentation/play27/appsec/RoutingDsl27Instrumentation.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/main/java/datadog/trace/instrumentation/play27/appsec/RoutingDsl27Instrumentation.java rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/main/java/datadog/trace/instrumentation/play27/appsec/RoutingDsl27Instrumentation.java diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/routeGenerator/scala/generator/CompileRoutes.scala b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/routeGenerator/scala/generator/CompileRoutes.scala similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/routeGenerator/scala/generator/CompileRoutes.scala rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/routeGenerator/scala/generator/CompileRoutes.scala diff --git a/settings.gradle.kts b/settings.gradle.kts index ee2b2bd34b9..5e65ee180de 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -502,6 +502,8 @@ include( ":dd-java-agent:instrumentation:play:play-2.4", ":dd-java-agent:instrumentation:play:play-appsec-2.5", ":dd-java-agent:instrumentation:play:play-2.6", + ":dd-java-agent:instrumentation:play:play-appsec-2.6", + ":dd-java-agent:instrumentation:play:play-appsec-2.7", ":dd-java-agent:instrumentation:protobuf-3.0", ":dd-java-agent:instrumentation:quartz-2.0", ":dd-java-agent:instrumentation:rabbitmq-amqp-2.7", From 7f9456cd16e32aecd8ccce21260dd10f26226064 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Fri, 2 Jan 2026 14:17:23 +0100 Subject: [PATCH 02/12] wip --- .../TestJvmConstraintsUtils.kt | 4 +- .../play/play-2.6/build.gradle | 20 ++++- .../play26/server/PlayAsyncServerTest.groovy | 2 +- ...PlayAsyncServerWithErrorHandlerTest.groovy | 0 .../play26/server/PlayServerTest.groovy | 33 +++++++++ .../PlayServerWithErrorHandlerTest.groovy | 13 +--- .../server/AbstractPlayServerTest.groovy} | 30 +------- ...tractPlayServerWithErrorHandlerTest.groovy | 15 ++++ .../play26/server/PlayHttpServer.groovy | 0 .../play26/server/PlayRouters.groovy | 13 +--- .../play26/server/TestHttpErrorHandler.java | 0 .../play/play-appsec-2.5/build.gradle | 1 + .../appsec/ArgumentCaptureWrappers.java | 1 + .../play25/appsec/PathPatternApplyAdvice.java | 1 + .../appsec/PathPatternInstrumentation.java | 2 +- .../appsec/RoutingDslInstrumentation.java | 2 +- .../SirdPathExtractorExtractAdvice.java | 1 + .../SirdPathExtractorInstrumentation.java | 2 +- .../play/play-appsec-2.6/build.gradle | 15 ++-- .../appsec/ArgumentCaptureWrappers.java | 1 + .../play26/appsec/PathExtractionHelpers.java | 58 --------------- .../appsec/PathPatternInstrumentation.java | 3 +- .../appsec/RoutingDslInstrumentation.java | 2 +- .../SirdPathExtractorInstrumentation.java | 3 +- .../play26/server/PlayAsyncServerTest.groovy | 0 ...PlayAsyncServerWithErrorHandlerTest.groovy | 0 .../play26/server/PlayHttpServer.groovy | 0 .../play26/server/PlayRouters.groovy | 0 .../play26/server/PlayServerTest.groovy | 0 .../PlayServerWithErrorHandlerTest.groovy | 0 .../play26/server/TestHttpErrorHandler.java | 0 .../play/play-appsec-2.7/build.gradle | 73 +++++++++++-------- .../play27/appsec/ArgumentCaptureAdvice.java | 2 +- .../appsec/RoutingDsl27Instrumentation.java | 2 +- ...actPlayServer27WithErrorHandlerTest.groovy | 13 ++++ .../server/latestdep/Play27Routers.groovy} | 2 +- ...rverRoutesScalaWithErrorHandlerTest.groovy | 3 +- ...syncServerScalaWithErrorHandlerTest.groovy | 3 +- .../latestdep/PlayHttpServerScala.groovy | 0 .../routes/conf/routes | 0 .../latestdep/ImplicitConversions.scala | 0 .../server/latestdep/PlayController.scala | 0 .../server/latestdep/PlayRoutersScala.scala | 0 .../play/play-appsec-common/build.gradle | 3 + .../play}/appsec/PathExtractionHelpers.java | 2 +- settings.gradle.kts | 3 +- 46 files changed, 159 insertions(+), 169 deletions(-) rename dd-java-agent/instrumentation/play/{play-appsec-2.6/src/baseTest => play-2.6/src/test}/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy (88%) rename dd-java-agent/instrumentation/play/play-2.6/src/{baseTest => test}/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy (100%) create mode 100644 dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy rename dd-java-agent/instrumentation/play/{play-appsec-2.6/src/baseTest => play-2.6/src/test}/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy (77%) rename dd-java-agent/instrumentation/play/{play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy => play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerTest.groovy} (78%) create mode 100644 dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerWithErrorHandlerTest.groovy rename dd-java-agent/instrumentation/play/play-2.6/src/{baseTest => testFixtures}/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy (100%) rename dd-java-agent/instrumentation/play/{play-appsec-2.6/src/baseTest => play-2.6/src/testFixtures}/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy (96%) rename dd-java-agent/instrumentation/play/play-2.6/src/{baseTest => testFixtures}/java/datadog/trace/instrumentation/play26/server/TestHttpErrorHandler.java (100%) delete mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PathExtractionHelpers.java rename dd-java-agent/instrumentation/play/{play-2.6/src/baseTest => play-appsec-2.6/src/test}/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy (100%) rename dd-java-agent/instrumentation/play/play-appsec-2.6/src/{baseTest => test}/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy (100%) rename dd-java-agent/instrumentation/play/play-appsec-2.6/src/{baseTest => test}/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy (100%) rename dd-java-agent/instrumentation/play/{play-2.6/src/baseTest => play-appsec-2.6/src/test}/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy (100%) rename dd-java-agent/instrumentation/play/{play-2.6/src/baseTest => play-appsec-2.6/src/test}/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy (100%) rename dd-java-agent/instrumentation/play/{play-2.6/src/baseTest => play-appsec-2.6/src/test}/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy (100%) rename dd-java-agent/instrumentation/play/play-appsec-2.6/src/{baseTest => test}/java/datadog/trace/instrumentation/play26/server/TestHttpErrorHandler.java (100%) create mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/AbstractPlayServer27WithErrorHandlerTest.groovy rename dd-java-agent/instrumentation/play/play-appsec-2.7/src/{latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayRouters.groovy => test/groovy/datadog/trace/instrumentation/play26/server/latestdep/Play27Routers.groovy} (99%) rename dd-java-agent/instrumentation/play/play-appsec-2.7/src/{latestDepTest => test}/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy (95%) rename dd-java-agent/instrumentation/play/play-appsec-2.7/src/{latestDepTest => test}/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerScalaWithErrorHandlerTest.groovy (83%) rename dd-java-agent/instrumentation/play/play-appsec-2.7/src/{latestDepTest => test}/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayHttpServerScala.groovy (100%) rename dd-java-agent/instrumentation/play/play-appsec-2.7/src/{latestDepTest => test}/routes/conf/routes (100%) rename dd-java-agent/instrumentation/play/play-appsec-2.7/src/{latestDepTest => test}/scala/datadog/trace/instrumentation/play26/server/latestdep/ImplicitConversions.scala (100%) rename dd-java-agent/instrumentation/play/play-appsec-2.7/src/{latestDepTest => test}/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayController.scala (100%) rename dd-java-agent/instrumentation/play/play-appsec-2.7/src/{latestDepTest => test}/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayRoutersScala.scala (100%) create mode 100644 dd-java-agent/instrumentation/play/play-appsec-common/build.gradle rename dd-java-agent/instrumentation/play/{play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25 => play-appsec-common/src/main/java/datadog/trace/instrumentation/play}/appsec/PathExtractionHelpers.java (97%) diff --git a/buildSrc/src/main/kotlin/datadog/gradle/plugin/testJvmConstraints/TestJvmConstraintsUtils.kt b/buildSrc/src/main/kotlin/datadog/gradle/plugin/testJvmConstraints/TestJvmConstraintsUtils.kt index f8e70ed186b..a8c5ddf69f6 100644 --- a/buildSrc/src/main/kotlin/datadog/gradle/plugin/testJvmConstraints/TestJvmConstraintsUtils.kt +++ b/buildSrc/src/main/kotlin/datadog/gradle/plugin/testJvmConstraints/TestJvmConstraintsUtils.kt @@ -33,12 +33,12 @@ private fun TestJvmConstraintsExtension.withinAllowedRange(currentJvmVersion: Ja val definedMax = maxJavaVersion.isPresent if (definedMin && (minJavaVersion.get()) > currentJvmVersion) { - logger.info("isWithinAllowedRange returns false b/o minProp=${minJavaVersion.get()} is defined and greater than version=$currentJvmVersion") + logger.info("'isWithinAllowedRange' returns false b/o testJvmConstraints.minJavaVersion=${minJavaVersion.get()} is defined and greater than test JVM version=$currentJvmVersion") return false } if (definedMax && (maxJavaVersion.get()) < currentJvmVersion) { - logger.info("isWithinAllowedRange returns false b/o maxProp=${maxJavaVersion.get()} is defined and lower than version=$currentJvmVersion") + logger.info("'isWithinAllowedRange' returns false because testJvmConstraints.maxJavaVersion=${maxJavaVersion.get()} is defined and lower than test JVM version=$currentJvmVersion") return false } diff --git a/dd-java-agent/instrumentation/play/play-2.6/build.gradle b/dd-java-agent/instrumentation/play/play-2.6/build.gradle index 570f934df6a..9c5aee0f47c 100644 --- a/dd-java-agent/instrumentation/play/play-2.6/build.gradle +++ b/dd-java-agent/instrumentation/play/play-2.6/build.gradle @@ -39,6 +39,7 @@ muzzle { apply from: "$rootDir/gradle/java.gradle" apply plugin: 'scala' +apply plugin: 'groovy' apply plugin: 'java-test-fixtures' testJvmConstraints { @@ -55,15 +56,22 @@ repositories { } } -addTestSuite('baseTest') - dependencies { compileOnly group: 'com.typesafe.play', name: "play_$scalaVersion", version: playVersion compileOnly group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion - baseTestImplementation group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion + testFixturesCompileOnly group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion // TODO: Play WS is a separately versioned library starting with 2.6 and needs separate instrumentation. - baseTestImplementation(group: 'com.typesafe.play', name: "play-test_$scalaVersion", version: playVersion) { + testFixturesCompileOnly(group: 'com.typesafe.play', name: "play-test_$scalaVersion", version: playVersion) { + exclude group: 'org.eclipse.jetty.websocket', module: 'websocket-client' + } + testFixturesApi project(':dd-java-agent:instrumentation-testing') + testFixturesApi libs.spock.core + + testImplementation group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion + testImplementation testFixtures(project(':dd-java-agent:instrumentation:play:play-2.6')) + testImplementation group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion + testImplementation(group: 'com.typesafe.play', name: "play-test_$scalaVersion", version: playVersion) { exclude group: 'org.eclipse.jetty.websocket', module: 'websocket-client' } @@ -75,3 +83,7 @@ dependencies { testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-promise:scala-promise-2.10') testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-promise:scala-promise-2.13') } + +// tasks.named('forbiddenApisTestFixtures') { +// enabled = false +// } diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy b/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy similarity index 88% rename from dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy rename to dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy index 4d9e443369d..4155deea955 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy @@ -6,7 +6,7 @@ import spock.lang.Shared import java.util.concurrent.Executors -class PlayAsyncServerTest extends PlayServerTest { +class PlayAsyncServerTest extends AbstractPlayServerTest { @Shared def executor diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy rename to dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy b/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy new file mode 100644 index 00000000000..bea9c5fe9ca --- /dev/null +++ b/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy @@ -0,0 +1,33 @@ +package datadog.trace.instrumentation.play26.server + +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_XML + +import okhttp3.MediaType +import okhttp3.RequestBody + +class PlayServerTest extends AbstractPlayServerTest { + def 'test instrumentation gateway xml request body'() { + setup: + def request = request( + BODY_XML, 'POST', + RequestBody.create(MediaType.get('text/xml'), 'mytext')) + .build() + def response = client.newCall(request).execute() + if (isDataStreamsEnabled()) { + TEST_DATA_STREAMS_WRITER.waitForGroups(1) + } + String body = response.body().charStream().text + + + expect: + body == BODY_XML.body || body == 'mytext' + + when: + TEST_WRITER.waitForTraces(1) + + then: + TEST_WRITER.get(0).any { + it.getTag('request.body.converted') == '[[children:[mytext, [:]], attributes:[attr:attr_value]]]' + } + } +} diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy similarity index 77% rename from dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy rename to dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy index 6221c5681ce..1b3597150d4 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy @@ -1,21 +1,10 @@ package datadog.trace.instrumentation.play26.server -import datadog.trace.agent.test.base.HttpServer import spock.lang.IgnoreIf import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CUSTOM_EXCEPTION -class PlayServerWithErrorHandlerTest extends PlayServerTest { - @Override - HttpServer server() { - new PlayHttpServer(PlayRouters.&sync, new TestHttpErrorHandler()) - } - - @Override - boolean testExceptionBody() { - true - } - +class PlayServerWithErrorHandlerTest extends AbstractPlayServerTest { @IgnoreIf({ !instance.testException() }) def "test exception with custom status"() { setup: diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy b/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerTest.groovy similarity index 78% rename from dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy rename to dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerTest.groovy index 2f5b1f27f96..741d3fb50fd 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerTest.groovy @@ -8,17 +8,14 @@ import datadog.trace.api.DDTags import datadog.trace.bootstrap.instrumentation.api.Tags import datadog.trace.instrumentation.play26.PlayHttpServerDecorator import groovy.transform.CompileStatic -import okhttp3.MediaType -import okhttp3.RequestBody import play.server.Server -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_XML import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CUSTOM_EXCEPTION import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.EXCEPTION import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.FORWARDED import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS -class PlayServerTest extends HttpServerTest { +class AbstractPlayServerTest extends HttpServerTest { @Override @CompileStatic @@ -150,29 +147,4 @@ class PlayServerTest extends HttpServerTest { } } } - - def 'test instrumentation gateway xml request body'() { - setup: - def request = request( - BODY_XML, 'POST', - RequestBody.create(MediaType.get('text/xml'), 'mytext')) - .build() - def response = client.newCall(request).execute() - if (isDataStreamsEnabled()) { - TEST_DATA_STREAMS_WRITER.waitForGroups(1) - } - String body = response.body().charStream().text - - - expect: - body == BODY_XML.body || body == 'mytext' - - when: - TEST_WRITER.waitForTraces(1) - - then: - TEST_WRITER.get(0).any { - it.getTag('request.body.converted') == '[[children:[mytext, [:]], attributes:[attr:attr_value]]]' - } - } } diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerWithErrorHandlerTest.groovy new file mode 100644 index 00000000000..9b34bdddb51 --- /dev/null +++ b/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerWithErrorHandlerTest.groovy @@ -0,0 +1,15 @@ +package datadog.trace.instrumentation.play26.server + +import datadog.trace.agent.test.base.HttpServer + +abstract class AbstractPlayServerWithErrorHandlerTest extends AbstractPlayServerTest { + @Override + HttpServer server() { + new PlayHttpServer(PlayRouters.&sync, new TestHttpErrorHandler()) + } + + @Override + boolean testExceptionBody() { + true + } +} diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy b/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy rename to dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy b/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy similarity index 96% rename from dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy rename to dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy index c2226b78f6d..41195d7ac33 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy +++ b/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy @@ -41,23 +41,14 @@ import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.REDIRE import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.USER_BLOCK import static datadog.trace.agent.test.base.HttpServerTest.controller -import static java.lang.Class.forName class PlayRouters { static Router sync(BuiltInComponents components) { - try { - forName("datadog.trace.instrumentation.play26.server.latestdep.PlayRouters").sync components - } catch (ClassNotFoundException cnf) { - sync26(components) - } + sync26(components) } static Router async(ExecutorService executor, BuiltInComponents components) { - try { - forName("datadog.trace.instrumentation.play26.server.latestdep.PlayRouters").async executor, components - } catch (ClassNotFoundException cnf) { - async26(executor, components) - } + async26(executor, components) } private static Router sync26(BuiltInComponents components) { diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/baseTest/java/datadog/trace/instrumentation/play26/server/TestHttpErrorHandler.java b/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/java/datadog/trace/instrumentation/play26/server/TestHttpErrorHandler.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/baseTest/java/datadog/trace/instrumentation/play26/server/TestHttpErrorHandler.java rename to dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/java/datadog/trace/instrumentation/play26/server/TestHttpErrorHandler.java diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.5/build.gradle b/dd-java-agent/instrumentation/play/play-appsec-2.5/build.gradle index 6f10dfeebdd..5fa79c91539 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.5/build.gradle +++ b/dd-java-agent/instrumentation/play/play-appsec-2.5/build.gradle @@ -34,6 +34,7 @@ addTestSuiteForDir('latestDepTest', 'test') dependencies { compileOnly group: 'com.typesafe.play', name: 'play_2.11', version: '2.5.0' + implementation(project(':dd-java-agent:instrumentation:play:play-appsec-common')) testRuntimeOnly project(':dd-java-agent:instrumentation:netty:netty-4.0') testRuntimeOnly project(':dd-java-agent:instrumentation:netty:netty-4.1') diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/ArgumentCaptureWrappers.java b/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/ArgumentCaptureWrappers.java index 2eb39277e5d..8b7c89dcc8f 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/ArgumentCaptureWrappers.java +++ b/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/ArgumentCaptureWrappers.java @@ -6,6 +6,7 @@ import datadog.trace.api.gateway.RequestContext; import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.instrumentation.play.appsec.PathExtractionHelpers; import java.util.Collections; import java.util.HashMap; import java.util.Map; diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/PathPatternApplyAdvice.java b/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/PathPatternApplyAdvice.java index 7eab9542568..7ff4f4f80e3 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/PathPatternApplyAdvice.java +++ b/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/PathPatternApplyAdvice.java @@ -5,6 +5,7 @@ import datadog.trace.advice.RequiresRequestContext; import datadog.trace.api.gateway.RequestContext; import datadog.trace.api.gateway.RequestContextSlot; +import datadog.trace.instrumentation.play.appsec.PathExtractionHelpers; import net.bytebuddy.asm.Advice; import scala.Tuple2; import scala.collection.Iterator; diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/PathPatternInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/PathPatternInstrumentation.java index ba78f5d5472..86856d3b199 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/PathPatternInstrumentation.java +++ b/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/PathPatternInstrumentation.java @@ -30,7 +30,7 @@ public Reference[] additionalMuzzleReferences() { @Override public String[] helperClassNames() { return new String[] { - packageName + ".PathExtractionHelpers", + "datadog.trace.instrumentation.play.appsec.PathExtractionHelpers", }; } diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/RoutingDslInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/RoutingDslInstrumentation.java index a548b58fb52..5e975ec2805 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/RoutingDslInstrumentation.java +++ b/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/RoutingDslInstrumentation.java @@ -36,7 +36,7 @@ public String[] helperClassNames() { packageName + ".ArgumentCaptureWrappers$ArgumentCaptureFunction", packageName + ".ArgumentCaptureWrappers$ArgumentCaptureBiFunction", packageName + ".ArgumentCaptureWrappers$ArgumentCaptureFunction3", - packageName + ".PathExtractionHelpers", + "datadog.trace.instrumentation.play.appsec.PathExtractionHelpers", }; } diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/SirdPathExtractorExtractAdvice.java b/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/SirdPathExtractorExtractAdvice.java index 7de650729c0..3770edf4e9f 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/SirdPathExtractorExtractAdvice.java +++ b/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/SirdPathExtractorExtractAdvice.java @@ -4,6 +4,7 @@ import datadog.trace.advice.RequiresRequestContext; import datadog.trace.api.gateway.RequestContext; import datadog.trace.api.gateway.RequestContextSlot; +import datadog.trace.instrumentation.play.appsec.PathExtractionHelpers; import java.util.HashMap; import java.util.Map; import net.bytebuddy.asm.Advice; diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/SirdPathExtractorInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/SirdPathExtractorInstrumentation.java index 3be2f0295be..946a8299fef 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/SirdPathExtractorInstrumentation.java +++ b/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/SirdPathExtractorInstrumentation.java @@ -44,7 +44,7 @@ public void methodAdvice(MethodTransformer transformer) { @Override public String[] helperClassNames() { return new String[] { - packageName + ".PathExtractionHelpers", + "datadog.trace.instrumentation.play.appsec.PathExtractionHelpers", }; } } diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle b/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle index 59cb3770f38..694c6f1debb 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle @@ -45,16 +45,19 @@ repositories { } } -addTestSuite('baseTest') - dependencies { compileOnly group: 'com.typesafe.play', name: "play_$scalaVersion", version: playVersion compileOnly group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion compileOnly project(':dd-java-agent:instrumentation:play:play-2.6') + implementation(project(':dd-java-agent:instrumentation:play:play-appsec-common')) + + // TODO + // * replace with testFixtures when we migrate this module to use java-test-fixtures plugin + // * replace 'baseTest' by 'test' - baseTestImplementation project(':dd-java-agent:instrumentation:play:play-2.6') - baseTestImplementation group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion - baseTestImplementation(group: 'com.typesafe.play', name: "play-test_$scalaVersion", version: playVersion) { + testImplementation project(':dd-java-agent:instrumentation:play:play-2.6') + testImplementation group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion + testImplementation(group: 'com.typesafe.play', name: "play-test_$scalaVersion", version: playVersion) { exclude group: 'org.eclipse.jetty.websocket', module: 'websocket-client' } @@ -65,4 +68,4 @@ dependencies { testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-concurrent-2.8') testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-promise:scala-promise-2.10') testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-promise:scala-promise-2.13') -} \ No newline at end of file +} diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/ArgumentCaptureWrappers.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/ArgumentCaptureWrappers.java index 853fbb39f4a..26f716b3414 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/ArgumentCaptureWrappers.java +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/ArgumentCaptureWrappers.java @@ -6,6 +6,7 @@ import datadog.trace.api.gateway.RequestContext; import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.instrumentation.play.appsec.PathExtractionHelpers; import java.util.Collections; import java.util.HashMap; import java.util.Map; diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PathExtractionHelpers.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PathExtractionHelpers.java deleted file mode 100644 index 5003ec73ee3..00000000000 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PathExtractionHelpers.java +++ /dev/null @@ -1,58 +0,0 @@ -package datadog.trace.instrumentation.play26.appsec; - -import static datadog.trace.api.gateway.Events.EVENTS; - -import datadog.appsec.api.blocking.BlockingException; -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.Map; -import java.util.function.BiFunction; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class PathExtractionHelpers { - private static final Logger log = LoggerFactory.getLogger(PathExtractionHelpers.class); - - private PathExtractionHelpers() {} - - public static BlockingException callRequestPathParamsCallback( - RequestContext reqCtx, Map params, String origin) { - try { - return doCallRequestPathParamsCallback(reqCtx, params, origin); - } catch (Exception e) { - log.warn("Error calling {}", origin, e); - return null; - } - } - - private static BlockingException doCallRequestPathParamsCallback( - RequestContext reqCtx, Map params, String origin) { - if (params == null || params.isEmpty()) { - return null; - } - - CallbackProvider cbp = AgentTracer.get().getCallbackProvider(RequestContextSlot.APPSEC); - BiFunction, Flow> callback = - cbp.getCallback(EVENTS.requestPathParams()); - if (callback == null) { - return null; - } - - Flow flow = callback.apply(reqCtx, params); - Flow.Action action = flow.getAction(); - if (!(action instanceof Flow.Action.RequestBlockingAction)) { - return null; - } - - Flow.Action.RequestBlockingAction rba = (Flow.Action.RequestBlockingAction) action; - BlockResponseFunction brf = reqCtx.getBlockResponseFunction(); - if (brf != null) { - brf.tryCommitBlockingResponse(reqCtx.getTraceSegment(), rba); - } - return new BlockingException("Blocked request (for " + origin + ")"); - } -} diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PathPatternInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PathPatternInstrumentation.java index becc3b54a44..386f2889e81 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PathPatternInstrumentation.java +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/PathPatternInstrumentation.java @@ -16,6 +16,7 @@ import datadog.trace.agent.tooling.muzzle.Reference; import datadog.trace.api.gateway.RequestContext; import datadog.trace.api.gateway.RequestContextSlot; +import datadog.trace.instrumentation.play.appsec.PathExtractionHelpers; import datadog.trace.instrumentation.play26.MuzzleReferences; import net.bytebuddy.asm.Advice; import scala.Tuple2; @@ -40,7 +41,7 @@ public String muzzleDirective() { @Override public String[] helperClassNames() { return new String[] { - packageName + ".PathExtractionHelpers", + "datadog.trace.instrumentation.play.appsec.PathExtractionHelpers", }; } diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/RoutingDslInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/RoutingDslInstrumentation.java index d181146f9e6..ce026f7727d 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/RoutingDslInstrumentation.java +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/RoutingDslInstrumentation.java @@ -58,7 +58,7 @@ public String[] helperClassNames() { packageName + ".ArgumentCaptureWrappers$ArgumentCaptureFunction", packageName + ".ArgumentCaptureWrappers$ArgumentCaptureBiFunction", packageName + ".ArgumentCaptureWrappers$ArgumentCaptureFunction3", - packageName + ".PathExtractionHelpers", + "datadog.trace.instrumentation.play.appsec.PathExtractionHelpers", }; } diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/SirdPathExtractorInstrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/SirdPathExtractorInstrumentation.java index 375c17897ff..3c7844ccec5 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/SirdPathExtractorInstrumentation.java +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/main/java/datadog/trace/instrumentation/play26/appsec/SirdPathExtractorInstrumentation.java @@ -13,6 +13,7 @@ import datadog.trace.agent.tooling.muzzle.Reference; import datadog.trace.api.gateway.RequestContext; import datadog.trace.api.gateway.RequestContextSlot; +import datadog.trace.instrumentation.play.appsec.PathExtractionHelpers; import datadog.trace.instrumentation.play26.MuzzleReferences; import java.util.HashMap; import java.util.Map; @@ -57,7 +58,7 @@ public void methodAdvice(MethodTransformer transformer) { @Override public String[] helperClassNames() { return new String[] { - packageName + ".PathExtractionHelpers", + "datadog.trace.instrumentation.play.appsec.PathExtractionHelpers", }; } diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy similarity index 100% rename from dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy similarity index 100% rename from dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy similarity index 100% rename from dd-java-agent/instrumentation/play/play-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/java/datadog/trace/instrumentation/play26/server/TestHttpErrorHandler.java b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/java/datadog/trace/instrumentation/play26/server/TestHttpErrorHandler.java similarity index 100% rename from dd-java-agent/instrumentation/play/play-appsec-2.6/src/baseTest/java/datadog/trace/instrumentation/play26/server/TestHttpErrorHandler.java rename to dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/java/datadog/trace/instrumentation/play26/server/TestHttpErrorHandler.java diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle b/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle index 4d8ef6fc8e2..f40ad5ec4f2 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle @@ -39,25 +39,36 @@ testJvmConstraints { repositories { maven { + // for muzzle because of play-2.3 + // only place that has 'com.typesafe.netty:netty-http-pipelining:1.1.2' publicly accessible name = 'typesafe' url = 'https://repo.typesafe.com/typesafe/maven-releases/' } } -addTestSuite('latestDepTest') - dependencies { compileOnly group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion - compileOnly project(':dd-java-agent:instrumentation:play:play-2.6') - - latestDepTestImplementation libs.scala213 - latestDepTestImplementation project(':dd-java-agent:instrumentation:play:play-2.6') - latestDepTestImplementation project(':dd-java-agent:instrumentation:play:play-2.6').sourceSets.baseTest.output - latestDepTestImplementation group: 'com.typesafe.play', name: "play-java_2.13", version: '2.+' - latestDepTestImplementation(group: 'com.typesafe.play', name: "play-test_2.13", version: '2.+') { + implementation project(':dd-java-agent:instrumentation:play:play-2.6') + implementation(project(':dd-java-agent:instrumentation:play:play-appsec-common')) + + // TODO + // * [x] replace 'latestDepTest' by 'test' + // * [x] ensure test fixture is used in 'test' instead of 'latestDepTest' + // * [x] use the introduced 'Abstract*Test' classes + // * [ ] router.Routes is generated code, find a way to generate it for tests + + testImplementation libs.scala213 + testImplementation project(':dd-java-agent:instrumentation:play:play-2.6') + // Inherited tests needs play-appsec-2.6 instrumentation + testImplementation project(':dd-java-agent:instrumentation:play:play-appsec-2.6') + testImplementation testFixtures(project(':dd-java-agent:instrumentation:play:play-2.6')) + + testImplementation group: 'com.typesafe.play', name: "play-java_2.13", version: '2.+' + testImplementation(group: 'com.typesafe.play', name: "play-test_2.13", version: '2.+') { exclude group: 'org.eclipse.jetty.websocket', module: 'websocket-client' } - latestDepTestImplementation group: 'com.typesafe.play', name: 'play-akka-http-server_2.13', version: '2.+' + testImplementation group: 'com.typesafe.play', name: 'play-akka-http-server_2.13', version: '2.+' + testRuntimeOnly project(':dd-java-agent:instrumentation:netty:netty-4.0') testRuntimeOnly project(':dd-java-agent:instrumentation:netty:netty-4.1') @@ -68,33 +79,33 @@ dependencies { testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-promise:scala-promise-2.13') } -configurations.matching({ it.name.startsWith('latestDepTest') }).configureEach({ +configurations.matching({ it.name.startsWith('test') }).configureEach({ it.resolutionStrategy { // logback-classic 1.4.11 doesn't like being loaded in the bootstrap classloader (NPE) force group: 'ch.qos.logback', name: 'logback-classic', version: '1.4.5' } }) -tasks.named("compileLatestDepTestJava", JavaCompile) { +tasks.named("compileTestJava", JavaCompile) { configureCompiler(it, 11) } -tasks.named("compileLatestDepTestScala", ScalaCompile) { +tasks.named("compileTestScala", ScalaCompile) { configureCompiler(it, 11) } -tasks.named("latestDepTest", Test) { - javaLauncher = getJavaLauncherFor(11) -} +// tasks.named("latestDepTest", Test) { +// javaLauncher = getJavaLauncherFor(11) +// } -final generatedRoutes = layout.buildDirectory.dir('generated/sources/latestDepTestRoutes/scala') +final generatedRoutes = layout.buildDirectory.dir('generated/sources/testRoutes/scala') sourceSets { routeGenerator { scala { srcDir "${project.projectDir}/src/routeGenerator/scala" } } - latestDepTestGenerated { + testGenerated { scala { srcDir generatedRoutes } @@ -107,11 +118,11 @@ dependencies { } configurations { - latestDepTestGeneratedCompileClasspath.extendsFrom(latestDepTestCompileClasspath) + testGeneratedCompileClasspath.extendsFrom(testCompileClasspath) } -tasks.register('buildLatestDepTestRoutes', JavaExec) { - String routesFile = "${project.projectDir}/src/latestDepTest/routes/conf/routes" +tasks.register('buildTestRoutes', JavaExec) { + String routesFile = "${project.projectDir}/src/test/routes/conf/routes" def outputDir = generatedRoutes it.inputs.file routesFile @@ -122,28 +133,28 @@ tasks.register('buildLatestDepTestRoutes', JavaExec) { it.classpath configurations.named('routeGeneratorRuntimeClasspath') it.classpath tasks.named('compileRouteGeneratorScala').map { it.destinationDirectory } - it.classpath tasks.named('compileLatestDepTestScala').map { it.destinationDirectory } + it.classpath tasks.named('compileTestScala').map { it.destinationDirectory } it.javaLauncher = getJavaLauncherFor(11) } -tasks.named("compileLatestDepTestGeneratedScala", ScalaCompile) { +tasks.named("compileTestGeneratedScala", ScalaCompile) { configureCompiler(it, 11) - classpath = classpath + files(tasks.named('compileLatestDepTestScala').map { it.destinationDirectory }) - dependsOn 'buildLatestDepTestRoutes' + classpath = classpath + files(tasks.named('compileTestScala').map { it.destinationDirectory }) + dependsOn 'buildTestRoutes' } -tasks.named("forbiddenApisLatestDepTestGenerated") { +tasks.named("forbiddenApisTestGenerated") { enabled = false } -tasks.named("compileLatestDepTestGroovy", GroovyCompile) { +tasks.named("compileTestGroovy", GroovyCompile) { configureCompiler(it, 11) classpath = classpath + - files(tasks.named('compileLatestDepTestScala').map { it.destinationDirectory }) + - files(tasks.named('compileLatestDepTestGeneratedScala').map { it.destinationDirectory }) + files(tasks.named('compileTestScala').map { it.destinationDirectory }) + + files(tasks.named('compileTestGeneratedScala').map { it.destinationDirectory }) } dependencies { - latestDepTestRuntimeOnly sourceSets.latestDepTestGenerated.output -} \ No newline at end of file + testRuntimeOnly sourceSets.testGenerated.output +} diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/main/java/datadog/trace/instrumentation/play27/appsec/ArgumentCaptureAdvice.java b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/main/java/datadog/trace/instrumentation/play27/appsec/ArgumentCaptureAdvice.java index fefc4747eb1..d32fdb49773 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/main/java/datadog/trace/instrumentation/play27/appsec/ArgumentCaptureAdvice.java +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/main/java/datadog/trace/instrumentation/play27/appsec/ArgumentCaptureAdvice.java @@ -6,7 +6,7 @@ import datadog.trace.api.gateway.RequestContext; import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; -import datadog.trace.instrumentation.play26.appsec.PathExtractionHelpers; +import datadog.trace.instrumentation.play.appsec.PathExtractionHelpers; import java.util.Collections; import java.util.HashMap; import java.util.Map; diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/main/java/datadog/trace/instrumentation/play27/appsec/RoutingDsl27Instrumentation.java b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/main/java/datadog/trace/instrumentation/play27/appsec/RoutingDsl27Instrumentation.java index 930fc97b218..1f60d2aa906 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/main/java/datadog/trace/instrumentation/play27/appsec/RoutingDsl27Instrumentation.java +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/main/java/datadog/trace/instrumentation/play27/appsec/RoutingDsl27Instrumentation.java @@ -51,7 +51,7 @@ public String[] helperClassNames() { packageName + ".ArgumentCaptureAdvice$ArgumentCaptureFunctionParam1", packageName + ".ArgumentCaptureAdvice$ArgumentCaptureFunctionParam2", packageName + ".ArgumentCaptureAdvice$ArgumentCaptureFunctionParam3", - "datadog.trace.instrumentation.play26.appsec.PathExtractionHelpers", + "datadog.trace.instrumentation.play.appsec.PathExtractionHelpers", }; } diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/AbstractPlayServer27WithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/AbstractPlayServer27WithErrorHandlerTest.groovy new file mode 100644 index 00000000000..1a4f1e04d36 --- /dev/null +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/AbstractPlayServer27WithErrorHandlerTest.groovy @@ -0,0 +1,13 @@ +package datadog.trace.instrumentation.play26.server.latestdep + +import datadog.trace.agent.test.base.HttpServer +import datadog.trace.instrumentation.play26.server.AbstractPlayServerWithErrorHandlerTest +import datadog.trace.instrumentation.play26.server.PlayHttpServer +import datadog.trace.instrumentation.play26.server.TestHttpErrorHandler + +abstract class AbstractPlayServer27WithErrorHandlerTest extends AbstractPlayServerWithErrorHandlerTest { + @Override + HttpServer server() { + new PlayHttpServer(Play27Routers.&sync, new TestHttpErrorHandler()) + } +} diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayRouters.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/Play27Routers.groovy similarity index 99% rename from dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayRouters.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/Play27Routers.groovy index 3f80a909182..00d199e3d1d 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayRouters.groovy +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/Play27Routers.groovy @@ -43,7 +43,7 @@ import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.USER_B import static datadog.trace.agent.test.base.HttpServerTest.controller // TODO: a lot of this routes don't exercise query/parameter extraction, when they should -class PlayRouters { +class Play27Routers { static Router sync(BuiltInComponents components) { RoutingDsl.fromComponents(components) .GET(SUCCESS.path).routingTo({ diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy similarity index 95% rename from dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy index 9ca31fbffa8..1f6d1a92741 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy @@ -8,7 +8,6 @@ import datadog.trace.api.DDTags import datadog.trace.api.config.TraceInstrumentationConfig import datadog.trace.bootstrap.instrumentation.api.Tags import datadog.trace.instrumentation.play26.PlayHttpServerDecorator -import datadog.trace.instrumentation.play26.server.PlayServerWithErrorHandlerTest import datadog.trace.instrumentation.play26.server.TestHttpErrorHandler import play.api.BuiltInComponents import play.libs.concurrent.ClassLoaderExecution @@ -26,7 +25,7 @@ import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.NOT_FO import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.PATH_PARAM import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS -class PlayAsyncServerRoutesScalaWithErrorHandlerTest extends PlayServerWithErrorHandlerTest { +class PlayAsyncServerRoutesScalaWithErrorHandlerTest extends AbstractPlayServer27WithErrorHandlerTest { @Shared ExecutorService executor diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerScalaWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerScalaWithErrorHandlerTest.groovy similarity index 83% rename from dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerScalaWithErrorHandlerTest.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerScalaWithErrorHandlerTest.groovy index f1efed6da8b..63ee7e44084 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerScalaWithErrorHandlerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerScalaWithErrorHandlerTest.groovy @@ -1,7 +1,6 @@ package datadog.trace.instrumentation.play26.server.latestdep import datadog.trace.agent.test.base.HttpServer -import datadog.trace.instrumentation.play26.server.PlayServerWithErrorHandlerTest import datadog.trace.instrumentation.play26.server.TestHttpErrorHandler import play.api.BuiltInComponents import play.routing.Router @@ -11,7 +10,7 @@ import java.util.concurrent.ExecutorService import java.util.concurrent.Executors import java.util.function.Function -class PlayAsyncServerScalaWithErrorHandlerTest extends PlayServerWithErrorHandlerTest { +class PlayAsyncServerScalaWithErrorHandlerTest extends AbstractPlayServer27WithErrorHandlerTest { @Shared ExecutorService executor diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayHttpServerScala.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayHttpServerScala.groovy similarity index 100% rename from dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayHttpServerScala.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayHttpServerScala.groovy diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/routes/conf/routes b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/routes/conf/routes similarity index 100% rename from dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/routes/conf/routes rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/routes/conf/routes diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/ImplicitConversions.scala b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play26/server/latestdep/ImplicitConversions.scala similarity index 100% rename from dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/ImplicitConversions.scala rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play26/server/latestdep/ImplicitConversions.scala diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayController.scala b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayController.scala similarity index 100% rename from dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayController.scala rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayController.scala diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayRoutersScala.scala b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayRoutersScala.scala similarity index 100% rename from dd-java-agent/instrumentation/play/play-appsec-2.7/src/latestDepTest/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayRoutersScala.scala rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayRoutersScala.scala diff --git a/dd-java-agent/instrumentation/play/play-appsec-common/build.gradle b/dd-java-agent/instrumentation/play/play-appsec-common/build.gradle new file mode 100644 index 00000000000..b1e219f2c52 --- /dev/null +++ b/dd-java-agent/instrumentation/play/play-appsec-common/build.gradle @@ -0,0 +1,3 @@ +apply from: "$rootDir/gradle/java.gradle" + + diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/PathExtractionHelpers.java b/dd-java-agent/instrumentation/play/play-appsec-common/src/main/java/datadog/trace/instrumentation/play/appsec/PathExtractionHelpers.java similarity index 97% rename from dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/PathExtractionHelpers.java rename to dd-java-agent/instrumentation/play/play-appsec-common/src/main/java/datadog/trace/instrumentation/play/appsec/PathExtractionHelpers.java index c97bf454889..8da233f0388 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.5/src/main/java/datadog/trace/instrumentation/play25/appsec/PathExtractionHelpers.java +++ b/dd-java-agent/instrumentation/play/play-appsec-common/src/main/java/datadog/trace/instrumentation/play/appsec/PathExtractionHelpers.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.play25.appsec; +package datadog.trace.instrumentation.play.appsec; import static datadog.trace.api.gateway.Events.EVENTS; diff --git a/settings.gradle.kts b/settings.gradle.kts index 5e65ee180de..e766669cc19 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -500,10 +500,11 @@ include( ":dd-java-agent:instrumentation:play-ws:play-ws-common", ":dd-java-agent:instrumentation:play:play-2.3", ":dd-java-agent:instrumentation:play:play-2.4", - ":dd-java-agent:instrumentation:play:play-appsec-2.5", ":dd-java-agent:instrumentation:play:play-2.6", + ":dd-java-agent:instrumentation:play:play-appsec-2.5", ":dd-java-agent:instrumentation:play:play-appsec-2.6", ":dd-java-agent:instrumentation:play:play-appsec-2.7", + ":dd-java-agent:instrumentation:play:play-appsec-common", ":dd-java-agent:instrumentation:protobuf-3.0", ":dd-java-agent:instrumentation:quartz-2.0", ":dd-java-agent:instrumentation:rabbitmq-amqp-2.7", From 85db5b75509dd8189025d0ef587fe6c93ca6d495 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Fri, 2 Jan 2026 14:39:11 +0100 Subject: [PATCH 03/12] chore: Rename play-appsec-2.7 test packages --- ...actPlayServer27WithErrorHandlerTest.groovy | 2 +- .../server/test}/Play27Routers.groovy | 2 +- ...rverRoutesScalaWithErrorHandlerTest.groovy | 2 +- ...syncServerScalaWithErrorHandlerTest.groovy | 2 +- .../server/test}/PlayHttpServerScala.groovy | 2 +- .../src/test/routes/conf/routes | 34 +++++++++---------- .../server/test}/ImplicitConversions.scala | 2 +- .../server/test}/PlayController.scala | 4 +-- .../server/test}/PlayRoutersScala.scala | 4 +-- 9 files changed, 27 insertions(+), 27 deletions(-) rename dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/{play26/server/latestdep => play27/server/test}/AbstractPlayServer27WithErrorHandlerTest.groovy (88%) rename dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/{play26/server/latestdep => play27/server/test}/Play27Routers.groovy (99%) rename dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/{play26/server/latestdep => play27/server/test}/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy (98%) rename dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/{play26/server/latestdep => play27/server/test}/PlayAsyncServerScalaWithErrorHandlerTest.groovy (93%) rename dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/{play26/server/latestdep => play27/server/test}/PlayHttpServerScala.groovy (97%) rename dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/{play26/server/latestdep => play27/server/test}/ImplicitConversions.scala (88%) rename dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/{play26/server/latestdep => play27/server/test}/PlayController.scala (95%) rename dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/{play26/server/latestdep => play27/server/test}/PlayRoutersScala.scala (97%) diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/AbstractPlayServer27WithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play27/server/test/AbstractPlayServer27WithErrorHandlerTest.groovy similarity index 88% rename from dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/AbstractPlayServer27WithErrorHandlerTest.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play27/server/test/AbstractPlayServer27WithErrorHandlerTest.groovy index 1a4f1e04d36..60fb36c77cd 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/AbstractPlayServer27WithErrorHandlerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play27/server/test/AbstractPlayServer27WithErrorHandlerTest.groovy @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.play26.server.latestdep +package datadog.trace.instrumentation.play27.server.test import datadog.trace.agent.test.base.HttpServer import datadog.trace.instrumentation.play26.server.AbstractPlayServerWithErrorHandlerTest diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/Play27Routers.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play27/server/test/Play27Routers.groovy similarity index 99% rename from dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/Play27Routers.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play27/server/test/Play27Routers.groovy index 00d199e3d1d..692bf2e329d 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/Play27Routers.groovy +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play27/server/test/Play27Routers.groovy @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.play26.server.latestdep +package datadog.trace.instrumentation.play27.server.test import com.fasterxml.jackson.databind.JsonNode import datadog.appsec.api.blocking.Blocking diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play27/server/test/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy similarity index 98% rename from dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play27/server/test/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy index 1f6d1a92741..3285f8febe5 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play27/server/test/PlayAsyncServerRoutesScalaWithErrorHandlerTest.groovy @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.play26.server.latestdep +package datadog.trace.instrumentation.play27.server.test import datadog.trace.agent.test.asserts.TraceAssert import datadog.trace.agent.test.base.HttpServer diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerScalaWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play27/server/test/PlayAsyncServerScalaWithErrorHandlerTest.groovy similarity index 93% rename from dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerScalaWithErrorHandlerTest.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play27/server/test/PlayAsyncServerScalaWithErrorHandlerTest.groovy index 63ee7e44084..ad2f1e43b63 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayAsyncServerScalaWithErrorHandlerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play27/server/test/PlayAsyncServerScalaWithErrorHandlerTest.groovy @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.play26.server.latestdep +package datadog.trace.instrumentation.play27.server.test import datadog.trace.agent.test.base.HttpServer import datadog.trace.instrumentation.play26.server.TestHttpErrorHandler diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayHttpServerScala.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play27/server/test/PlayHttpServerScala.groovy similarity index 97% rename from dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayHttpServerScala.groovy rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play27/server/test/PlayHttpServerScala.groovy index 2a75fca703f..6edd6b6afd3 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayHttpServerScala.groovy +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/groovy/datadog/trace/instrumentation/play27/server/test/PlayHttpServerScala.groovy @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.play26.server.latestdep +package datadog.trace.instrumentation.play27.server.test import datadog.trace.agent.test.base.HttpServer import groovy.transform.CompileStatic diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/routes/conf/routes b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/routes/conf/routes index 0ba1ae9cff2..b7fe09a0106 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/routes/conf/routes +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/routes/conf/routes @@ -1,17 +1,17 @@ -GET /success datadog.trace.instrumentation.play26.server.latestdep.PlayController.success() -GET /redirect datadog.trace.instrumentation.play26.server.latestdep.PlayController.redirect() -GET /forwarded datadog.trace.instrumentation.play26.server.latestdep.PlayController.forwarded() -GET /error-status datadog.trace.instrumentation.play26.server.latestdep.PlayController.errorStatus() -GET /exception datadog.trace.instrumentation.play26.server.latestdep.PlayController.exception() -GET /custom-exception datadog.trace.instrumentation.play26.server.latestdep.PlayController.customException() -GET /not-here datadog.trace.instrumentation.play26.server.latestdep.PlayController.notHere() -GET /user-block datadog.trace.instrumentation.play26.server.latestdep.PlayController.userBlock() -GET /query datadog.trace.instrumentation.play26.server.latestdep.PlayController.query(some: String) -GET /encoded_query datadog.trace.instrumentation.play26.server.latestdep.PlayController.encodedQuery(some: String) -GET /encoded%20path%20query datadog.trace.instrumentation.play26.server.latestdep.PlayController.encodedPathQuery(some: String) -GET /path/:path/param datadog.trace.instrumentation.play26.server.latestdep.PlayController.pathParam(path: Integer) -POST /created datadog.trace.instrumentation.play26.server.latestdep.PlayController.created() -POST /body-urlencoded datadog.trace.instrumentation.play26.server.latestdep.PlayController.bodyUrlencoded() -POST /body-multipart datadog.trace.instrumentation.play26.server.latestdep.PlayController.bodyMultipart() -POST /body-json datadog.trace.instrumentation.play26.server.latestdep.PlayController.bodyJson() -POST /body-xml datadog.trace.instrumentation.play26.server.latestdep.PlayController.bodyXml() +GET /success datadog.trace.instrumentation.play27.server.test.PlayController.success() +GET /redirect datadog.trace.instrumentation.play27.server.test.PlayController.redirect() +GET /forwarded datadog.trace.instrumentation.play27.server.test.PlayController.forwarded() +GET /error-status datadog.trace.instrumentation.play27.server.test.PlayController.errorStatus() +GET /exception datadog.trace.instrumentation.play27.server.test.PlayController.exception() +GET /custom-exception datadog.trace.instrumentation.play27.server.test.PlayController.customException() +GET /not-here datadog.trace.instrumentation.play27.server.test.PlayController.notHere() +GET /user-block datadog.trace.instrumentation.play27.server.test.PlayController.userBlock() +GET /query datadog.trace.instrumentation.play27.server.test.PlayController.query(some: String) +GET /encoded_query datadog.trace.instrumentation.play27.server.test.PlayController.encodedQuery(some: String) +GET /encoded%20path%20query datadog.trace.instrumentation.play27.server.test.PlayController.encodedPathQuery(some: String) +GET /path/:path/param datadog.trace.instrumentation.play27.server.test.PlayController.pathParam(path: Integer) +POST /created datadog.trace.instrumentation.play27.server.test.PlayController.created() +POST /body-urlencoded datadog.trace.instrumentation.play27.server.test.PlayController.bodyUrlencoded() +POST /body-multipart datadog.trace.instrumentation.play27.server.test.PlayController.bodyMultipart() +POST /body-json datadog.trace.instrumentation.play27.server.test.PlayController.bodyJson() +POST /body-xml datadog.trace.instrumentation.play27.server.test.PlayController.bodyXml() diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play26/server/latestdep/ImplicitConversions.scala b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play27/server/test/ImplicitConversions.scala similarity index 88% rename from dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play26/server/latestdep/ImplicitConversions.scala rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play27/server/test/ImplicitConversions.scala index 19a290847f7..c45d49a5ac2 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play26/server/latestdep/ImplicitConversions.scala +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play27/server/test/ImplicitConversions.scala @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.play26.server.latestdep +package datadog.trace.instrumentation.play27.server.test object ImplicitConversions { implicit class MapExtensions[A](m: Iterable[(String, A)]) { diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayController.scala b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play27/server/test/PlayController.scala similarity index 95% rename from dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayController.scala rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play27/server/test/PlayController.scala index 06d1950421c..f8db3d3e7a8 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayController.scala +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play27/server/test/PlayController.scala @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.play26.server.latestdep +package datadog.trace.instrumentation.play27.server.test import datadog.trace.agent.test.base.HttpServerTest import datadog.trace.agent.test.base.HttpServerTest.{ @@ -8,7 +8,7 @@ import datadog.trace.agent.test.base.HttpServerTest.{ } import datadog.appsec.api.blocking.Blocking import datadog.trace.instrumentation.play26.server.TestHttpErrorHandler -import datadog.trace.instrumentation.play26.server.latestdep.ImplicitConversions.MapExtensions +import datadog.trace.instrumentation.play27.server.test.ImplicitConversions.MapExtensions import groovy.lang.Closure import play.api.libs.json.{JsNull, JsValue, Json} import play.api.mvc._ diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayRoutersScala.scala b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play27/server/test/PlayRoutersScala.scala similarity index 97% rename from dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayRoutersScala.scala rename to dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play27/server/test/PlayRoutersScala.scala index aa145a4377e..dcc33d0e8b8 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play26/server/latestdep/PlayRoutersScala.scala +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/src/test/scala/datadog/trace/instrumentation/play27/server/test/PlayRoutersScala.scala @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.play26.server.latestdep +package datadog.trace.instrumentation.play27.server.test import datadog.appsec.api.blocking.Blocking import datadog.trace.agent.test.base.HttpServerTest @@ -9,7 +9,7 @@ import datadog.trace.agent.test.base.HttpServerTest.{ } import datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint._ import datadog.trace.instrumentation.play26.server.TestHttpErrorHandler.CustomRuntimeException -import datadog.trace.instrumentation.play26.server.latestdep.ImplicitConversions.MapExtensions +import datadog.trace.instrumentation.play27.server.test.ImplicitConversions.MapExtensions import groovy.lang.Closure import play.api.BuiltInComponents import play.api.libs.json._ From 596a29104e411b493f51f08c9dbcd524d0cd197a Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Fri, 2 Jan 2026 14:56:55 +0100 Subject: [PATCH 04/12] chore: Use test-fixtures in play-appsec-2.6 --- .../play/play-appsec-2.6/build.gradle | 5 +- .../play26/server/PlayAsyncServerTest.groovy | 2 +- ...PlayAsyncServerWithErrorHandlerTest.groovy | 2 +- .../play26/server/PlayHttpServer.groovy | 84 ----- .../play26/server/PlayRouters.groovy | 339 ------------------ .../play26/server/PlayServerTest.groovy | 146 +------- .../PlayServerWithErrorHandlerTest.groovy | 12 +- 7 files changed, 5 insertions(+), 585 deletions(-) delete mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy delete mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle b/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle index 694c6f1debb..56104c4a042 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle @@ -51,11 +51,8 @@ dependencies { compileOnly project(':dd-java-agent:instrumentation:play:play-2.6') implementation(project(':dd-java-agent:instrumentation:play:play-appsec-common')) - // TODO - // * replace with testFixtures when we migrate this module to use java-test-fixtures plugin - // * replace 'baseTest' by 'test' - testImplementation project(':dd-java-agent:instrumentation:play:play-2.6') + testImplementation testFixtures(project(':dd-java-agent:instrumentation:play:play-2.6')) testImplementation group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion testImplementation(group: 'com.typesafe.play', name: "play-test_$scalaVersion", version: playVersion) { exclude group: 'org.eclipse.jetty.websocket', module: 'websocket-client' diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy index 4d9e443369d..4155deea955 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy @@ -6,7 +6,7 @@ import spock.lang.Shared import java.util.concurrent.Executors -class PlayAsyncServerTest extends PlayServerTest { +class PlayAsyncServerTest extends AbstractPlayServerTest { @Shared def executor diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy index 8e84b25e8cf..a63949be584 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerWithErrorHandlerTest.groovy @@ -5,7 +5,7 @@ import spock.lang.Shared import java.util.concurrent.Executors -class PlayAsyncServerWithErrorHandlerTest extends PlayServerWithErrorHandlerTest { +class PlayAsyncServerWithErrorHandlerTest extends AbstractPlayServerWithErrorHandlerTest { @Shared def executor diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy deleted file mode 100644 index e4fac0aeb7b..00000000000 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayHttpServer.groovy +++ /dev/null @@ -1,84 +0,0 @@ -package datadog.trace.instrumentation.play26.server - -import datadog.trace.agent.test.base.HttpServer -import play.ApplicationLoader -import play.BuiltInComponents -import play.BuiltInComponentsFromContext -import play.Environment -import play.Mode -import play.api.Configuration -import play.api.Play -import play.core.server.AkkaHttpServerProvider -import play.core.server.ServerConfig -import play.http.HttpErrorHandler -import play.mvc.EssentialFilter -import play.routing.Router -import scala.Option - -import java.util.concurrent.TimeoutException -import java.util.function.Function - -class PlayHttpServer implements HttpServer { - final Function router - HttpErrorHandler httpErrorHandler - def application - def server - def port - - PlayHttpServer(Function router) { - this(router, null) - } - - PlayHttpServer(Function router, HttpErrorHandler httpErrorHandler) { - this.router = router - this.httpErrorHandler = httpErrorHandler - } - - @Override - void start() throws TimeoutException { - def environment = Environment.simple() - def context = ApplicationLoader.create(environment) - application = new BuiltInComponentsFromContext(context) { - @Override - Router router() { - router.apply(this) - } - - @Override - List httpFilters() { - Collections.emptyList() - } - - @Override - HttpErrorHandler httpErrorHandler() { - if (httpErrorHandler != null) { - return httpErrorHandler - } - return super.httpErrorHandler() - } - }.application().asScala() - Play.start(application) - - def config = new ServerConfig( - new File("."), - Option.apply(0), - Option.empty(), - "0.0.0.0", - Mode.PROD.asScala(), - System.getProperties(), - Configuration.load(environment.asScala()) - ) - server = new AkkaHttpServerProvider().createServer(config, application) - port = server.httpPort().get() - } - - @Override - void stop() { - server.stop() - } - - @Override - URI address() { - return new URI("http://localhost:$port/") - } -} diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy deleted file mode 100644 index c2226b78f6d..00000000000 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy +++ /dev/null @@ -1,339 +0,0 @@ -package datadog.trace.instrumentation.play26.server - -import com.fasterxml.jackson.databind.ObjectMapper -import datadog.appsec.api.blocking.Blocking -import datadog.trace.agent.test.base.HttpServerTest -import groovy.transform.CompileStatic -import play.BuiltInComponents -import play.api.libs.json.JsValue -import play.api.mvc.AnyContent -import play.libs.concurrent.HttpExecution -import play.mvc.Http -import play.mvc.Result -import play.mvc.Results -import play.routing.Router -import play.routing.RoutingDsl -import scala.collection.JavaConverters -import scala.concurrent.ExecutionContextExecutor -import scala.xml.NodeSeq - -import java.util.concurrent.CompletableFuture -import java.util.concurrent.CompletionStage -import java.util.concurrent.Executor -import java.util.concurrent.ExecutorService -import java.util.function.Function -import java.util.function.Supplier - -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_JSON -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_MULTIPART -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_URLENCODED -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_XML -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CREATED -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CUSTOM_EXCEPTION -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.ERROR -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.EXCEPTION -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.FORWARDED -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.PATH_PARAM -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.QUERY_ENCODED_BOTH -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.QUERY_ENCODED_QUERY -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.QUERY_PARAM -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.REDIRECT -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.USER_BLOCK -import static datadog.trace.agent.test.base.HttpServerTest.controller -import static java.lang.Class.forName - -class PlayRouters { - static Router sync(BuiltInComponents components) { - try { - forName("datadog.trace.instrumentation.play26.server.latestdep.PlayRouters").sync components - } catch (ClassNotFoundException cnf) { - sync26(components) - } - } - - static Router async(ExecutorService executor, BuiltInComponents components) { - try { - forName("datadog.trace.instrumentation.play26.server.latestdep.PlayRouters").async executor, components - } catch (ClassNotFoundException cnf) { - async26(executor, components) - } - } - - private static Router sync26(BuiltInComponents components) { - RoutingDsl.fromComponents(components) - .GET(SUCCESS.path).routeTo({ - controller(SUCCESS) { - Results.status(SUCCESS.status, SUCCESS.body) - } - } as Supplier) - .GET(FORWARDED.path).routeTo({ - controller(FORWARDED) { - Results.status(FORWARDED.status, FORWARDED.body) - } - } as Supplier) - .GET(QUERY_PARAM.path).routeTo({ - controller(QUERY_PARAM) { - Results.status(QUERY_PARAM.status, QUERY_PARAM.body) - } - } as Supplier) - .GET(QUERY_ENCODED_QUERY.path).routeTo({ - controller(QUERY_ENCODED_QUERY) { - Results.status(QUERY_ENCODED_QUERY.status, QUERY_ENCODED_QUERY.body) - } - } as Supplier) - .GET(QUERY_ENCODED_BOTH.rawPath).routeTo({ - controller(QUERY_ENCODED_BOTH) { - Results.status(QUERY_ENCODED_BOTH.status, QUERY_ENCODED_BOTH.body). - withHeader(HttpServerTest.IG_RESPONSE_HEADER, HttpServerTest.IG_RESPONSE_HEADER_VALUE) - } - } as Supplier) - .GET(REDIRECT.path).routeTo({ - controller(REDIRECT) { - Results.found(REDIRECT.body) - } - } as Supplier) - .GET(ERROR.path).routeTo({ - controller(ERROR) { - Results.status(ERROR.status, ERROR.body) - } - } as Supplier) - .GET(EXCEPTION.path).routeTo({ - controller(EXCEPTION) { - throw new RuntimeException(EXCEPTION.body) - } - } as Supplier) - .GET(CUSTOM_EXCEPTION.path).routeAsync({ - controller(CUSTOM_EXCEPTION) { - throw new TestHttpErrorHandler.CustomRuntimeException(CUSTOM_EXCEPTION.body) - } - } as Supplier) - .GET("/path/:id/param").routeTo(PathParamSyncFunction.INSTANCE) - .GET(USER_BLOCK.path).routeTo({ - controller(USER_BLOCK) { - controller(USER_BLOCK) { - Blocking.forUser('user-to-block').blockIfMatch() - Results.status(200, "should never be reached") - } - } - } as Supplier) - .POST(CREATED.path).routeTo({ - -> - controller(CREATED) { - def body = body().asText().get() - Results.status(CREATED.status, "created: $body") - } - } as Supplier) - .POST(BODY_URLENCODED.path).routeTo({ - -> - controller(BODY_URLENCODED) { - def body = body().asFormUrlEncoded().get() - def javaMap = JavaConverters.mapAsJavaMapConverter(body).asJava() - def res = javaMap.collectEntries { - [it.key, JavaConverters.asJavaCollectionConverter(it.value).asJavaCollection()] - } - Results.status(BODY_URLENCODED.status, res as String) - } - } as Supplier) - .POST(BODY_MULTIPART.path).routeTo({ - -> - controller(BODY_MULTIPART) { - def body = body().asMultipartFormData().get().asFormUrlEncoded() - def javaMap = JavaConverters.mapAsJavaMapConverter(body).asJava() - def res = javaMap.collectEntries { - [it.key, JavaConverters.asJavaCollectionConverter(it.value).asJavaCollection()] - } - Results.status(BODY_MULTIPART.status, res as String) - } - } as Supplier) - .POST(BODY_JSON.path).routeTo({ - -> - controller(BODY_JSON) { - JsValue json = body().asJson().get() - Results.status(BODY_JSON.status, new ObjectMapper().readTree(json.toString())) - } - } as Supplier) - .POST(BODY_XML.path).routeTo({ - -> - controller(BODY_XML) { - NodeSeq node = body().asXml().get() - Results.status(BODY_XML.status, node.toString()) - } - } as Supplier) - .build() - } - - static Router async26(ExecutorService executor, BuiltInComponents components) { - ExecutionContextExecutor execContext = HttpExecution.fromThread(executor) - RoutingDsl.fromComponents(components) - .GET(SUCCESS.getPath()).routeAsync({ - CompletableFuture.supplyAsync({ - controller(SUCCESS) { - Results.status(SUCCESS.getStatus(), SUCCESS.getBody()) - } - }, execContext) - } as Supplier) - .GET(FORWARDED.getPath()).routeAsync({ - CompletableFuture.supplyAsync({ - controller(FORWARDED) { - Results.status(FORWARDED.getStatus(), FORWARDED.getBody()) // cheating - } - }, execContext) - } as Supplier) - .GET(QUERY_PARAM.getPath()).routeAsync({ - CompletableFuture.supplyAsync({ - controller(QUERY_PARAM) { - Results.status(QUERY_PARAM.getStatus(), QUERY_PARAM.getBody()) // cheating - } - }, execContext) - } as Supplier) - .GET(QUERY_ENCODED_QUERY.getPath()).routeAsync({ - CompletableFuture.supplyAsync({ - controller(QUERY_ENCODED_QUERY) { - Results.status(QUERY_ENCODED_QUERY.getStatus(), QUERY_ENCODED_QUERY.getBody()) // cheating - } - }, execContext) - } as Supplier) - .GET(QUERY_ENCODED_BOTH.getRawPath()).routeAsync({ - CompletableFuture.supplyAsync({ - controller(QUERY_ENCODED_BOTH) { - Results.status(QUERY_ENCODED_BOTH.getStatus(), QUERY_ENCODED_BOTH.getBody()). - withHeader(HttpServerTest.IG_RESPONSE_HEADER, HttpServerTest.IG_RESPONSE_HEADER_VALUE) // cheating - } - }, execContext) - } as Supplier) - .GET(REDIRECT.getPath()).routeAsync({ - CompletableFuture.supplyAsync({ - controller(REDIRECT) { - Results.found(REDIRECT.getBody()) - } - }, execContext) - } as Supplier) - .GET(ERROR.getPath()).routeAsync({ - CompletableFuture.supplyAsync({ - controller(ERROR) { - Results.status(ERROR.getStatus(), ERROR.getBody()) - } - }, execContext) - } as Supplier) - .GET(EXCEPTION.getPath()).routeAsync({ - CompletableFuture.supplyAsync({ - controller(EXCEPTION) { - throw new RuntimeException(EXCEPTION.getBody()) - } - }, execContext) - } as Supplier) - .GET(CUSTOM_EXCEPTION.path).routeAsync({ - CompletableFuture.supplyAsync({ - controller(CUSTOM_EXCEPTION) { - throw new TestHttpErrorHandler.CustomRuntimeException(CUSTOM_EXCEPTION.body) - } - }, execContext) - } as Supplier) - .GET("/path/:id/param").routeAsync(new PathParamAsyncFunction(execContext)) - .GET(USER_BLOCK.path).routeAsync({ - CompletableFuture.supplyAsync({ - -> - controller(USER_BLOCK) { - controller(USER_BLOCK) { - Blocking.forUser('user-to-block').blockIfMatch() - Results.status(200, "should never be reached") - } - } - }, execContext) - } as Supplier) - .POST(CREATED.path).routeAsync({ - -> - def body = body().asText().get() - CompletableFuture.supplyAsync({ - -> - controller(CREATED) { - Results.status(CREATED.status, "created: $body") - } - }, execContext) - } as Supplier) - .POST(BODY_URLENCODED.path).routeAsync({ - -> - def body = body().asFormUrlEncoded().get() - CompletableFuture.supplyAsync({ - -> - controller(BODY_URLENCODED) { - def javaMap = JavaConverters.mapAsJavaMapConverter(body).asJava() - def res = javaMap.collectEntries { - [it.key, JavaConverters.asJavaCollectionConverter(it.value).asJavaCollection()] - } - Results.status(BODY_URLENCODED.status, res as String) - } - }, execContext) - } as Supplier) - .POST(BODY_MULTIPART.path).routeAsync({ - -> - def body = body().asMultipartFormData().get().asFormUrlEncoded() - CompletableFuture.supplyAsync({ - -> - controller(BODY_MULTIPART) { - def javaMap = JavaConverters.mapAsJavaMapConverter(body).asJava() - def res = javaMap.collectEntries { - [it.key, JavaConverters.asJavaCollectionConverter(it.value).asJavaCollection()] - } - Results.status(BODY_MULTIPART.status, res as String) - } - }, execContext) - } as Supplier) - .POST(BODY_JSON.path).routeAsync({ - -> - JsValue json = body().asJson().get() - CompletableFuture.supplyAsync({ - -> - controller(BODY_JSON) { - Results.status(BODY_JSON.status, new ObjectMapper().readTree(json.toString())) - } - }, execContext) - } as Supplier) - .POST(BODY_XML.path).routeAsync({ - -> - NodeSeq node = body().asXml().get() - CompletableFuture.supplyAsync({ - -> - controller(BODY_XML) { - Results.status(BODY_XML.status, node.toString()) - } - }, execContext) - } as Supplier) - .build() - } - - private static AnyContent body() { - Http.Context.current()._requestHeader().body - } - - @CompileStatic - static enum PathParamSyncFunction implements Function { - INSTANCE - - @Override - Result apply(Integer i) { - controller(PATH_PARAM) { - Results.ok(i as String) - } - } - } - - @CompileStatic - static class PathParamAsyncFunction implements Function> { - private final Executor executor - - PathParamAsyncFunction(Executor executor) { - this.executor = executor - } - - @Override - CompletionStage apply(Integer i) { - CompletableFuture.supplyAsync({ - controller(PATH_PARAM) { - Results.ok(i as String) - } - }, executor) - } - } -} diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy index 2f5b1f27f96..b425a73b0ce 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy @@ -1,155 +1,11 @@ package datadog.trace.instrumentation.play26.server -import datadog.trace.agent.test.asserts.TraceAssert -import datadog.trace.agent.test.base.HttpServer -import datadog.trace.agent.test.base.HttpServerTest -import datadog.trace.api.DDSpanTypes -import datadog.trace.api.DDTags -import datadog.trace.bootstrap.instrumentation.api.Tags -import datadog.trace.instrumentation.play26.PlayHttpServerDecorator -import groovy.transform.CompileStatic import okhttp3.MediaType import okhttp3.RequestBody -import play.server.Server import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_XML -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CUSTOM_EXCEPTION -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.EXCEPTION -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.FORWARDED -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS -class PlayServerTest extends HttpServerTest { - - @Override - @CompileStatic - HttpServer server() { - new PlayHttpServer(PlayRouters.&sync) - } - - @Override - void stopServer(Server server) { - server.stop() - } - - @Override - String component() { - 'akka-http-server' - } - - @Override - String expectedOperationName() { - 'akka-http.request' - } - - @Override - boolean hasHandlerSpan() { - true - } - - @Override - boolean hasExtraErrorInformation() { - true - } - - @Override - boolean changesAll404s() { - true - } - - boolean testExceptionBody() { - // I can't figure out how to set a proper exception handler to customize the response body. - false - } - - @Override - boolean testRequestBody() { - true - } - - @Override - boolean isRequestBodyNoStreaming() { - true - } - - @Override - boolean testBodyUrlencoded() { - true - } - - @Override - boolean testBodyMultipart() { - true - } - - @Override - boolean testBodyJson() { - true - } - - @Override - boolean testBlocking() { - true - } - - @Override - boolean testBlockingOnResponse() { - true - } - - @Override - boolean testResponseBodyJson() { - true - } - - @Override - String testPathParam() { - '/path/?/param' - } - - @Override - Map expectedIGPathParams() { - ['0': 123] - } - - @Override - Class expectedExceptionType() { - RuntimeException - } - - @Override - Class expectedCustomExceptionType() { - TestHttpErrorHandler.CustomRuntimeException - } - - @Override - void handlerSpan(TraceAssert trace, ServerEndpoint endpoint = SUCCESS) { - def expectedQueryTag = expectedQueryTag(endpoint) - trace.span { - serviceName expectedServiceName() - operationName "play.request" - spanType DDSpanTypes.HTTP_SERVER - errored endpoint == EXCEPTION || endpoint == CUSTOM_EXCEPTION - childOfPrevious() - tags { - "$Tags.COMPONENT" PlayHttpServerDecorator.DECORATE.component() - "$Tags.SPAN_KIND" Tags.SPAN_KIND_SERVER - "$Tags.PEER_HOST_IPV4" '127.0.0.1' - "$Tags.HTTP_CLIENT_IP" (endpoint == FORWARDED ? endpoint.body : '127.0.0.1') - "$Tags.HTTP_URL" String - "$Tags.HTTP_HOSTNAME" address.host - "$Tags.HTTP_METHOD" String - // BUG - // "$Tags.HTTP_ROUTE" String - if (endpoint == EXCEPTION || endpoint == CUSTOM_EXCEPTION) { - errorTags(endpoint == CUSTOM_EXCEPTION ? TestHttpErrorHandler.CustomRuntimeException : RuntimeException, endpoint.body) - } - if (endpoint.query) { - "$DDTags.HTTP_QUERY" expectedQueryTag - } - defaultTags() - } - } - } +class PlayServerTest extends AbstractPlayServerTest { def 'test instrumentation gateway xml request body'() { setup: diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy index 6221c5681ce..0f416940d5f 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy @@ -1,20 +1,10 @@ package datadog.trace.instrumentation.play26.server -import datadog.trace.agent.test.base.HttpServer import spock.lang.IgnoreIf import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CUSTOM_EXCEPTION -class PlayServerWithErrorHandlerTest extends PlayServerTest { - @Override - HttpServer server() { - new PlayHttpServer(PlayRouters.&sync, new TestHttpErrorHandler()) - } - - @Override - boolean testExceptionBody() { - true - } +class PlayServerWithErrorHandlerTest extends AbstractPlayServerWithErrorHandlerTest { @IgnoreIf({ !instance.testException() }) def "test exception with custom status"() { From 85e3b4a88f511d95ed05503761234e98463aef9f Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Fri, 2 Jan 2026 19:26:36 +0100 Subject: [PATCH 05/12] fix: Muzzle artifact was incorrect --- .../play/play-appsec-2.6/build.gradle | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle b/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle index 56104c4a042..9000e272ac4 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle @@ -7,26 +7,9 @@ muzzle { pass { name = 'play26Only' group = 'com.typesafe.play' - module = "play_$scalaVersion" + module = 'play-java_2.11' versions = "[2.6.0,2.7.0)" assertInverse = true - javaVersion = 11 - } - pass { - name = 'play26Only' - group = 'com.typesafe.play' - module = 'play_2.12' - versions = "[2.6.0,2.7.0)" - assertInverse = true - javaVersion = 11 - } - pass { - name = 'play26Only' - group = 'com.typesafe.play' - module = 'play_2.13' - versions = "[2.6.0,2.7.0)" - assertInverse = true - javaVersion = 11 } } From 87662d0b34a4ff6e742371d45e8c78102c99db0f Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Fri, 2 Jan 2026 19:28:24 +0100 Subject: [PATCH 06/12] chore: Remove needless gitignore --- dd-java-agent/instrumentation/play/play-2.3/.gitignore | 1 - dd-java-agent/instrumentation/play/play-2.4/.gitignore | 1 - dd-java-agent/instrumentation/play/play-2.6/.gitignore | 1 - dd-java-agent/instrumentation/play/play-appsec-2.5/.gitignore | 1 - dd-java-agent/instrumentation/play/play-appsec-2.6/.gitignore | 2 -- dd-java-agent/instrumentation/play/play-appsec-2.7/.gitignore | 2 -- 6 files changed, 8 deletions(-) delete mode 100644 dd-java-agent/instrumentation/play/play-2.3/.gitignore delete mode 100644 dd-java-agent/instrumentation/play/play-2.4/.gitignore delete mode 100644 dd-java-agent/instrumentation/play/play-2.6/.gitignore delete mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.5/.gitignore delete mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.6/.gitignore delete mode 100644 dd-java-agent/instrumentation/play/play-appsec-2.7/.gitignore diff --git a/dd-java-agent/instrumentation/play/play-2.3/.gitignore b/dd-java-agent/instrumentation/play/play-2.3/.gitignore deleted file mode 100644 index 5292519a25e..00000000000 --- a/dd-java-agent/instrumentation/play/play-2.3/.gitignore +++ /dev/null @@ -1 +0,0 @@ -logs/ \ No newline at end of file diff --git a/dd-java-agent/instrumentation/play/play-2.4/.gitignore b/dd-java-agent/instrumentation/play/play-2.4/.gitignore deleted file mode 100644 index 5292519a25e..00000000000 --- a/dd-java-agent/instrumentation/play/play-2.4/.gitignore +++ /dev/null @@ -1 +0,0 @@ -logs/ \ No newline at end of file diff --git a/dd-java-agent/instrumentation/play/play-2.6/.gitignore b/dd-java-agent/instrumentation/play/play-2.6/.gitignore deleted file mode 100644 index 5292519a25e..00000000000 --- a/dd-java-agent/instrumentation/play/play-2.6/.gitignore +++ /dev/null @@ -1 +0,0 @@ -logs/ \ No newline at end of file diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.5/.gitignore b/dd-java-agent/instrumentation/play/play-appsec-2.5/.gitignore deleted file mode 100644 index 5292519a25e..00000000000 --- a/dd-java-agent/instrumentation/play/play-appsec-2.5/.gitignore +++ /dev/null @@ -1 +0,0 @@ -logs/ \ No newline at end of file diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/.gitignore b/dd-java-agent/instrumentation/play/play-appsec-2.6/.gitignore deleted file mode 100644 index 192221b47d1..00000000000 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.gradle/ -build/ \ No newline at end of file diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/.gitignore b/dd-java-agent/instrumentation/play/play-appsec-2.7/.gitignore deleted file mode 100644 index 192221b47d1..00000000000 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.gradle/ -build/ \ No newline at end of file From 6fd49305a9f7cc5177b73908ccba8960a9351be9 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Fri, 2 Jan 2026 20:27:31 +0100 Subject: [PATCH 07/12] chore: Modernize build play-appsec-2.5 and play-appsec-2.7 configuration --- .../play/play-2.3/build.gradle | 2 +- .../play/play-2.6/build.gradle | 3 - .../play/play-appsec-2.5/build.gradle | 127 +++++++----------- .../play/play-appsec-2.7/build.gradle | 73 ++++------ 4 files changed, 72 insertions(+), 133 deletions(-) diff --git a/dd-java-agent/instrumentation/play/play-2.3/build.gradle b/dd-java-agent/instrumentation/play/play-2.3/build.gradle index 13aff562fe7..b6871bc0b14 100644 --- a/dd-java-agent/instrumentation/play/play-2.3/build.gradle +++ b/dd-java-agent/instrumentation/play/play-2.3/build.gradle @@ -60,5 +60,5 @@ dependencies { } tasks.named("compileLatestDepTestGroovy", GroovyCompile) { - classpath += files(tasks.named('compileLatestDepTestScala').map { it.destinationDirectory }) + classpath += files(tasks.named('compileLatestDepTestScala')) } diff --git a/dd-java-agent/instrumentation/play/play-2.6/build.gradle b/dd-java-agent/instrumentation/play/play-2.6/build.gradle index 9c5aee0f47c..c18ae8ae64d 100644 --- a/dd-java-agent/instrumentation/play/play-2.6/build.gradle +++ b/dd-java-agent/instrumentation/play/play-2.6/build.gradle @@ -84,6 +84,3 @@ dependencies { testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-promise:scala-promise-2.13') } -// tasks.named('forbiddenApisTestFixtures') { -// enabled = false -// } diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.5/build.gradle b/dd-java-agent/instrumentation/play/play-appsec-2.5/build.gradle index 5fa79c91539..10c1a6cac9d 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.5/build.gradle +++ b/dd-java-agent/instrumentation/play/play-appsec-2.5/build.gradle @@ -12,6 +12,21 @@ muzzle { apply from: "$rootDir/gradle/java.gradle" apply plugin: 'scala' +def buildTestRoutes = tasks.register('buildTestRoutes', JavaExec) + +sourceSets { + test { + scala { + srcDir buildTestRoutes + } + } + routeGenerator { + scala { + srcDir 'src/routeGenerator/scala' + } + } +} + testJvmConstraints { // Play doesn't work with Java 9+ until 2.6.12 maxJavaVersion = JavaVersion.VERSION_1_8 @@ -31,11 +46,22 @@ tasks.withType(ScalaCompile).configureEach { } addTestSuiteForDir('latestDepTest', 'test') +def buildLatestDepTestRoutes = tasks.register('buildLatestDepTestRoutes', JavaExec) +sourceSets { + latestDepTest { + scala { + srcDir buildLatestDepTestRoutes + } + } +} dependencies { compileOnly group: 'com.typesafe.play', name: 'play_2.11', version: '2.5.0' implementation(project(':dd-java-agent:instrumentation:play:play-appsec-common')) + routeGeneratorImplementation libs.scala211 + routeGeneratorImplementation group: 'com.typesafe.play', name: "routes-compiler_2.11", version: '2.5.0' + testRuntimeOnly project(':dd-java-agent:instrumentation:netty:netty-4.0') testRuntimeOnly project(':dd-java-agent:instrumentation:netty:netty-4.1') testRuntimeOnly project(':dd-java-agent:instrumentation:akka:akka-http:akka-http-10.0') @@ -60,97 +86,40 @@ dependencies { } } -tasks.named("compileTestGroovy", GroovyCompile) { - classpath = classpath + files(tasks.named('compileTestScala').map { it.destinationDirectory }) -} +buildTestRoutes.configure { + String routesFile = "${project.projectDir}/src/test/routes/conf/routes" + def outputDir = layout.buildDirectory.dir('generated/sources/testRoutes/scala') -tasks.named("compileLatestDepTestGroovy", GroovyCompile) { - classpath = classpath + files(tasks.named('compileLatestDepTestScala').map { it.destinationDirectory }) -} - -sourceSets { - routeGenerator { - scala { - srcDir "${project.projectDir}/src/routeGenerator/scala" - } - } - testGenerated { - scala { - srcDir layout.buildDirectory.dir('generated/sources/testRoutes/scala') - } - } - latestDepTestGenerated { - scala { - srcDir layout.buildDirectory.dir('generated/sources/latestDepTestRoutes/scala') - } - } -} + it.inputs.file routesFile + it.outputs.dir outputDir -dependencies { - routeGeneratorImplementation libs.scala211 - routeGeneratorImplementation group: 'com.typesafe.play', name: "routes-compiler_2.11", version: '2.5.0' -} + it.mainClass.set 'generator.CompileRoutes' + it.args routesFile, outputDir.get().asFile.absolutePath -configurations { - testGeneratedCompileClasspath.extendsFrom testCompileClasspath - latestDepTestGeneratedCompileClasspath.extendsFrom latestDepTestCompileClasspath + it.classpath configurations.named('routeGeneratorRuntimeClasspath') + it.classpath tasks.named('compileRouteGeneratorScala') } -['buildTestRoutes', 'buildLatestDepTestRoutes'].each { taskName -> - tasks.register(taskName, JavaExec) { - String routesFile = "${project.projectDir}/src/test/routes/conf/routes" - def subdir = taskName == 'buildTestRoutes' ? 'testRoutes' : 'latestDepTestRoutes' - def outputDir = - layout.buildDirectory.dir("generated/sources/$subdir/scala") - - it.inputs.file routesFile - it.outputs.dir outputDir +buildLatestDepTestRoutes.configure { + String routesFile = "${project.projectDir}/src/test/routes/conf/routes" + def outputDir = layout.buildDirectory.dir('generated/sources/latestDepTestRoutes/scala') - it.mainClass.set 'generator.CompileRoutes' - it.args routesFile, outputDir.get().asFile.absolutePath + it.inputs.file routesFile + it.outputs.dir outputDir - it.classpath configurations.named('routeGeneratorRuntimeClasspath') - it.classpath tasks.named('compileRouteGeneratorScala').map { it.destinationDirectory } + it.mainClass.set 'generator.CompileRoutes' + it.args routesFile, outputDir.get().asFile.absolutePath - if (taskName == 'buildTestRoutes') { - it.classpath tasks.named('compileTestScala').map { it.destinationDirectory } - } else { - it.classpath tasks.named('compileLatestDepTestScala').map { it.destinationDirectory } - } - } -} - -tasks.named("compileTestGeneratedScala", ScalaCompile) { - classpath += files(tasks.named('compileTestScala').map { it.destinationDirectory }) - dependsOn 'buildTestRoutes', 'compileLatestDepTestScala' -} - -tasks.named("compileLatestDepTestGeneratedScala", ScalaCompile) { - classpath += files(tasks.named('compileLatestDepTestScala').map { it.destinationDirectory }) - dependsOn 'buildLatestDepTestRoutes' + it.classpath configurations.named('routeGeneratorRuntimeClasspath') + it.classpath tasks.named('compileRouteGeneratorScala') } tasks.named("compileTestGroovy", GroovyCompile) { - classpath += files(tasks.named('compileTestGeneratedScala').map { it.destinationDirectory }) + // Groovy tests need access to generated routes compiled by Scala + classpath += files(tasks.named('compileTestScala')) } tasks.named("compileLatestDepTestGroovy", GroovyCompile) { - classpath += files(tasks.named('compileLatestDepTestGeneratedScala').map { it.destinationDirectory }) -} -// do it this way rather than through dependencies {} because -// latestDepTestImplementation extends testImplementation -tasks.named("test", Test) { - classpath += files(tasks.named('compileTestGeneratedScala').map { it.destinationDirectory }) -} - -tasks.named("latestDepTest", Test) { - classpath += files(tasks.named('compileLatestDepTestGeneratedScala').map { it.destinationDirectory }) -} - -tasks.named("forbiddenApisTestGenerated") { - enabled = false -} - -tasks.named("forbiddenApisLatestDepTestGenerated") { - enabled = false + // Groovy tests need access to generated routes compiled by Scala + classpath += files(tasks.named('compileLatestDepTestScala')) } diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle b/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle index f40ad5ec4f2..cb2eca4d7de 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle @@ -33,6 +33,20 @@ muzzle { apply from: "$rootDir/gradle/java.gradle" apply plugin: 'scala' +def buildTestRoutes = tasks.register('buildTestRoutes', JavaExec) +sourceSets { + test { + scala { + srcDir buildTestRoutes + } + } + routeGenerator { + scala { + srcDir 'src/routeGenerator/scala' + } + } +} + testJvmConstraints { minJavaVersion = JavaVersion.VERSION_11 } @@ -51,11 +65,8 @@ dependencies { implementation project(':dd-java-agent:instrumentation:play:play-2.6') implementation(project(':dd-java-agent:instrumentation:play:play-appsec-common')) - // TODO - // * [x] replace 'latestDepTest' by 'test' - // * [x] ensure test fixture is used in 'test' instead of 'latestDepTest' - // * [x] use the introduced 'Abstract*Test' classes - // * [ ] router.Routes is generated code, find a way to generate it for tests + routeGeneratorImplementation libs.scala213 + routeGeneratorImplementation group: 'com.typesafe.play', name: "routes-compiler_2.13", version: '2.+' testImplementation libs.scala213 testImplementation project(':dd-java-agent:instrumentation:play:play-2.6') @@ -94,36 +105,9 @@ tasks.named("compileTestScala", ScalaCompile) { configureCompiler(it, 11) } -// tasks.named("latestDepTest", Test) { -// javaLauncher = getJavaLauncherFor(11) -// } - -final generatedRoutes = layout.buildDirectory.dir('generated/sources/testRoutes/scala') -sourceSets { - routeGenerator { - scala { - srcDir "${project.projectDir}/src/routeGenerator/scala" - } - } - testGenerated { - scala { - srcDir generatedRoutes - } - } -} - -dependencies { - routeGeneratorImplementation libs.scala213 - routeGeneratorImplementation group: 'com.typesafe.play', name: "routes-compiler_2.13", version: '2.+' -} - -configurations { - testGeneratedCompileClasspath.extendsFrom(testCompileClasspath) -} - -tasks.register('buildTestRoutes', JavaExec) { - String routesFile = "${project.projectDir}/src/test/routes/conf/routes" - def outputDir = generatedRoutes +buildTestRoutes.configure { + def routesFile = "${project.projectDir}/src/test/routes/conf/routes" + def outputDir = layout.buildDirectory.dir('generated/sources/testRoutes/scala') it.inputs.file routesFile it.outputs.dir outputDir @@ -132,29 +116,18 @@ tasks.register('buildTestRoutes', JavaExec) { it.args routesFile, outputDir.get().asFile.absolutePath it.classpath configurations.named('routeGeneratorRuntimeClasspath') - it.classpath tasks.named('compileRouteGeneratorScala').map { it.destinationDirectory } - it.classpath tasks.named('compileTestScala').map { it.destinationDirectory } + it.classpath tasks.named('compileRouteGeneratorScala') it.javaLauncher = getJavaLauncherFor(11) } -tasks.named("compileTestGeneratedScala", ScalaCompile) { +tasks.named("compileTestScala", ScalaCompile) { configureCompiler(it, 11) - classpath = classpath + files(tasks.named('compileTestScala').map { it.destinationDirectory }) dependsOn 'buildTestRoutes' } -tasks.named("forbiddenApisTestGenerated") { - enabled = false -} - tasks.named("compileTestGroovy", GroovyCompile) { configureCompiler(it, 11) - classpath = classpath + - files(tasks.named('compileTestScala').map { it.destinationDirectory }) + - files(tasks.named('compileTestGeneratedScala').map { it.destinationDirectory }) -} - -dependencies { - testRuntimeOnly sourceSets.testGenerated.output + // Groovy tests need access to generated routes compiled by Scala + classpath += files(tasks.named('compileTestScala')) } From 1611c3d8748a96ad8b62ee84e56eb8fa2d1f62e4 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Fri, 2 Jan 2026 21:55:53 +0100 Subject: [PATCH 08/12] chore: Re-run some tests on play 2.6 and play 2.7 --- .../play26/server/PlayServerTest.groovy | 29 ----------------- .../PlayServerWithErrorHandlerTest.groovy | 31 ------------------ .../server/AbstractPlayServerTest.groovy | 29 +++++++++++++++++ ...tractPlayServerWithErrorHandlerTest.groovy | 31 ++++++++++++++++++ .../PlayServerWithErrorHandlerTest.groovy | 32 ------------------- 5 files changed, 60 insertions(+), 92 deletions(-) diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy b/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy index bea9c5fe9ca..3a85e22386f 100644 --- a/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy @@ -1,33 +1,4 @@ package datadog.trace.instrumentation.play26.server -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_XML - -import okhttp3.MediaType -import okhttp3.RequestBody - class PlayServerTest extends AbstractPlayServerTest { - def 'test instrumentation gateway xml request body'() { - setup: - def request = request( - BODY_XML, 'POST', - RequestBody.create(MediaType.get('text/xml'), 'mytext')) - .build() - def response = client.newCall(request).execute() - if (isDataStreamsEnabled()) { - TEST_DATA_STREAMS_WRITER.waitForGroups(1) - } - String body = response.body().charStream().text - - - expect: - body == BODY_XML.body || body == 'mytext' - - when: - TEST_WRITER.waitForTraces(1) - - then: - TEST_WRITER.get(0).any { - it.getTag('request.body.converted') == '[[children:[mytext, [:]], attributes:[attr:attr_value]]]' - } - } } diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy index 1b3597150d4..dd4052f0bce 100644 --- a/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy @@ -1,35 +1,4 @@ package datadog.trace.instrumentation.play26.server -import spock.lang.IgnoreIf - -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CUSTOM_EXCEPTION - class PlayServerWithErrorHandlerTest extends AbstractPlayServerTest { - @IgnoreIf({ !instance.testException() }) - def "test exception with custom status"() { - setup: - def request = request(CUSTOM_EXCEPTION, 'GET', null).build() - def response = client.newCall(request).execute() - - expect: - response.code() == CUSTOM_EXCEPTION.status - if (testExceptionBody()) { - assert response.body().string() == CUSTOM_EXCEPTION.body - } - - and: - assertTraces(1) { - trace(spanCount(CUSTOM_EXCEPTION)) { - sortSpansByStart() - serverSpan(it, null, null, 'GET', CUSTOM_EXCEPTION) - if (hasHandlerSpan()) { - handlerSpan(it, CUSTOM_EXCEPTION) - } - controllerSpan(it, CUSTOM_EXCEPTION) - if (hasResponseSpan(CUSTOM_EXCEPTION)) { - responseSpan(it, CUSTOM_EXCEPTION) - } - } - } - } } diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerTest.groovy b/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerTest.groovy index 741d3fb50fd..0cab2d1bf82 100644 --- a/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerTest.groovy @@ -1,5 +1,7 @@ package datadog.trace.instrumentation.play26.server +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_XML + import datadog.trace.agent.test.asserts.TraceAssert import datadog.trace.agent.test.base.HttpServer import datadog.trace.agent.test.base.HttpServerTest @@ -8,6 +10,8 @@ import datadog.trace.api.DDTags import datadog.trace.bootstrap.instrumentation.api.Tags import datadog.trace.instrumentation.play26.PlayHttpServerDecorator import groovy.transform.CompileStatic +import okhttp3.MediaType +import okhttp3.RequestBody import play.server.Server import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CUSTOM_EXCEPTION @@ -147,4 +151,29 @@ class AbstractPlayServerTest extends HttpServerTest { } } } + + def 'test instrumentation gateway xml request body'() { + setup: + def request = request( + BODY_XML, 'POST', + RequestBody.create(MediaType.get('text/xml'), 'mytext')) + .build() + def response = client.newCall(request).execute() + if (isDataStreamsEnabled()) { + TEST_DATA_STREAMS_WRITER.waitForGroups(1) + } + String body = response.body().charStream().text + + + expect: + body == BODY_XML.body || body == 'mytext' + + when: + TEST_WRITER.waitForTraces(1) + + then: + TEST_WRITER.get(0).any { + it.getTag('request.body.converted') == '[[children:[mytext, [:]], attributes:[attr:attr_value]]]' + } + } } diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerWithErrorHandlerTest.groovy index 9b34bdddb51..22adcc7b3eb 100644 --- a/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerWithErrorHandlerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerWithErrorHandlerTest.groovy @@ -1,6 +1,9 @@ package datadog.trace.instrumentation.play26.server +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CUSTOM_EXCEPTION + import datadog.trace.agent.test.base.HttpServer +import spock.lang.IgnoreIf abstract class AbstractPlayServerWithErrorHandlerTest extends AbstractPlayServerTest { @Override @@ -12,4 +15,32 @@ abstract class AbstractPlayServerWithErrorHandlerTest extends AbstractPlayServer boolean testExceptionBody() { true } + + @IgnoreIf({ !instance.testException() }) + def "test exception with custom status"() { + setup: + def request = request(CUSTOM_EXCEPTION, 'GET', null).build() + def response = client.newCall(request).execute() + + expect: + response.code() == CUSTOM_EXCEPTION.status + if (testExceptionBody()) { + assert response.body().string() == CUSTOM_EXCEPTION.body + } + + and: + assertTraces(1) { + trace(spanCount(CUSTOM_EXCEPTION)) { + sortSpansByStart() + serverSpan(it, null, null, 'GET', CUSTOM_EXCEPTION) + if (hasHandlerSpan()) { + handlerSpan(it, CUSTOM_EXCEPTION) + } + controllerSpan(it, CUSTOM_EXCEPTION) + if (hasResponseSpan(CUSTOM_EXCEPTION)) { + responseSpan(it, CUSTOM_EXCEPTION) + } + } + } + } } diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy index 0f416940d5f..6cae40b1b4a 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy @@ -1,36 +1,4 @@ package datadog.trace.instrumentation.play26.server -import spock.lang.IgnoreIf - -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CUSTOM_EXCEPTION - class PlayServerWithErrorHandlerTest extends AbstractPlayServerWithErrorHandlerTest { - - @IgnoreIf({ !instance.testException() }) - def "test exception with custom status"() { - setup: - def request = request(CUSTOM_EXCEPTION, 'GET', null).build() - def response = client.newCall(request).execute() - - expect: - response.code() == CUSTOM_EXCEPTION.status - if (testExceptionBody()) { - assert response.body().string() == CUSTOM_EXCEPTION.body - } - - and: - assertTraces(1) { - trace(spanCount(CUSTOM_EXCEPTION)) { - sortSpansByStart() - serverSpan(it, null, null, 'GET', CUSTOM_EXCEPTION) - if (hasHandlerSpan()) { - handlerSpan(it, CUSTOM_EXCEPTION) - } - controllerSpan(it, CUSTOM_EXCEPTION) - if (hasResponseSpan(CUSTOM_EXCEPTION)) { - responseSpan(it, CUSTOM_EXCEPTION) - } - } - } - } } From f29a4ea9111316b2c4602a80c593b169965110ca Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Mon, 5 Jan 2026 14:33:09 +0100 Subject: [PATCH 09/12] chore: Inline versions --- .../play/play-2.6/build.gradle | 25 ++++++++----------- .../play/play-appsec-2.6/build.gradle | 11 +++----- .../play/play-appsec-2.7/build.gradle | 5 +--- 3 files changed, 16 insertions(+), 25 deletions(-) diff --git a/dd-java-agent/instrumentation/play/play-2.6/build.gradle b/dd-java-agent/instrumentation/play/play-2.6/build.gradle index c18ae8ae64d..472f5894c77 100644 --- a/dd-java-agent/instrumentation/play/play-2.6/build.gradle +++ b/dd-java-agent/instrumentation/play/play-2.6/build.gradle @@ -1,14 +1,11 @@ -def scalaVersion = '2.11' -def playVersion = '2.6.0' - muzzle { extraRepository("typesafe", "https://repo.typesafe.com/typesafe/maven-releases/") pass { name = 'play26Plus' group = 'com.typesafe.play' - module = "play_$scalaVersion" - versions = "[$playVersion,)" + module = "play_2.11" + versions = "[2.6.0,)" assertInverse = true javaVersion = 11 } @@ -16,7 +13,7 @@ muzzle { name = 'play26Plus' group = 'com.typesafe.play' module = 'play_2.12' - versions = "[$playVersion,)" + versions = "[2.6.0,)" assertInverse = true javaVersion = 11 } @@ -24,7 +21,7 @@ muzzle { name = 'play26Plus' group = 'com.typesafe.play' module = 'play_2.13' - versions = "[$playVersion,)" + versions = "[2.6.0,)" assertInverse = true javaVersion = 11 } @@ -57,21 +54,21 @@ repositories { } dependencies { - compileOnly group: 'com.typesafe.play', name: "play_$scalaVersion", version: playVersion - compileOnly group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion + compileOnly group: 'com.typesafe.play', name: "play_2.11", version: '2.6.0' + compileOnly group: 'com.typesafe.play', name: "play-java_2.11", version: '2.6.0' - testFixturesCompileOnly group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion + testFixturesCompileOnly group: 'com.typesafe.play', name: "play-java_2.11", version: '2.6.0' // TODO: Play WS is a separately versioned library starting with 2.6 and needs separate instrumentation. - testFixturesCompileOnly(group: 'com.typesafe.play', name: "play-test_$scalaVersion", version: playVersion) { + testFixturesCompileOnly(group: 'com.typesafe.play', name: "play-test_2.11", version: '2.6.0') { exclude group: 'org.eclipse.jetty.websocket', module: 'websocket-client' } testFixturesApi project(':dd-java-agent:instrumentation-testing') testFixturesApi libs.spock.core - testImplementation group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion + testImplementation group: 'com.typesafe.play', name: "play-java_2.11", version: '2.6.0' testImplementation testFixtures(project(':dd-java-agent:instrumentation:play:play-2.6')) - testImplementation group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion - testImplementation(group: 'com.typesafe.play', name: "play-test_$scalaVersion", version: playVersion) { + testImplementation group: 'com.typesafe.play', name: "play-java_2.11", version: '2.6.0' + testImplementation(group: 'com.typesafe.play', name: "play-test_2.11", version: '2.6.0') { exclude group: 'org.eclipse.jetty.websocket', module: 'websocket-client' } diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle b/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle index 9000e272ac4..457c7ce58ba 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle +++ b/dd-java-agent/instrumentation/play/play-appsec-2.6/build.gradle @@ -1,6 +1,3 @@ -def scalaVersion = '2.11' -def playVersion = '2.6.0' - muzzle { extraRepository("typesafe", "https://repo.typesafe.com/typesafe/maven-releases/") @@ -29,15 +26,15 @@ repositories { } dependencies { - compileOnly group: 'com.typesafe.play', name: "play_$scalaVersion", version: playVersion - compileOnly group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion + compileOnly group: 'com.typesafe.play', name: "play_2.11", version: '2.6.0' + compileOnly group: 'com.typesafe.play', name: "play-java_2.11", version: '2.6.0' compileOnly project(':dd-java-agent:instrumentation:play:play-2.6') implementation(project(':dd-java-agent:instrumentation:play:play-appsec-common')) testImplementation project(':dd-java-agent:instrumentation:play:play-2.6') testImplementation testFixtures(project(':dd-java-agent:instrumentation:play:play-2.6')) - testImplementation group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion - testImplementation(group: 'com.typesafe.play', name: "play-test_$scalaVersion", version: playVersion) { + testImplementation group: 'com.typesafe.play', name: "play-java_2.11", version: '2.6.0' + testImplementation(group: 'com.typesafe.play', name: "play-test_2.11", version: '2.6.0') { exclude group: 'org.eclipse.jetty.websocket', module: 'websocket-client' } diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle b/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle index cb2eca4d7de..dd7592d8b39 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle @@ -1,6 +1,3 @@ -def scalaVersion = '2.11' -def playVersion = '2.7.0' - muzzle { extraRepository("typesafe", "https://repo.typesafe.com/typesafe/maven-releases/") @@ -61,7 +58,7 @@ repositories { } dependencies { - compileOnly group: 'com.typesafe.play', name: "play-java_$scalaVersion", version: playVersion + compileOnly group: 'com.typesafe.play', name: "play-java_2.11", version: '2.7.0' implementation project(':dd-java-agent:instrumentation:play:play-2.6') implementation(project(':dd-java-agent:instrumentation:play:play-appsec-common')) From 42359594928be83b12a94a99b7ea256896885c95 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Mon, 5 Jan 2026 15:27:09 +0100 Subject: [PATCH 10/12] fix: Proper inheritance of tests, disable appsec / Instrumentation Gateway tests in simple play-2.6 module --- .../play26/server/PlayAsyncServerTest.groovy | 2 +- .../play26/server/PlayServerTest.groovy | 46 ++++++++++++++++++ .../PlayServerWithErrorHandlerTest.groovy | 48 ++++++++++++++++++- .../server/AbstractPlayServerTest.groovy | 9 +++- 4 files changed, 101 insertions(+), 4 deletions(-) diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy b/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy index 4155deea955..4d9e443369d 100644 --- a/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayAsyncServerTest.groovy @@ -6,7 +6,7 @@ import spock.lang.Shared import java.util.concurrent.Executors -class PlayAsyncServerTest extends AbstractPlayServerTest { +class PlayAsyncServerTest extends PlayServerTest { @Shared def executor diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy b/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy index 3a85e22386f..5f42d474c10 100644 --- a/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy @@ -1,4 +1,50 @@ package datadog.trace.instrumentation.play26.server class PlayServerTest extends AbstractPlayServerTest { + // Disabling involving Appsec / Instrumentation Gateway, they are tested in play-appsec-2.x modules + + @Override + boolean testBlocking() { + false + } + + @Override + boolean testBlockingOnResponse() { + false + } + + @Override + boolean testRequestBody() { + false + } + + @Override + boolean testBodyJson() { + false + } + + @Override + boolean testBodyUrlencoded() { + false + } + + @Override + boolean testBodyMultipart() { + false + } + + @Override + boolean testResponseBodyJson() { + false + } + + @Override + Map expectedIGPathParams() { + null + } + + @Override + boolean testBodyXml() { + false + } } diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy b/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy index dd4052f0bce..d64f38092a8 100644 --- a/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-2.6/src/test/groovy/datadog/trace/instrumentation/play26/server/PlayServerWithErrorHandlerTest.groovy @@ -1,4 +1,50 @@ package datadog.trace.instrumentation.play26.server -class PlayServerWithErrorHandlerTest extends AbstractPlayServerTest { +class PlayServerWithErrorHandlerTest extends AbstractPlayServerWithErrorHandlerTest { + // Disabling involving Appsec / Instrumentation Gateway, they are tested in play-appsec-2.x modules + + @Override + boolean testBlocking() { + false + } + + @Override + boolean testBlockingOnResponse() { + false + } + + @Override + boolean testRequestBody() { + false + } + + @Override + boolean testBodyJson() { + false + } + + @Override + boolean testBodyUrlencoded() { + false + } + + @Override + boolean testBodyMultipart() { + false + } + + @Override + boolean testResponseBodyJson() { + false + } + + @Override + Map expectedIGPathParams() { + null + } + + @Override + boolean testBodyXml() { + false + } } diff --git a/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerTest.groovy b/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerTest.groovy index 0cab2d1bf82..26d00882753 100644 --- a/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerTest.groovy +++ b/dd-java-agent/instrumentation/play/play-2.6/src/testFixtures/groovy/datadog/trace/instrumentation/play26/server/AbstractPlayServerTest.groovy @@ -1,7 +1,5 @@ package datadog.trace.instrumentation.play26.server -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_XML - import datadog.trace.agent.test.asserts.TraceAssert import datadog.trace.agent.test.base.HttpServer import datadog.trace.agent.test.base.HttpServerTest @@ -13,7 +11,9 @@ import groovy.transform.CompileStatic import okhttp3.MediaType import okhttp3.RequestBody import play.server.Server +import spock.lang.IgnoreIf +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_XML import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CUSTOM_EXCEPTION import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.EXCEPTION import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.FORWARDED @@ -152,6 +152,11 @@ class AbstractPlayServerTest extends HttpServerTest { } } + boolean testBodyXml() { + true + } + + @IgnoreIf({ !instance.testBodyXml() }) def 'test instrumentation gateway xml request body'() { setup: def request = request( From 127f0ebfce1362875564e969f6b0d3e976aa5616 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Mon, 5 Jan 2026 15:40:35 +0100 Subject: [PATCH 11/12] fix: play-appsec-2.7 has now two tests suite 2.7.+ and 2.+ (latest dep) --- .../play/play-appsec-2.7/build.gradle | 91 ++++++++++--------- 1 file changed, 50 insertions(+), 41 deletions(-) diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle b/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle index dd7592d8b39..e03850f3a0b 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle +++ b/dd-java-agent/instrumentation/play/play-appsec-2.7/build.gradle @@ -30,13 +30,46 @@ muzzle { apply from: "$rootDir/gradle/java.gradle" apply plugin: 'scala' -def buildTestRoutes = tasks.register('buildTestRoutes', JavaExec) -sourceSets { - test { +def configureRoutesCompilation(String sourceSetName) { + def capitalizedName = sourceSetName.capitalize() + def buildRoutesTask = tasks.register("build${capitalizedName}Routes", JavaExec) { + def routesFile = "${project.projectDir}/src/test/routes/conf/routes" + def outputDir = layout.buildDirectory.dir("generated/sources/${sourceSetName}Routes/scala") + + inputs.file routesFile + outputs.dir outputDir + + mainClass = 'generator.CompileRoutes' + args routesFile, outputDir.get().asFile.absolutePath + + classpath configurations.named('routeGeneratorRuntimeClasspath') + classpath tasks.named('compileRouteGeneratorScala') + + javaLauncher = getJavaLauncherFor(11) + } + + sourceSets.named(sourceSetName) { scala { - srcDir buildTestRoutes + srcDir buildRoutesTask } } + + tasks.named("compile${capitalizedName}Java", JavaCompile) { + configureCompiler(it, 11) + } + + tasks.named("compile${capitalizedName}Scala", ScalaCompile) { + configureCompiler(it, 11) + dependsOn buildRoutesTask + } + + tasks.named("compile${capitalizedName}Groovy", GroovyCompile) { + configureCompiler(it, 11) + classpath += files(tasks.named("compile${capitalizedName}Scala")) + } +} + +sourceSets { routeGenerator { scala { srcDir 'src/routeGenerator/scala' @@ -57,6 +90,8 @@ repositories { } } +addTestSuiteForDir('latestDepTest', 'test') + dependencies { compileOnly group: 'com.typesafe.play', name: "play-java_2.11", version: '2.7.0' implementation project(':dd-java-agent:instrumentation:play:play-2.6') @@ -71,13 +106,12 @@ dependencies { testImplementation project(':dd-java-agent:instrumentation:play:play-appsec-2.6') testImplementation testFixtures(project(':dd-java-agent:instrumentation:play:play-2.6')) - testImplementation group: 'com.typesafe.play', name: "play-java_2.13", version: '2.+' - testImplementation(group: 'com.typesafe.play', name: "play-test_2.13", version: '2.+') { + testImplementation group: 'com.typesafe.play', name: "play-java_2.13", version: '2.7.+' + testImplementation(group: 'com.typesafe.play', name: "play-test_2.13", version: '2.7.+') { exclude group: 'org.eclipse.jetty.websocket', module: 'websocket-client' } testImplementation group: 'com.typesafe.play', name: 'play-akka-http-server_2.13', version: '2.+' - testRuntimeOnly project(':dd-java-agent:instrumentation:netty:netty-4.0') testRuntimeOnly project(':dd-java-agent:instrumentation:netty:netty-4.1') testRuntimeOnly project(':dd-java-agent:instrumentation:akka:akka-http:akka-http-10.0') @@ -85,6 +119,13 @@ dependencies { testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-concurrent-2.8') testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-promise:scala-promise-2.10') testRuntimeOnly project(':dd-java-agent:instrumentation:scala:scala-promise:scala-promise-2.13') + + latestDepTestImplementation libs.scala213 + latestDepTestImplementation group: 'com.typesafe.play', name: "play-java_2.13", version: '2.+' + latestDepTestImplementation(group: 'com.typesafe.play', name: "play-test_2.13", version: '2.+') { + exclude group: 'org.eclipse.jetty.websocket', module: 'websocket-client' + } + latestDepTestImplementation group: 'com.typesafe.play', name: 'play-akka-http-server_2.13', version: '2.+' } configurations.matching({ it.name.startsWith('test') }).configureEach({ @@ -94,37 +135,5 @@ configurations.matching({ it.name.startsWith('test') }).configureEach({ } }) -tasks.named("compileTestJava", JavaCompile) { - configureCompiler(it, 11) -} - -tasks.named("compileTestScala", ScalaCompile) { - configureCompiler(it, 11) -} - -buildTestRoutes.configure { - def routesFile = "${project.projectDir}/src/test/routes/conf/routes" - def outputDir = layout.buildDirectory.dir('generated/sources/testRoutes/scala') - - it.inputs.file routesFile - it.outputs.dir outputDir - - it.mainClass = 'generator.CompileRoutes' - it.args routesFile, outputDir.get().asFile.absolutePath - - it.classpath configurations.named('routeGeneratorRuntimeClasspath') - it.classpath tasks.named('compileRouteGeneratorScala') - - it.javaLauncher = getJavaLauncherFor(11) -} - -tasks.named("compileTestScala", ScalaCompile) { - configureCompiler(it, 11) - dependsOn 'buildTestRoutes' -} - -tasks.named("compileTestGroovy", GroovyCompile) { - configureCompiler(it, 11) - // Groovy tests need access to generated routes compiled by Scala - classpath += files(tasks.named('compileTestScala')) -} +configureRoutesCompilation('test') +configureRoutesCompilation('latestDepTest') From 8e4baa0ca9cdd5f802a554b52f53b8447702cbb1 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Mon, 5 Jan 2026 15:44:28 +0100 Subject: [PATCH 12/12] fix: Deduplicate config in play-appsec-2.5 (similar to play-appsec-2.7) --- .../play/play-appsec-2.5/build.gradle | 76 +++++++------------ 1 file changed, 27 insertions(+), 49 deletions(-) diff --git a/dd-java-agent/instrumentation/play/play-appsec-2.5/build.gradle b/dd-java-agent/instrumentation/play/play-appsec-2.5/build.gradle index 10c1a6cac9d..63042d2515a 100644 --- a/dd-java-agent/instrumentation/play/play-appsec-2.5/build.gradle +++ b/dd-java-agent/instrumentation/play/play-appsec-2.5/build.gradle @@ -12,14 +12,35 @@ muzzle { apply from: "$rootDir/gradle/java.gradle" apply plugin: 'scala' -def buildTestRoutes = tasks.register('buildTestRoutes', JavaExec) +def configureRoutesCompilation(String sourceSetName) { + def capitalizedName = sourceSetName.capitalize() + def buildRoutesTask = tasks.register("build${capitalizedName}Routes", JavaExec) { + String routesFile = "${project.projectDir}/src/test/routes/conf/routes" + def outputDir = layout.buildDirectory.dir("generated/sources/${sourceSetName}Routes/scala") -sourceSets { - test { + inputs.file routesFile + outputs.dir outputDir + + mainClass.set 'generator.CompileRoutes' + args routesFile, outputDir.get().asFile.absolutePath + + classpath configurations.named('routeGeneratorRuntimeClasspath') + classpath tasks.named('compileRouteGeneratorScala') + } + + sourceSets.named(sourceSetName) { scala { - srcDir buildTestRoutes + srcDir buildRoutesTask } } + + tasks.named("compile${capitalizedName}Groovy", GroovyCompile) { + // Groovy tests need access to generated routes compiled by Scala + classpath += files(tasks.named("compile${capitalizedName}Scala")) + } +} + +sourceSets { routeGenerator { scala { srcDir 'src/routeGenerator/scala' @@ -46,14 +67,6 @@ tasks.withType(ScalaCompile).configureEach { } addTestSuiteForDir('latestDepTest', 'test') -def buildLatestDepTestRoutes = tasks.register('buildLatestDepTestRoutes', JavaExec) -sourceSets { - latestDepTest { - scala { - srcDir buildLatestDepTestRoutes - } - } -} dependencies { compileOnly group: 'com.typesafe.play', name: 'play_2.11', version: '2.5.0' @@ -86,40 +99,5 @@ dependencies { } } -buildTestRoutes.configure { - String routesFile = "${project.projectDir}/src/test/routes/conf/routes" - def outputDir = layout.buildDirectory.dir('generated/sources/testRoutes/scala') - - it.inputs.file routesFile - it.outputs.dir outputDir - - it.mainClass.set 'generator.CompileRoutes' - it.args routesFile, outputDir.get().asFile.absolutePath - - it.classpath configurations.named('routeGeneratorRuntimeClasspath') - it.classpath tasks.named('compileRouteGeneratorScala') -} - -buildLatestDepTestRoutes.configure { - String routesFile = "${project.projectDir}/src/test/routes/conf/routes" - def outputDir = layout.buildDirectory.dir('generated/sources/latestDepTestRoutes/scala') - - it.inputs.file routesFile - it.outputs.dir outputDir - - it.mainClass.set 'generator.CompileRoutes' - it.args routesFile, outputDir.get().asFile.absolutePath - - it.classpath configurations.named('routeGeneratorRuntimeClasspath') - it.classpath tasks.named('compileRouteGeneratorScala') -} - -tasks.named("compileTestGroovy", GroovyCompile) { - // Groovy tests need access to generated routes compiled by Scala - classpath += files(tasks.named('compileTestScala')) -} - -tasks.named("compileLatestDepTestGroovy", GroovyCompile) { - // Groovy tests need access to generated routes compiled by Scala - classpath += files(tasks.named('compileLatestDepTestScala')) -} +configureRoutesCompilation('test') +configureRoutesCompilation('latestDepTest')