diff --git a/.github/workflows/merge-build.yml b/.github/workflows/merge-build.yml
index 84168a5..7f869cf 100644
--- a/.github/workflows/merge-build.yml
+++ b/.github/workflows/merge-build.yml
@@ -25,7 +25,7 @@ jobs:
publish-snapshot:
name: publish to oss sonatype & push image
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-latest
permissions:
contents: read
@@ -42,12 +42,7 @@ jobs:
with:
distribution: 'temurin'
architecture: x64
- java-version: 11
-
- - name: Set up Maven
- uses: stCarolas/setup-maven@v4.5
- with:
- maven-version: 3.8.8
+ java-version: 17
- name: maven-settings-xml-action
uses: whelk-io/maven-settings-xml-action@v14
diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml
index bbc3277..317862b 100644
--- a/.github/workflows/pr-build.yml
+++ b/.github/workflows/pr-build.yml
@@ -24,7 +24,7 @@ on: [pull_request]
jobs:
build:
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
@@ -32,14 +32,9 @@ jobs:
- name: Set up JDK
uses: actions/setup-java@v2
with:
- java-version: '11'
+ java-version: '17'
distribution: 'adopt'
- - name: Set up Maven
- uses: stCarolas/setup-maven@v4.5
- with:
- maven-version: 3.8.8
-
- name: maven-settings-xml-action
uses: whelk-io/maven-settings-xml-action@v14
with:
diff --git a/README.md b/README.md
index 50c459c..3e31fe1 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ Users r/w the files via REST api. Multiple users can r/w same file without affec
The concurrent r/w is no surprise when you run a standalone service which only concerns one node. The most significant fact lies on the 'cluster' mode. You can deploy it on a Cloud platform, such as k8s or Openshift, and scale up to as many nodes as you want. The concurrent r/w promise still hold. On cluster mode, all nodes share the same persistent volume and connect to the same Cassandra as the backend DB.
## Prerequisite
-1. jdk11
+1. jdk17
2. mvn 3.6.2+
## Prerequisite for debugging in local
diff --git a/pom.xml b/pom.xml
index 87733e1..e32b0cf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,7 +44,6 @@
UTF-8
3.0
3.0.0
- 3.8
uber-jar
1.19.7
false
@@ -196,6 +195,11 @@
localstack
test
+
+ org.testcontainers
+ cassandra
+ test
+
@@ -254,7 +258,7 @@
- 11
+ 17
OpenJDK
@@ -279,34 +283,6 @@
-
- org.codehaus.mojo
- cassandra-maven-plugin
- ${cassandra-maven-plugin.version}
-
- true
- 9942
- true
-
- ${skipTests}
-
-
-
- net.java.dev.jna
- jna
- 5.8.0
-
-
-
-
- cassandra
-
- start
- stop
-
-
-
-
org.apache.maven.plugins
maven-release-plugin
diff --git a/src/main/image/Dockerfile.jvm b/src/main/image/Dockerfile.jvm
index 24ca0fd..ecf968e 100644
--- a/src/main/image/Dockerfile.jvm
+++ b/src/main/image/Dockerfile.jvm
@@ -23,7 +23,7 @@
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1
-ARG JAVA_PACKAGE=java-11-openjdk-headless
+ARG JAVA_PACKAGE=java-17-openjdk-headless
ARG RUN_JAVA_VERSION=1.3.8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
diff --git a/src/test/java/org/commonjava/service/storage/S3StorageIT.java b/src/test/java/org/commonjava/service/storage/S3StorageIT.java
index 127cb1d..a17cb49 100644
--- a/src/test/java/org/commonjava/service/storage/S3StorageIT.java
+++ b/src/test/java/org/commonjava/service/storage/S3StorageIT.java
@@ -18,6 +18,7 @@
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.inject.Inject;
+import org.commonjava.service.storage.util.CassandraTestResource;
import org.commonjava.service.storage.util.LocalStackTestResource;
import org.junit.jupiter.api.Test;
import software.amazon.awssdk.services.s3.S3Client;
@@ -32,6 +33,7 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
@QuarkusTest
+@QuarkusTestResource(CassandraTestResource.class)
@QuarkusTestResource(LocalStackTestResource.class)
public class S3StorageIT
extends StorageIT
diff --git a/src/test/java/org/commonjava/service/storage/StorageIT.java b/src/test/java/org/commonjava/service/storage/StorageIT.java
index 79b9ea5..e45bf58 100644
--- a/src/test/java/org/commonjava/service/storage/StorageIT.java
+++ b/src/test/java/org/commonjava/service/storage/StorageIT.java
@@ -15,8 +15,10 @@
*/
package org.commonjava.service.storage;
+import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.common.http.TestHTTPResource;
import org.apache.commons.io.IOUtils;
+import org.commonjava.service.storage.util.CassandraTestResource;
import org.commonjava.storage.pathmapped.core.PathMappedFileManager;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
@@ -27,6 +29,7 @@
import java.io.OutputStream;
import java.net.URL;
+@QuarkusTestResource(CassandraTestResource.class)
public abstract class StorageIT
{
protected final String PATH = "io/quarkus/quarkus-junit5/quarkus-junit5-1.12.0.Final.jar";
@@ -45,27 +48,18 @@ public abstract class StorageIT
public static void init() throws Exception
{
/*
- * The reason I dropped embedded cassandra:
- * Previously I use 'cassandra-unit' which is great because we can run the unit tests both
- * by mvn command and in IDEA. Unfortunately, after upgrading to Quarkus 3.x, there is a
- * dependence change, and it breaks the embedded cassandra.
+ * Now using testcontainers for Cassandra which supports Java 17.
+ * The CassandraTestResource starts/stops the container automatically.
+ * Tests can now be run both from mvn and directly in IDEA.
*
- * Because of that, I moved to cassandra-maven-plugin in pom.xml. It works well with Quarkus 3
- * to start/stop cassandra. But I have to move Junit tests to integration tests because
- * this plugin works for integration phase only. The test classes are refactored as '*IT.java'.
- * The downside is that we can not run the IT tests in IDEA by simply clicking the 'Run'.
- * We need to do from command line as 'mvn verify'. Or we run 'mvn cassandra:start' beforehand
- * then run IT tests in IDEA.
- *
- * ruhan Feb 9, 2024
+ * Updated for Java 17 migration, March 2026
*/
- //EmbeddedCassandraServerHelper.startEmbeddedCassandra();
}
@AfterAll
public static void stop() throws Exception
{
- //EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
+ // Cleanup handled by CassandraTestResource
}
@BeforeEach
diff --git a/src/test/java/org/commonjava/service/storage/util/CassandraTestResource.java b/src/test/java/org/commonjava/service/storage/util/CassandraTestResource.java
new file mode 100644
index 0000000..0653862
--- /dev/null
+++ b/src/test/java/org/commonjava/service/storage/util/CassandraTestResource.java
@@ -0,0 +1,74 @@
+/**
+ * Copyright (C) 2021 Red Hat, Inc. (https://github.com/Commonjava/service-parent)
+ *
+ * Licensed 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.
+ */
+package org.commonjava.service.storage.util;
+
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.Session;
+import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
+import org.testcontainers.containers.CassandraContainer;
+import org.testcontainers.utility.DockerImageName;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class CassandraTestResource implements QuarkusTestResourceLifecycleManager {
+
+ static DockerImageName dockerImageName = DockerImageName.parse("cassandra:3.11.10");
+ static CassandraContainer> cassandraContainer = new CassandraContainer<>(dockerImageName);
+
+ @Override
+ public Map start() {
+ cassandraContainer.start();
+
+ // Wait for Cassandra to be truly ready by attempting to connect
+ waitForCassandraToBeReady();
+
+ HashMap map = new HashMap<>();
+ map.put("cassandra.host", cassandraContainer.getHost());
+ map.put("cassandra.port", String.valueOf(cassandraContainer.getMappedPort(9042)));
+ map.put("cassandra.user", cassandraContainer.getUsername());
+ map.put("cassandra.pass", cassandraContainer.getPassword());
+ return map;
+ }
+
+ private void waitForCassandraToBeReady() {
+ int maxAttempts = 30;
+ for (int i = 0; i < maxAttempts; i++) {
+ try (Cluster cluster = cassandraContainer.getCluster();
+ Session session = cluster.connect()) {
+ // Successfully connected
+ return;
+ } catch (Exception e) {
+ if (i == maxAttempts - 1) {
+ throw new RuntimeException("Cassandra did not become ready in time", e);
+ }
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException("Interrupted while waiting for Cassandra", ie);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void stop() {
+ if (cassandraContainer != null) {
+ cassandraContainer.stop();
+ }
+ }
+}
diff --git a/src/test/resources/application.yaml b/src/test/resources/application.yaml
index b9141cc..3ebae89 100644
--- a/src/test/resources/application.yaml
+++ b/src/test/resources/application.yaml
@@ -32,11 +32,8 @@ quarkus:
swagger-ui:
always-include: true
+# Cassandra configuration is provided by CassandraTestResource at runtime
cassandra:
- host: localhost
- port: 9942
- user: cassandra
- pass: cassandra
keyspace: indystorage
storage:
diff --git a/toolchains.xml b/toolchains.xml
index 0314f4a..de1ef43 100644
--- a/toolchains.xml
+++ b/toolchains.xml
@@ -30,11 +30,11 @@
jdk
- 11
+ 17
OpenJDK
- /usr/lib/jvm/java-11-openjdk
+ /usr/lib/jvm/java-17-openjdk