| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| |
| import com.github.spotbugs.SpotBugsTask |
| import org.nosphere.apache.rat.RatTask |
| |
| import java.nio.file.Files |
| import java.nio.file.Paths |
| |
| buildscript { |
| dependencies { |
| // findBugs needs a newer version of Guava in the buildscript. |
| // otherwise it throws an exception |
| classpath "com.google.guava:guava:28.2-jre" |
| } |
| } |
| |
| plugins { |
| id 'idea' |
| id 'java' |
| id 'java-test-fixtures' |
| id 'application' |
| id 'maven-publish' |
| |
| // since we're using a specific version here, we delay applying the plugin till the all projects |
| id "com.github.spotbugs" version "3.0.0" apply false |
| |
| // https://github.com/nebula-plugins/gradle-ospackage-plugin/wiki |
| id "nebula.ospackage" version "8.3.0" |
| id 'nebula.ospackage-application' version "8.3.0" |
| id 'com.google.cloud.tools.jib' version '2.2.0' |
| id 'org.asciidoctor.jvm.convert' version '3.1.0' |
| |
| // Release Audit Tool (RAT) plugin for checking project licenses |
| id("org.nosphere.apache.rat") version "0.8.0" |
| } |
| |
| println("Using DTest jar: ${dtestVersion}") |
| |
| def integrationMaxHeapSize = System.getenv("INTEGRATION_MAX_HEAP_SIZE") ?: "8g" |
| println("Using ${integrationMaxHeapSize} maxHeapSize") |
| |
| def integrationMaxParallelForks = (System.getenv("INTEGRATION_MAX_PARALLEL_FORKS") ?: "4") as int |
| println("Using ${integrationMaxParallelForks} maxParallelForks") |
| |
| // Force checkstyle, rat, and spotBugs to run before test tasks for faster feedback |
| def codeCheckTasks = task("codeCheckTasks") |
| |
| allprojects { |
| apply plugin: 'jacoco' |
| apply plugin: 'checkstyle' |
| apply plugin: "com.github.spotbugs" |
| |
| repositories { |
| mavenCentral() |
| |
| // for dtest jar |
| mavenLocal() |
| } |
| |
| checkstyle { |
| toolVersion '7.8.1' |
| configFile file("${project.rootDir}/checkstyle.xml") |
| } |
| spotbugs { |
| toolVersion = '4.2.3' |
| excludeFilter = file("${project.rootDir}/spotbugs-exclude.xml") |
| } |
| |
| tasks.withType(SpotBugsTask) { |
| reports.xml.enabled = false |
| reports.html.enabled = true |
| } |
| |
| codeCheckTasks.dependsOn(tasks.withType(Checkstyle)) |
| codeCheckTasks.dependsOn(tasks.withType(RatTask)) |
| codeCheckTasks.dependsOn(tasks.withType(SpotBugsTask)) |
| |
| tasks.withType(Test) { |
| shouldRunAfter(codeCheckTasks) |
| shouldRunAfter(tasks.withType(Checkstyle)) |
| shouldRunAfter(tasks.withType(RatTask)) |
| shouldRunAfter(tasks.withType(SpotBugsTask)) |
| } |
| |
| } |
| |
| group 'org.apache.cassandra' |
| version project.version |
| |
| sourceCompatibility = 1.8 |
| |
| // Take the application out once we're running via Cassandra |
| mainClassName = "org.apache.cassandra.sidecar.CassandraSidecarDaemon" |
| applicationName = 'cassandra-sidecar' |
| |
| // Config file location should be in file:/// format for local files, |
| def confFile = "file:" + File.separator + File.separator + "APP_HOME_TO_REPLACE/conf/sidecar.yaml" |
| |
| applicationDefaultJvmArgs = ["-Dsidecar.logdir=./logs", |
| "-Dsidecar.config=" + confFile, |
| "-Dlogback.configurationFile=./conf/logback.xml", |
| "-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory", |
| "-javaagent:APP_HOME_TO_REPLACE/agents/jolokia-jvm-1.6.0-agent.jar=port=7777,host=localhost"] |
| startScripts { |
| doLast { |
| unixScript.text = unixScript.text.replace("APP_HOME_TO_REPLACE", "\${APP_HOME}") |
| } |
| } |
| |
| run { |
| confFile = "file:" + File.separator + File.separator + "$projectDir/conf/sidecar.yaml" |
| println "Sidecar configuration file $confFile" |
| jvmArgs = ["-Dsidecar.logdir=./logs", |
| "-Dsidecar.config=" + confFile, |
| "-Dlogback.configurationFile=./conf/logback.xml", |
| "-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory", |
| "-javaagent:$projectDir/agents/jolokia-jvm-1.6.0-agent.jar=port=7777,host=localhost"] |
| } |
| |
| // add additional test source set |
| sourceSets { |
| integrationTest { |
| java { |
| compileClasspath += main.output + test.output |
| runtimeClasspath += main.output + test.output |
| srcDir file('src/test/integration') |
| } |
| } |
| |
| containerTest { |
| java { |
| compileClasspath += main.output + test.output |
| runtimeClasspath += main.output + test.output |
| srcDir file('src/test/containerTest') |
| } |
| } |
| } |
| |
| // and mark it as test root |
| idea { |
| module { |
| testSourceDirs += sourceSets.integrationTest.java.srcDirs |
| testSourceDirs += sourceSets.containerTest.java.srcDirs |
| } |
| } |
| |
| configurations { |
| jolokia |
| |
| integrationTestImplementation.extendsFrom testImplementation |
| containerTestImplementation.extendsFrom testImplementation |
| |
| runtime.exclude(group: "com.google.code.findbugs", module: "jsr305") |
| runtime.exclude(group: "org.codehaus.mojo", module: "animal-sniffer-annotations") |
| runtime.exclude(group: "com.google.guava", module: "listenablefuture") |
| runtime.exclude(group: "org.checkerframework", module: "checker-qual") |
| runtime.exclude(group: "com.google.errorprone", module: "error_prone_annotations") |
| runtime.exclude(group: 'com.github.jnr', module: 'jnr-ffi') |
| runtime.exclude(group: 'com.github.jnr', module: 'jnr-posix') |
| } |
| |
| dependencies { |
| compileOnly('org.jetbrains:annotations:23.0.0') |
| testCompileOnly('org.jetbrains:annotations:23.0.0') |
| integrationTestCompileOnly('org.jetbrains:annotations:23.0.0') |
| |
| implementation("io.vertx:vertx-web:${project.vertxVersion}") { |
| exclude group: 'junit', module: 'junit' |
| } |
| implementation("io.vertx:vertx-dropwizard-metrics:${project.vertxVersion}") |
| implementation("io.vertx:vertx-web-client:${project.vertxVersion}") |
| |
| implementation('com.datastax.cassandra:cassandra-driver-core:3.11.3') |
| implementation('com.google.inject:guice:4.2.2') |
| implementation("com.github.ben-manes.caffeine:caffeine:2.9.3") |
| |
| // Trying to be exactly compatible with Cassandra's deps |
| implementation("org.slf4j:slf4j-api:${project.slf4jVersion}") |
| implementation('ch.qos.logback:logback-core:1.2.3') |
| implementation('ch.qos.logback:logback-classic:1.2.3') |
| |
| |
| implementation(group: 'org.apache.commons', name: 'commons-lang3', version: '3.13.0') |
| implementation(group: 'commons-codec', name: 'commons-codec', version: "${project.commonsCodecVersion}") |
| |
| // Jackson for yaml-based configuration parsing |
| implementation(group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "${project.jacksonVersion}") |
| implementation(group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: "${project.jacksonVersion}") |
| |
| // aws sdk BOM + s3 |
| implementation platform(group: 'software.amazon.awssdk', name:'bom', version:"${project.aswSdkVersion}") |
| implementation('software.amazon.awssdk:s3') |
| implementation('software.amazon.awssdk:netty-nio-client') |
| |
| jolokia 'org.jolokia:jolokia-jvm:1.6.0:agent' |
| |
| testImplementation "org.junit.jupiter:junit-jupiter-api:${project.junitVersion}" |
| testImplementation "org.junit.jupiter:junit-jupiter-params:${project.junitVersion}" |
| testImplementation "org.assertj:assertj-core:3.24.2" |
| testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${project.junitVersion}" |
| |
| testImplementation('com.google.guava:guava-testlib:31.1-jre') { |
| exclude group: 'junit', module: 'junit' |
| } |
| |
| testImplementation('com.datastax.cassandra:cassandra-driver-core:3.9.0:tests') |
| testImplementation('org.mockito:mockito-core:4.10.0') |
| testImplementation('org.mockito:mockito-inline:4.10.0') |
| testImplementation("io.vertx:vertx-junit5:${project.vertxVersion}") |
| testImplementation(testFixtures(project(":client-common"))) |
| testImplementation(testFixtures(project(":server-common"))) |
| |
| implementation(project(":server-common")) |
| implementation(project(":adapters:base")) |
| implementation(project(":adapters:cassandra41")) |
| |
| testFixturesApi(testFixtures(project(":server-common"))) |
| testFixturesImplementation("io.vertx:vertx-junit5:${project.vertxVersion}") |
| testFixturesImplementation('com.google.inject:guice:4.2.2') |
| testFixturesImplementation('org.mockito:mockito-core:4.10.0') |
| testFixturesImplementation("org.junit.jupiter:junit-jupiter-api:${project.junitVersion}") |
| testFixturesImplementation("org.junit.jupiter:junit-jupiter-params:${project.junitVersion}") |
| testFixturesImplementation("org.assertj:assertj-core:3.24.2") |
| testFixturesImplementation("io.vertx:vertx-web:${project.vertxVersion}") { |
| exclude group: 'junit', module: 'junit' |
| } |
| integrationTestImplementation(group: 'org.apache.cassandra', name: "${dtestDependencyName}", version: "${dtestVersion}") |
| integrationTestImplementation(group: 'org.apache.cassandra', name: 'dtest-api', version: "${dtestApiVersion}") |
| integrationTestImplementation "org.junit.jupiter:junit-jupiter-api:${project.junitVersion}" |
| // Needed by the Cassandra dtest framework |
| integrationTestImplementation("org.junit.vintage:junit-vintage-engine:${junitVersion}") |
| // Needed for snapshot manifest validation |
| integrationTestImplementation(group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: "${project.jacksonVersion}") |
| |
| containerTestImplementation('com.adobe.testing:s3mock-testcontainers:2.17.0') // 3.x version do not support java 11 |
| } |
| |
| jar { |
| doFirst { |
| // Store current Cassandra Sidecar build version in an embedded resource file; |
| // the file is either created or overwritten, and ignored by Git source control |
| Files.createDirectories(Paths.get("$projectDir/server-common/src/main/resources")) |
| new File("$projectDir/server-common/src/main/resources/sidecar.version").text = version |
| } |
| } |
| |
| java { |
| withJavadocJar() |
| withSourcesJar() |
| } |
| |
| publishing { |
| publications { |
| maven(MavenPublication) { |
| from components.java |
| groupId project.group |
| artifactId "${archivesBaseName}" |
| version System.getenv("CODE_VERSION") ?: "${version}" |
| } |
| } |
| } |
| |
| task copyIdeaSettings(type: Copy) { |
| from "ide/idea" |
| into ".idea" |
| } |
| |
| tasks.named('idea').configure { |
| dependsOn copyIdeaSettings |
| } |
| |
| // Lets copy the distributions from build/install directory to /bin and /lib |
| // directories to be aligned with C* distribution format |
| task copyDist(type: Copy) { |
| from "$buildDir/install/$applicationName" |
| into "$projectDir" |
| } |
| |
| task copyJolokia(type: Copy) { |
| from configurations.jolokia |
| into "$projectDir/src/main/dist/agents" |
| } |
| |
| // Lets clean distribution directories along with default build directories. |
| clean.doLast { |
| ["agents", "bin", "conf", "lib"].each { |
| println "Deleting directory $projectDir/$it" |
| delete "$projectDir/$it" |
| } |
| println "Deleting generated docs $projectDir/src/main/resources/docs" |
| delete "$projectDir/src/main/resources/docs" |
| } |
| |
| test { |
| systemProperty "vertxweb.environment", "dev" |
| systemProperty "logback.configurationFile", "logback-sidecar.xml" |
| systemProperty "vertx.logger-delegate-factory-class-name", "io.vertx.core.logging.SLF4JLogDelegateFactory" |
| // ordinarily we don't need integration tests |
| // see the integrationTest task |
| useJUnitPlatform() |
| reports { |
| junitXml.enabled = true |
| def destDir = Paths.get(rootProject.rootDir.absolutePath, "build", "test-results", "test").toFile() |
| println("Destination directory for unit tests: ${destDir}") |
| junitXml.destination = destDir |
| html.enabled = true |
| } |
| testLogging { |
| events "passed", "skipped", "failed" |
| } |
| } |
| |
| def JDK11_OPTIONS = ['-Djdk.attach.allowAttachSelf=true', |
| '--add-exports', 'java.base/jdk.internal.misc=ALL-UNNAMED', |
| '--add-exports', 'java.base/jdk.internal.ref=ALL-UNNAMED', |
| '--add-exports', 'java.base/sun.nio.ch=ALL-UNNAMED', |
| '--add-exports', 'java.management.rmi/com.sun.jmx.remote.internal.rmi=ALL-UNNAMED', |
| '--add-exports', 'java.rmi/sun.rmi.registry=ALL-UNNAMED', |
| '--add-exports', 'java.rmi/sun.rmi.server=ALL-UNNAMED', |
| '--add-exports', 'java.sql/java.sql=ALL-UNNAMED', |
| '--add-opens', 'java.base/java.lang.module=ALL-UNNAMED', |
| '--add-opens', 'java.base/jdk.internal.loader=ALL-UNNAMED', |
| '--add-opens', 'java.base/jdk.internal.ref=ALL-UNNAMED', |
| '--add-opens', 'java.base/jdk.internal.reflect=ALL-UNNAMED', |
| '--add-opens', 'java.base/jdk.internal.math=ALL-UNNAMED', |
| '--add-opens', 'java.base/jdk.internal.module=ALL-UNNAMED', |
| '--add-opens', 'java.base/jdk.internal.util.jar=ALL-UNNAMED', |
| '--add-opens', 'jdk.management/com.sun.management.internal=ALL-UNNAMED'] |
| |
| def integrationTest = task("integrationTest") |
| |
| ['integrationTestLightWeight', 'integrationTestHeavyWeight'].each { name -> |
| tasks.register(name, Test) { |
| if (JavaVersion.current().isJava11Compatible()) { |
| jvmArgs(JDK11_OPTIONS) |
| println("JVM arguments for $project.name are $allJvmArgs") |
| } |
| // Disable direct memory allocator as it doesn't release properly |
| systemProperty "cassandra.netty_use_heap_allocator", "true" |
| systemProperty "vertxweb.environment", "dev" |
| // config logback for in-jvm clusters |
| systemProperty "logback.configurationFile", "src/test/resources/logback-in-jvm-dtest.xml" |
| // Because tests are forked, we need to explicitly pass the system property from the |
| // Gradle JVM down to the children |
| |
| def versionsToTest = System.getProperty("cassandra.sidecar.versions_to_test", null) |
| if (versionsToTest != "" && versionsToTest != null) { |
| systemProperty "cassandra.sidecar.versions_to_test", versionsToTest |
| } |
| useJUnitPlatform() { |
| if (name.contains("HeavyWeight")) |
| { |
| includeTags "heavy" |
| } |
| else |
| { |
| excludeTags "heavy" |
| } |
| } |
| |
| reports { |
| junitXml.enabled = true |
| def destDir = Paths.get(rootProject.rootDir.absolutePath, "build", "test-results", "integration").toFile() |
| println("Destination directory for integration tests: ${destDir}") |
| junitXml.destination = destDir |
| html.enabled = true |
| } |
| testLogging { |
| events "passed", "skipped", "failed" |
| } |
| testClassesDirs = sourceSets.integrationTest.output.classesDirs |
| classpath = sourceSets.integrationTest.runtimeClasspath |
| shouldRunAfter test |
| forkEvery = 1 // DTest framework tends to have issues without forkEvery test class |
| maxHeapSize = integrationMaxHeapSize |
| maxParallelForks = integrationMaxParallelForks |
| |
| afterTest { descriptor, result -> |
| def totalTime = (result.endTime - result.startTime) / 1000.0 |
| logger.lifecycle("--") |
| if (totalTime >= 60) { // log the tests that take 1 minute and more |
| logger.warn("$descriptor.displayName took $totalTime s") |
| } |
| else { |
| logger.info("$descriptor.displayName took $totalTime s") |
| } |
| } |
| } |
| } |
| |
| tasks.register("containerTest", Test) { |
| if (JavaVersion.current().isJava11Compatible()) { |
| jvmArgs(JDK11_OPTIONS) |
| println("JVM arguments for $project.name are $allJvmArgs") |
| } |
| |
| useJUnitPlatform() |
| reports { |
| junitXml.enabled = true |
| def destDir = Paths.get(rootProject.rootDir.absolutePath, "build", "test-results", "containerTest").toFile() |
| println("Destination directory for testcontainer tests: ${destDir}") |
| junitXml.destination = destDir |
| html.enabled = true |
| } |
| testLogging { |
| events "passed", "skipped", "failed" |
| } |
| testClassesDirs = sourceSets.containerTest.output.classesDirs |
| classpath = sourceSets.containerTest.runtimeClasspath |
| shouldRunAfter test |
| } |
| |
| // copy the user documentation to the final build |
| task copyDocs(type: Copy, dependsOn: ':docs:asciidoctor') { |
| from(tasks.getByPath(":docs:asciidoctor").outputs) { |
| include "**/*.html" |
| } |
| into "build/docs/" |
| exclude "tmp" |
| } |
| |
| /** |
| * General configuration for linux packages. |
| * Can be overridden in the buildRpm and buildDeb configuration |
| * We can put dependencies here, such as java, but unfortunately since java is distributed |
| * in an inconsistent manner depending on the version you want (8 vs 11) we can't include Java |
| * as a requirement without the install breaking if you want to use a different version |
| */ |
| ospackage { |
| packageName = "cassandra-sidecar" |
| version = project.version |
| // ospackage puts packages into /opt/[package] by default |
| // which is _technically_ the right spot for packages |
| link("/usr/local/bin/cassandra-sidecar", "/opt/cassandra-sidecar/bin/cassandra-sidecar") |
| license "Apache License 2.0" |
| description "Sidecar Management Tool for Apache Cassandra" |
| os = LINUX |
| user "root" |
| } |
| |
| buildRpm { |
| group = "build" |
| } |
| |
| buildDeb { |
| group = "build" |
| } |
| |
| applicationDistribution.from("LICENSE.txt") { |
| into "" |
| } |
| |
| tasks.register('buildIgnoreRatList', Exec) { |
| description 'Builds a list of ignored files for the rat task from the unversioned git files' |
| commandLine 'bash', '-c', "git clean --force -d --dry-run -x | cut -c 14-" |
| doFirst { |
| standardOutput new FileOutputStream("${buildDir}/.rat-excludes.txt") |
| } |
| // allows task to fail when git/cut commands are unavailable or fail |
| ignoreExitValue = true |
| } |
| |
| jacocoTestReport { |
| // include all jacoco execution data from different Test tasks, i.e. test, integration test, container test |
| executionData fileTree(project.buildDir).include("jacoco/*.exec") |
| } |
| |
| rat { |
| doFirst { |
| def excludeFilePath = Paths.get("${buildDir}/.rat-excludes.txt") |
| def excludeLines = Files.readAllLines(excludeFilePath) |
| excludeLines.each { line -> |
| if (line.endsWith("/")) { |
| excludes.add("**/" + line + "**") |
| } else { |
| excludes.add(line) |
| } |
| } |
| } |
| |
| // List of Gradle exclude directives, defaults to ['**/.gradle/**'] |
| excludes.add("**/build/**") |
| excludes.add("CHANGES.txt") |
| |
| // Documentation files |
| excludes.add("**/docs/src/**") |
| // gradle files |
| excludes.add("gradle/**") |
| excludes.add("gradlew") |
| excludes.add("gradlew.bat") |
| |
| // resource files for test |
| excludes.add("**/test**/resources/**") |
| |
| // XML, TXT and HTML reports directory, defaults to 'build/reports/rat' |
| reportDir.set(file("build/reports/rat")) |
| } |
| |
| compileIntegrationTestJava.onlyIf { "true" != System.getenv("skipIntegrationTest") } |
| checkstyleIntegrationTest.onlyIf { "true" != System.getenv("skipIntegrationTest") } |
| spotbugsIntegrationTest.onlyIf { "true" != System.getenv("skipIntegrationTest") } |
| compileContainerTestJava.onlyIf { "true" != System.getenv("skipContainerTest") } |
| checkstyleContainerTest.onlyIf { "true" != System.getenv("skipContainerTest") } |
| spotbugsContainerTest.onlyIf { "true" != System.getenv("skipContainerTest") } |
| |
| // copyDist gets called on every build |
| copyDist.dependsOn installDist, copyJolokia |
| integrationTest.dependsOn integrationTestLightWeight, integrationTestHeavyWeight |
| check.dependsOn codeCheckTasks, containerTest, integrationTest, jacocoTestReport |
| build.dependsOn copyDist, copyJolokia, copyDocs |
| run.dependsOn build |
| |
| tasks.named('rat').configure { |
| dependsOn(buildIgnoreRatList) |
| } |