diff --git a/build.gradle.kts b/build.gradle.kts index 92355583..7cd939d1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,42 +1,51 @@ import org.radarbase.gradle.plugin.radarKotlin plugins { - id("org.radarbase.radar-root-project") version Versions.radarCommons - id("org.radarbase.radar-dependency-management") version Versions.radarCommons - id("org.radarbase.radar-kotlin") version Versions.radarCommons apply false + alias(libs.plugins.radar.root.project) + alias(libs.plugins.radar.dependency.management) + alias(libs.plugins.radar.kotlin) apply false } repositories { - // Use jcenter for resolving dependencies. - // You can declare any Maven/Ivy/file repository here. mavenCentral() } description = "Kafka connector for REST API sources" radarRootProject { - projectVersion.set(Versions.project) - gradleVersion.set(Versions.wrapper) + projectVersion.set(libs.versions.project) + gradleVersion.set(libs.versions.gradle) } subprojects { apply(plugin = "org.radarbase.radar-kotlin") + // --- Vulnerability fixes start --- + dependencies { + plugins.withType { + constraints { + add("implementation", rootProject.libs.jackson.bom) { + because("Force safe version of Jackson across all modules") + } + add("implementation", rootProject.libs.commons.lang3) { + because("Force safe version of commons-lang3 across all modules") + } + } + } + } configurations.all { - resolutionStrategy { - /* The entries in the block below are added here to force the version of - * transitive dependencies and mitigate reported vulnerabilities */ - force( - "org.apache.commons:commons-lang3:3.18.0", - ) + resolutionStrategy.dependencySubstitution { + // Substitute the old group/module with drop-in replacement + substitute(module("org.lz4:lz4-java")) + .using(module(rootProject.libs.lz4.get().toString())) + .because("Force safe version of LZ4 across all modules") } } + // --- Vulnerability fixes end --- radarKotlin { - javaVersion.set(Versions.java) - kotlinVersion.set(Versions.kotlin) - slf4jVersion.set(Versions.slf4j) - log4j2Version.set(Versions.log4j2) - junitVersion.set(Versions.junit) + log4j2Version.set(rootProject.libs.versions.log4j2) + sentryEnabled.set(true) + openTelemetryAgentEnabled.set(false) } } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts deleted file mode 100644 index dfbb6e6f..00000000 --- a/buildSrc/build.gradle.kts +++ /dev/null @@ -1,7 +0,0 @@ -plugins { - kotlin("jvm") version "1.9.22" -} - -repositories { - mavenCentral() -} diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt deleted file mode 100644 index 05b55a8d..00000000 --- a/buildSrc/src/main/kotlin/Versions.kt +++ /dev/null @@ -1,33 +0,0 @@ -@Suppress("ConstPropertyName", "MemberVisibilityCanBePrivate") -object Versions { - const val project = "0.7.2" - - const val java = 17 - const val kotlin = "1.9.22" - const val wrapper = "8.13" - - const val radarCommons = "1.2.4" - const val confluent = "7.8.1" - const val kafka = "$confluent-ce" - const val avro = "1.12.0" - - // From image - const val jackson = "2.17.3" - - const val log4j2 = "2.23.1" - const val slf4j = "2.0.13" - const val sentryLog4j = "1.7.30" - const val sentryOpenTelemetryAgent = "8.1.0" - - const val okhttp = "4.12.0" - - const val firebaseAdmin = "9.6.0" - const val radarSchemas = "0.8.14" - const val ktor = "2.3.10" - - const val junit = "5.10.2" - const val wiremock = "3.0.1" - const val mockito = "5.11.0" - - const val nettyVersion = "4.1.125.Final" -} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 00000000..c4161d60 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,62 @@ +[versions] +project = "0.7.3" +gradle = "8.14" +kotlin = "1.9.24" +radarCommons = "1.2.6" +confluent = "7.8.1" +avro = "1.12.1" +# @pin Upgrade to 2.21.x requires kotlin v2 minimum +jackson = "2.20.2" +jacksonAnnotations = "2.20" +log4j2 = "2.23.1" +slf4j = "2.0.17" +sentryLog4j = "1.7.30" +sentryOpenTelemetryAgent = "8.36.0" +# @pin Upgrade to 5.x.x requires kotlin v2 minimum +okhttp = "4.12.0" +firebaseAdmin = "9.8.0" +radarSchemas = "0.8.16" +# @pin Upgrade to 3.x.x requires kotlin v2 minimum +ktor = "2.3.13" +wiremock = "3.0.1" +mockito = "5.23.0" +netty = "4.2.10.Final" +commonsLang3 = "3.20.0" +lz4 = "1.10.1" + +[libraries] +lz4 = { module = "at.yawk.lz4:lz4-java", version.ref = "lz4" } +radar-commons-kotlin = { module = "org.radarbase:radar-commons-kotlin", version.ref = "radarCommons" } +radar-schemas-commons = { module = "org.radarbase:radar-schemas-commons", version.ref = "radarSchemas" } +kafka-connect-api = "org.apache.kafka:connect-api:7.8.1-ce" +kafka-connect-avro-converter = { module = "io.confluent:kafka-connect-avro-converter", version.ref = "confluent" } +okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" } +jackson-bom = { module = "com.fasterxml.jackson:jackson-bom", version.ref = "jackson" } +jackson-annotations = { module = "com.fasterxml.jackson.core:jackson-annotations", version.ref = "jacksonAnnotations" } +jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } +jackson-dataformat-yaml = { module = "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml", version.ref = "jackson" } +jackson-datatype-jsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version.ref = "jackson" } +jackson-module-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin", version.ref = "jackson" } +kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } +ktor-client-auth = { module = "io.ktor:ktor-client-auth", version.ref = "ktor" } +ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } +ktor-serialization-jackson = { module = "io.ktor:ktor-serialization-jackson", version.ref = "ktor" } +ktor-client-cio = { module = "io.ktor:ktor-client-cio-jvm", version.ref = "ktor" } +ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } +firebase-admin = { module = "com.google.firebase:firebase-admin", version.ref = "firebaseAdmin" } +avro = { module = "org.apache.avro:avro", version.ref = "avro" } +slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" } +sentry-log4j = { module = "io.sentry:sentry-log4j", version.ref = "sentryLog4j" } +sentry-opentelemetry-agent = { module = "io.sentry:sentry-opentelemetry-agent", version.ref = "sentryOpenTelemetryAgent" } +netty-handler-proxy = { module = "io.netty:netty-handler-proxy", version.ref = "netty" } +netty-handler = { module = "io.netty:netty-handler", version.ref = "netty" } +commons-lang3 = { module = "org.apache.commons:commons-lang3", version.ref = "commonsLang3" } +mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" } +wiremock = { module = "com.github.tomakehurst:wiremock", version.ref = "wiremock" } +kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } +kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" } + +[plugins] +radar-root-project = { id = "org.radarbase.radar-root-project", version.ref = "radarCommons" } +radar-dependency-management = { id = "org.radarbase.radar-dependency-management", version.ref = "radarCommons" } +radar-kotlin = { id = "org.radarbase.radar-kotlin", version.ref = "radarCommons" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 37f853b1..ca025c83 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/kafka-connect-fitbit-source/Dockerfile b/kafka-connect-fitbit-source/Dockerfile index 755c9703..ca5fe3e7 100644 --- a/kafka-connect-fitbit-source/Dockerfile +++ b/kafka-connect-fitbit-source/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=$BUILDPLATFORM gradle:8.13-jdk17 AS builder +FROM --platform=$BUILDPLATFORM gradle:8.14-jdk17 AS builder RUN mkdir /code WORKDIR /code @@ -20,7 +20,7 @@ WORKDIR /code ENV GRADLE_USER_HOME=/code/.gradlecache \ GRADLE_OPTS="-Dorg.gradle.vfs.watch=false -Djdk.lang.Process.launchMechanism=vfork" -COPY buildSrc /code/buildSrc +COPY ./gradle/libs.versions.toml /code/gradle/ COPY ./build.gradle.kts ./settings.gradle.kts ./gradle.properties /code/ COPY kafka-connect-rest-source/build.gradle.kts /code/kafka-connect-rest-source/ COPY kafka-connect-fitbit-source/build.gradle.kts /code/kafka-connect-fitbit-source/ @@ -32,7 +32,7 @@ COPY ./kafka-connect-fitbit-source/src/ /code/kafka-connect-fitbit-source/src RUN gradle jar -FROM confluentinc/cp-kafka-connect-base:7.8.1 +FROM confluentinc/cp-kafka-connect-base:7.8.7 USER appuser diff --git a/kafka-connect-fitbit-source/build.gradle.kts b/kafka-connect-fitbit-source/build.gradle.kts index 10d6ba34..78dbf5e5 100644 --- a/kafka-connect-fitbit-source/build.gradle.kts +++ b/kafka-connect-fitbit-source/build.gradle.kts @@ -5,33 +5,33 @@ dependencies { /* The entries in the block below are added here to force the version of * transitive dependencies and mitigate reported vulnerabilities */ - implementation("io.netty:netty-handler-proxy:${Versions.nettyVersion}") - implementation("io.netty:netty-handler:${Versions.nettyVersion}") + implementation(libs.netty.handler.proxy) + implementation(libs.netty.handler) api(project(":kafka-connect-rest-source")) api(project(":oura-library")) - api("io.confluent:kafka-connect-avro-converter:${Versions.confluent}") - api("org.radarbase:radar-schemas-commons:${Versions.radarSchemas}") - implementation("org.radarbase:radar-commons-kotlin:${Versions.radarCommons}") + api(libs.kafka.connect.avro.converter) + api(libs.radar.schemas.commons) + implementation(libs.radar.commons.kotlin) - api("com.squareup.okhttp3:okhttp:${Versions.okhttp}") - implementation(platform("com.fasterxml.jackson:jackson-bom:${Versions.jackson}")) - implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml") - implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") - implementation("com.google.firebase:firebase-admin:${Versions.firebaseAdmin}") - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.41") + api(libs.okhttp) + implementation(platform(libs.jackson.bom)) + implementation(libs.jackson.dataformat.yaml) + implementation(libs.jackson.datatype.jsr310) + implementation(libs.firebase.admin) + implementation(libs.kotlin.stdlib) - implementation("io.ktor:ktor-client-auth:${Versions.ktor}") - implementation("io.ktor:ktor-client-content-negotiation:${Versions.ktor}") - implementation("io.ktor:ktor-serialization-jackson:${Versions.ktor}") - implementation("io.ktor:ktor-client-cio-jvm:${Versions.ktor}") - implementation("io.ktor:ktor-serialization-kotlinx-json:${Versions.ktor}") - implementation("com.fasterxml.jackson.module:jackson-module-kotlin:${Versions.jackson}") + implementation(libs.ktor.client.auth) + implementation(libs.ktor.client.content.negotiation) + implementation(libs.ktor.serialization.jackson) + implementation(libs.ktor.client.cio) + implementation(libs.ktor.serialization.kotlinx.json) + implementation(libs.jackson.module.kotlin) // Included in connector runtime - compileOnly("org.apache.kafka:connect-api:${Versions.kafka}") - compileOnly(platform("com.fasterxml.jackson:jackson-bom:${Versions.jackson}")) - compileOnly("com.fasterxml.jackson.core:jackson-databind") + compileOnly(libs.kafka.connect.api) + compileOnly(platform(libs.jackson.bom)) + compileOnly(libs.jackson.databind) - testImplementation("org.apache.kafka:connect-api:${Versions.kafka}") + testImplementation(libs.kafka.connect.api) } diff --git a/kafka-connect-oura-source/Dockerfile b/kafka-connect-oura-source/Dockerfile index cf3cd2c8..b5d87718 100644 --- a/kafka-connect-oura-source/Dockerfile +++ b/kafka-connect-oura-source/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=$BUILDPLATFORM gradle:8.13-jdk17 AS builder +FROM --platform=$BUILDPLATFORM gradle:8.14-jdk17 AS builder RUN mkdir /code WORKDIR /code @@ -20,7 +20,7 @@ WORKDIR /code ENV GRADLE_USER_HOME=/code/.gradlecache \ GRADLE_OPTS="-Dorg.gradle.vfs.watch=false -Djdk.lang.Process.launchMechanism=vfork" -COPY buildSrc /code/buildSrc +COPY ./gradle/libs.versions.toml /code/gradle/ COPY ./build.gradle.kts ./settings.gradle.kts ./gradle.properties /code/ COPY kafka-connect-oura-source/build.gradle.kts /code/kafka-connect-oura-source/ COPY oura-library/build.gradle /code/oura-library/ @@ -32,7 +32,7 @@ COPY ./oura-library/src/ /code/oura-library/src RUN gradle jar -FROM confluentinc/cp-kafka-connect-base:7.8.1 +FROM confluentinc/cp-kafka-connect-base:7.8.7 LABEL org.opencontainers.image.authors="pauline.conde@kcl.ac.uk" diff --git a/kafka-connect-oura-source/build.gradle.kts b/kafka-connect-oura-source/build.gradle.kts index 65a18e42..8ba12ee8 100644 --- a/kafka-connect-oura-source/build.gradle.kts +++ b/kafka-connect-oura-source/build.gradle.kts @@ -5,32 +5,32 @@ dependencies { /* The entries in the block below are added here to force the version of * transitive dependencies and mitigate reported vulnerabilities */ - implementation("io.netty:netty-handler-proxy:${Versions.nettyVersion}") - implementation("io.netty:netty-handler:${Versions.nettyVersion}") + implementation(libs.netty.handler.proxy) + implementation(libs.netty.handler) api(project(":oura-library")) - api("io.confluent:kafka-connect-avro-converter:${Versions.confluent}") - api("org.radarbase:radar-schemas-commons:${Versions.radarSchemas}") - implementation("org.radarbase:radar-commons-kotlin:${Versions.radarCommons}") + api(libs.kafka.connect.avro.converter) + api(libs.radar.schemas.commons) + implementation(libs.radar.commons.kotlin) - api("com.squareup.okhttp3:okhttp:${Versions.okhttp}") - implementation(platform("com.fasterxml.jackson:jackson-bom:${Versions.jackson}")) - implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml") - implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") - implementation("com.google.firebase:firebase-admin:${Versions.firebaseAdmin}") - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.21") + api(libs.okhttp) + implementation(platform(libs.jackson.bom)) + implementation(libs.jackson.dataformat.yaml) + implementation(libs.jackson.datatype.jsr310) + implementation(libs.firebase.admin) + implementation(libs.kotlin.stdlib) - implementation("io.ktor:ktor-client-auth:${Versions.ktor}") - implementation("io.ktor:ktor-client-content-negotiation:${Versions.ktor}") - implementation("io.ktor:ktor-serialization-jackson:${Versions.ktor}") - implementation("io.ktor:ktor-client-cio-jvm:${Versions.ktor}") - implementation("io.ktor:ktor-serialization-kotlinx-json:${Versions.ktor}") - implementation("com.fasterxml.jackson.module:jackson-module-kotlin:${Versions.jackson}") + implementation(libs.ktor.client.auth) + implementation(libs.ktor.client.content.negotiation) + implementation(libs.ktor.serialization.jackson) + implementation(libs.ktor.client.cio) + implementation(libs.ktor.serialization.kotlinx.json) + implementation(libs.jackson.module.kotlin) // Included in connector runtime - compileOnly("org.apache.kafka:connect-api:${Versions.kafka}") - compileOnly(platform("com.fasterxml.jackson:jackson-bom:${Versions.jackson}")) - compileOnly("com.fasterxml.jackson.core:jackson-databind") + compileOnly(libs.kafka.connect.api) + compileOnly(platform(libs.jackson.bom)) + compileOnly(libs.jackson.databind) - testImplementation("org.apache.kafka:connect-api:${Versions.kafka}") + testImplementation(libs.kafka.connect.api) } diff --git a/kafka-connect-rest-source/build.gradle.kts b/kafka-connect-rest-source/build.gradle.kts index 8c29f835..0c5687b4 100644 --- a/kafka-connect-rest-source/build.gradle.kts +++ b/kafka-connect-rest-source/build.gradle.kts @@ -1,22 +1,25 @@ description = "Kafka connector for generic REST API sources" dependencies { - api("com.squareup.okhttp3:okhttp:${Versions.okhttp}") + api(libs.okhttp) // included in runtime - compileOnly("org.apache.kafka:connect-api:${Versions.kafka}") - compileOnly("org.slf4j:slf4j-api:${Versions.slf4j}") + compileOnly(libs.kafka.connect.api) + compileOnly(libs.slf4j.api) - testImplementation("org.mockito:mockito-core:${Versions.mockito}") - testImplementation("com.github.tomakehurst:wiremock:${Versions.wiremock}") + testImplementation(libs.mockito.core) + testImplementation(libs.wiremock) - testImplementation("org.apache.kafka:connect-api:${Versions.kafka}") + testImplementation(libs.kafka.connect.api) // Application monitoring // These dependencies are not used by the REST connector, but copied into the Docker image (Dockerfile) - runtimeOnly("io.sentry:sentry-log4j:${Versions.sentryLog4j}") { + runtimeOnly(libs.sentry.log4j) { // Exclude log4j with security vulnerability (safe version is provided by docker image). exclude(group = "log4j", module = "log4j") + exclude(group = "org.slf4j", module = "slf4j-api") + // Exclude Jackson with security vulnerability (safe version is provided by docker image). + exclude(group = "com.fasterxml.jackson.core") } - runtimeOnly("io.sentry:sentry-opentelemetry-agent:${Versions.sentryOpenTelemetryAgent}") + runtimeOnly(libs.sentry.opentelemetry.agent) } diff --git a/oura-library/build.gradle b/oura-library/build.gradle index 25484b46..6d0cc80a 100644 --- a/oura-library/build.gradle +++ b/oura-library/build.gradle @@ -12,25 +12,25 @@ repositories { dependencies { // Use the Kotlin JDK 8 standard library. - implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' + implementation libs.kotlin.stdlib - implementation "com.squareup.okhttp3:okhttp:$Versions.okhttp" + implementation libs.okhttp - implementation "org.radarbase:radar-schemas-commons:$Versions.radarSchemas" + implementation libs.radar.schemas.commons - implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: "$Versions.jackson" + implementation libs.jackson.annotations - implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "$Versions.jackson" + implementation libs.jackson.databind - implementation group: 'org.apache.avro', name: 'avro', version: "$Versions.avro" + implementation libs.avro - implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$Versions.jackson" + implementation libs.jackson.datatype.jsr310 // Use the Kotlin test library. - testImplementation 'org.jetbrains.kotlin:kotlin-test' + testImplementation libs.kotlin.test // Use the Kotlin JUnit integration. - testImplementation 'org.jetbrains.kotlin:kotlin-test-junit' + testImplementation libs.kotlin.test.junit } project.afterEvaluate { @@ -44,4 +44,4 @@ project.afterEvaluate { } } } -} \ No newline at end of file +}