From 549ec7482dd51399892945d943bdccc7e449a3ba Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Thu, 4 Jun 2026 22:06:04 +0200 Subject: [PATCH 1/2] Add MASS Gradle convention plugin --- build-logic/conventions/build.gradle.kts | 14 ++++++++++++++ .../datadog/buildlogic/mass/MassExtension.kt | 19 +++++++++++++++++++ .../main/kotlin/dd-trace-java.mass.gradle.kts | 4 ++++ build-logic/settings.gradle.kts | 1 + .../instrumentation/cics-9.1/build.gradle | 15 +++++---------- dd-smoke-tests/rum/wildfly-15/build.gradle | 12 ++---------- .../application/build.gradle | 12 ++---------- .../application/settings.gradle | 2 ++ dd-smoke-tests/wildfly/build.gradle | 12 ++---------- 9 files changed, 51 insertions(+), 40 deletions(-) create mode 100644 build-logic/conventions/build.gradle.kts create mode 100644 build-logic/conventions/src/main/kotlin/datadog/buildlogic/mass/MassExtension.kt create mode 100644 build-logic/conventions/src/main/kotlin/dd-trace-java.mass.gradle.kts diff --git a/build-logic/conventions/build.gradle.kts b/build-logic/conventions/build.gradle.kts new file mode 100644 index 00000000000..a31634bb8ec --- /dev/null +++ b/build-logic/conventions/build.gradle.kts @@ -0,0 +1,14 @@ +plugins { + `kotlin-dsl` +} + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +kotlin { + compilerOptions { + jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8) + } +} diff --git a/build-logic/conventions/src/main/kotlin/datadog/buildlogic/mass/MassExtension.kt b/build-logic/conventions/src/main/kotlin/datadog/buildlogic/mass/MassExtension.kt new file mode 100644 index 00000000000..2dcb90a9c7b --- /dev/null +++ b/build-logic/conventions/src/main/kotlin/datadog/buildlogic/mass/MassExtension.kt @@ -0,0 +1,19 @@ +package datadog.buildlogic.mass + +import javax.inject.Inject +import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.Property +import org.gradle.api.provider.ProviderFactory + +open class MassExtension +@Inject +constructor(objects: ObjectFactory, providers: ProviderFactory) { + val readUrl: Property = + objects.property(String::class.java).convention(providers.environmentVariable("MASS_READ_URL")) + + fun artifactUrl(upstreamArtifactUrl: String): String { + val massReadUrl = readUrl.orNull ?: return "https://$upstreamArtifactUrl" + val baseUrl = if (massReadUrl.endsWith("/")) massReadUrl else "$massReadUrl/" + return "${baseUrl}internal/artifact/$upstreamArtifactUrl" + } +} diff --git a/build-logic/conventions/src/main/kotlin/dd-trace-java.mass.gradle.kts b/build-logic/conventions/src/main/kotlin/dd-trace-java.mass.gradle.kts new file mode 100644 index 00000000000..147bff69ab7 --- /dev/null +++ b/build-logic/conventions/src/main/kotlin/dd-trace-java.mass.gradle.kts @@ -0,0 +1,4 @@ +import datadog.buildlogic.mass.MassExtension +import org.gradle.kotlin.dsl.create + +extensions.create("mass") diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts index 612ae4b8fdd..c218e2cd34c 100644 --- a/build-logic/settings.gradle.kts +++ b/build-logic/settings.gradle.kts @@ -47,4 +47,5 @@ dependencyResolutionManagement { rootProject.name = "build-logic" +include(":conventions") include(":smoke-test") diff --git a/dd-java-agent/instrumentation/cics-9.1/build.gradle b/dd-java-agent/instrumentation/cics-9.1/build.gradle index 405ae7e920d..41f3d89ebbc 100644 --- a/dd-java-agent/instrumentation/cics-9.1/build.gradle +++ b/dd-java-agent/instrumentation/cics-9.1/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'dd-trace-java.mass' +} + apply from: "$rootDir/gradle/java.gradle" // Configuration for downloading CICS SDK from IBM @@ -6,18 +10,9 @@ ext { cicsSdkName = 'CICS_TG_SDK_91_Unix' } -def massArtifactUrl = { String upstreamArtifactUrl -> - def massReadUrl = providers.environmentVariable('MASS_READ_URL').orNull - if (massReadUrl == null) { - return "https://${upstreamArtifactUrl}" - } - def baseUrl = massReadUrl.endsWith('/') ? massReadUrl : "${massReadUrl}/" - return "${baseUrl}internal/artifact/${upstreamArtifactUrl}" -} - repositories { ivy { - url = massArtifactUrl('public.dhe.ibm.com/software/htp/cics/support/supportpacs/individual/') + url = mass.artifactUrl('public.dhe.ibm.com/software/htp/cics/support/supportpacs/individual/') patternLayout { artifact '[module].[ext]' } diff --git a/dd-smoke-tests/rum/wildfly-15/build.gradle b/dd-smoke-tests/rum/wildfly-15/build.gradle index 698474c51b1..2be56770cd8 100644 --- a/dd-smoke-tests/rum/wildfly-15/build.gradle +++ b/dd-smoke-tests/rum/wildfly-15/build.gradle @@ -2,6 +2,7 @@ import datadog.buildlogic.smoketest.NestedGradleBuild plugins { id 'dd-trace-java.smoke-test-app' + id 'dd-trace-java.mass' } ext { @@ -12,18 +13,9 @@ ext { serverExtension = 'zip' } -def massArtifactUrl = { String upstreamArtifactUrl -> - def massReadUrl = providers.environmentVariable('MASS_READ_URL').orNull - if (massReadUrl == null) { - return "https://${upstreamArtifactUrl}" - } - def baseUrl = massReadUrl.endsWith('/') ? massReadUrl : "${massReadUrl}/" - return "${baseUrl}internal/artifact/${upstreamArtifactUrl}" -} - repositories { ivy { - url = massArtifactUrl('github.com/wildfly/wildfly/releases/download/') + url = mass.artifactUrl('github.com/wildfly/wildfly/releases/download/') // Restrict this repository to WildFly distribution artifacts only. // Without this filter, Gradle may probe this host for unrelated dependencies // (for example JUnit/Mockito), which makes the build flaky when the host is unreachable. diff --git a/dd-smoke-tests/springboot-tomcat/application/build.gradle b/dd-smoke-tests/springboot-tomcat/application/build.gradle index 6f04685ef8c..bc84586e9ca 100644 --- a/dd-smoke-tests/springboot-tomcat/application/build.gradle +++ b/dd-smoke-tests/springboot-tomcat/application/build.gradle @@ -1,6 +1,7 @@ plugins { id 'war' id 'org.springframework.boot' version '2.5.12' + id 'dd-trace-java.mass' } def sharedRootDir = "$rootDir/../../../" @@ -28,18 +29,9 @@ ext { serverExtension = 'zip' } -def massArtifactUrl = { String upstreamArtifactUrl -> - def massReadUrl = providers.environmentVariable('MASS_READ_URL').orNull - if (massReadUrl == null) { - return "https://${upstreamArtifactUrl}" - } - def baseUrl = massReadUrl.endsWith('/') ? massReadUrl : "${massReadUrl}/" - return "${baseUrl}internal/artifact/${upstreamArtifactUrl}" -} - repositories { ivy { - url = massArtifactUrl('dlcdn.apache.org') + url = mass.artifactUrl('dlcdn.apache.org') patternLayout { artifact '/[organisation]/[module]/v[revision]/bin/apache-[organisation]-[revision].[ext]' } diff --git a/dd-smoke-tests/springboot-tomcat/application/settings.gradle b/dd-smoke-tests/springboot-tomcat/application/settings.gradle index c526fe40384..48853d3895e 100644 --- a/dd-smoke-tests/springboot-tomcat/application/settings.gradle +++ b/dd-smoke-tests/springboot-tomcat/application/settings.gradle @@ -1,4 +1,6 @@ pluginManagement { + includeBuild("$settingsDir/../../../build-logic") + repositories { mavenLocal() if (settings.hasProperty("gradlePluginProxy")) { diff --git a/dd-smoke-tests/wildfly/build.gradle b/dd-smoke-tests/wildfly/build.gradle index 4d00d86c18b..cc8d48bf5a9 100644 --- a/dd-smoke-tests/wildfly/build.gradle +++ b/dd-smoke-tests/wildfly/build.gradle @@ -2,6 +2,7 @@ import datadog.buildlogic.smoketest.NestedGradleBuild plugins { id 'dd-trace-java.smoke-test-app' + id 'dd-trace-java.mass' } ext { @@ -12,18 +13,9 @@ ext { serverExtension = 'zip' } -def massArtifactUrl = { String upstreamArtifactUrl -> - def massReadUrl = providers.environmentVariable('MASS_READ_URL').orNull - if (massReadUrl == null) { - return "https://${upstreamArtifactUrl}" - } - def baseUrl = massReadUrl.endsWith('/') ? massReadUrl : "${massReadUrl}/" - return "${baseUrl}internal/artifact/${upstreamArtifactUrl}" -} - repositories { ivy { - url = massArtifactUrl('github.com/wildfly/wildfly/releases/download/') + url = mass.artifactUrl('github.com/wildfly/wildfly/releases/download/') // Restrict this repository to WildFly distribution artifacts only. // Without this filter, Gradle may probe this host for unrelated dependencies // (for example JUnit/Mockito), which makes the build flaky when the host is unreachable. From b134264c22a23451a2ff1157724cc5891284ca8e Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Thu, 4 Jun 2026 23:31:22 +0200 Subject: [PATCH 2/2] refactor(smoke-tests): move Tomcat download outward Keep the nested Spring Boot app isolated from build-logic. Resolve the Tomcat archive in the outer smoke-test project. Pass the expanded directory to tests with a JVM argument provider. --- .../application/build.gradle | 67 +----------------- .../application/settings.gradle | 2 - dd-smoke-tests/springboot-tomcat/build.gradle | 70 ++++++++++++++++++- .../springboot-tomcat/gradle.lockfile | 1 + 4 files changed, 72 insertions(+), 68 deletions(-) diff --git a/dd-smoke-tests/springboot-tomcat/application/build.gradle b/dd-smoke-tests/springboot-tomcat/application/build.gradle index bc84586e9ca..7e9833cc85a 100644 --- a/dd-smoke-tests/springboot-tomcat/application/build.gradle +++ b/dd-smoke-tests/springboot-tomcat/application/build.gradle @@ -1,7 +1,6 @@ plugins { id 'war' id 'org.springframework.boot' version '2.5.12' - id 'dd-trace-java.mass' } def sharedRootDir = "$rootDir/../../../" @@ -22,69 +21,7 @@ java { sourceCompatibility = JavaVersion.VERSION_1_8 } -ext { - serverName = 'tomcat' - serverModule = 'tomcat-9' - serverVersion = '9.0.117' - serverExtension = 'zip' -} - -repositories { - ivy { - url = mass.artifactUrl('dlcdn.apache.org') - patternLayout { - artifact '/[organisation]/[module]/v[revision]/bin/apache-[organisation]-[revision].[ext]' - } - metadataSources { - it.artifact() - } - } -} - -configurations { - serverFile { - extendsFrom implementation - canBeResolved = true - } -} - dependencies { - // uses the ivy repository url to download the tomcat server - // organisation = serverName, revision = serverVersion, module = serverModule, ext = serverExtension - serverFile "${serverName}:${serverModule}:${serverVersion}@${serverExtension}" - - implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.5.12' - providedRuntime group: 'org.springframework.boot', name: 'spring-boot-starter-tomcat', version: '2.5.12' -} - -tasks.register("unzip", Copy) { - def zipFileNamePrefix = "tomcat" - def serverZipTree = providers.provider { - // eager access - def zipPath = project.configurations.serverFile.find { - it.name.startsWith(zipFileNamePrefix) - } - if (zipPath == null) { - throw new GradleException("Can't find server zip file that starts with: " + zipFileNamePrefix) - } - zipTree(zipPath) - } - - from serverZipTree - into layout.buildDirectory - - // When tests are disabled this would still be run, so disable this manually - onlyIf { !project.rootProject.hasProperty("skipTests") } -} - -tasks.named('bootWar') { - dependsOn 'unzip' -} - -tasks.named('bootWarMainClassName') { - dependsOn 'unzip' -} - -tasks.named('war') { - dependsOn 'unzip' + implementation 'org.springframework.boot:spring-boot-starter-web:2.5.12' + providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat:2.5.12' } diff --git a/dd-smoke-tests/springboot-tomcat/application/settings.gradle b/dd-smoke-tests/springboot-tomcat/application/settings.gradle index 48853d3895e..c526fe40384 100644 --- a/dd-smoke-tests/springboot-tomcat/application/settings.gradle +++ b/dd-smoke-tests/springboot-tomcat/application/settings.gradle @@ -1,6 +1,4 @@ pluginManagement { - includeBuild("$settingsDir/../../../build-logic") - repositories { mavenLocal() if (settings.hasProperty("gradlePluginProxy")) { diff --git a/dd-smoke-tests/springboot-tomcat/build.gradle b/dd-smoke-tests/springboot-tomcat/build.gradle index 6ae55b8e65d..d7029149a9d 100644 --- a/dd-smoke-tests/springboot-tomcat/build.gradle +++ b/dd-smoke-tests/springboot-tomcat/build.gradle @@ -1,5 +1,6 @@ plugins { id 'dd-trace-java.smoke-test-app' + id 'dd-trace-java.mass' } apply from: "$rootDir/gradle/java.gradle" @@ -7,22 +8,89 @@ apply from: "$rootDir/gradle/java.gradle" description = 'SpringBoot Tomcat Smoke Tests.' def serverName = 'tomcat' +def serverModule = 'tomcat-9' def serverVersion = '9.0.117' +def serverExtension = 'zip' + +repositories { + ivy { + url = mass.artifactUrl('dlcdn.apache.org') + content { + includeGroup serverName + } + patternLayout { + artifact '/[organisation]/[module]/v[revision]/bin/apache-[organisation]-[revision].[ext]' + } + metadataSources { + it.artifact() + } + } +} + +configurations { + register('serverFile') { + canBeConsumed = false + canBeResolved = true + } +} smokeTestApp { application { taskName = 'bootWar' artifactPath = 'libs/springboot-tomcat-smoketest.war' sysProperty = 'datadog.smoketest.springboot.war.path' - additionalSystemProperties.put('datadog.smoketest.tomcatDir', "apache-${serverName}-${serverVersion}") } } dependencies { + // Uses the ivy repository url to download the Tomcat server zip. + // organisation = serverName, module = serverModule, revision = serverVersion, + // ext = serverExtension + serverFile "${serverName}:${serverModule}:${serverVersion}@${serverExtension}" + testImplementation project(':dd-smoke-tests') testImplementation group: 'commons-io', name: 'commons-io', version: '2.11.0' } +def serverDirectory = layout.buildDirectory.dir("server") + +tasks.register("unzip", Copy) { + def zipFileNamePrefix = "tomcat" + def serverZipTree = providers.provider { + // eager access + def zipPath = project.configurations.serverFile.find { + it.name.startsWith(zipFileNamePrefix) + } + if (zipPath == null) { + throw new GradleException("Can't find server zip file that starts with: " + zipFileNamePrefix) + } + zipTree(zipPath) + } + + from serverZipTree + into serverDirectory + + // When tests are disabled this would still be run, so disable this manually + onlyIf { !project.rootProject.hasProperty("skipTests") } +} + +def tomcatDir = serverDirectory.map { + it.dir("apache-${serverName}-${serverVersion}") +} + +tasks.withType(Test).configureEach { + dependsOn 'unzip' + + jvmArgumentProviders.add(new CommandLineArgumentProvider() { + @Override + Iterable asArguments() { + return tomcatDir.map { + ["-Ddatadog.smoketest.tomcatDir=${it.asFile.absolutePath}"] + }.get() + } + }) +} + spotless { java { target "**/*.java" diff --git a/dd-smoke-tests/springboot-tomcat/gradle.lockfile b/dd-smoke-tests/springboot-tomcat/gradle.lockfile index 5b801a39bfb..b2fe608ef0c 100644 --- a/dd-smoke-tests/springboot-tomcat/gradle.lockfile +++ b/dd-smoke-tests/springboot-tomcat/gradle.lockfile @@ -109,4 +109,5 @@ org.spockframework:spock-core:2.4-groovy-3.0=testCompileClasspath,testRuntimeCla org.tabletest:tabletest-junit:1.2.1=testCompileClasspath,testRuntimeClasspath org.tabletest:tabletest-parser:1.2.0=testCompileClasspath,testRuntimeClasspath org.xmlresolver:xmlresolver:5.3.3=spotbugs +tomcat:tomcat-9:9.0.117=serverFile empty=annotationProcessor,runtimeClasspath,spotbugsPlugins,testAnnotationProcessor