diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandra.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandra.java
index a354c5e4642..287ea77e40e 100644
--- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandra.java
+++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandra.java
@@ -133,7 +133,7 @@ private static String buildSpecificImageDiscriminator() {
@SuppressWarnings("resource")
public DockerCassandra() {
- this("cassandra_3_11_10-" + buildSpecificImageDiscriminator(), AdditionalDockerFileStep.IDENTITY);
+ this("cassandra_3_11_15-" + buildSpecificImageDiscriminator(), AdditionalDockerFileStep.IDENTITY);
}
private DockerCassandra(String imageName, AdditionalDockerFileStep additionalSteps) {
@@ -168,7 +168,7 @@ public void close() {
new ImageFromDockerfile(imageName,doNotDeleteImageAfterUsage)
.withDockerfileFromBuilder(builder ->
additionalSteps.applyStep(builder
- .from("cassandra:3.11.10")
+ .from("cassandra:3.11.15")
.env("CASSANDRA_CONFIG", "/etc/cassandra")
.run("echo \"-Xms" + CASSANDRA_MEMORY + "M\" >> " + JVM_OPTIONS
+ "&& echo \"-Xmx" + CASSANDRA_MEMORY + "M\" >> " + JVM_OPTIONS
@@ -183,6 +183,7 @@ public void close() {
.build()))
.withTmpFs(ImmutableMap.of("/var/lib/cassandra", "rw,noexec,nosuid,size=200m"))
.withExposedPorts(CASSANDRA_PORT)
+ .withCreateContainerCmdModifier(createContainerCmd -> createContainerCmd.withName("james-cassandra-test-" + UUID.randomUUID()))
.withLogConsumer(DockerCassandra::displayDockerLog);
cassandraContainer
.waitingFor(new CassandraWaitStrategy(cassandraContainer));
diff --git a/backends-common/opensearch/src/test/resources/auth-es/NginxDockerfile b/backends-common/opensearch/src/test/resources/auth-es/NginxDockerfile
index 039b00c1bf7..f22aee94683 100644
--- a/backends-common/opensearch/src/test/resources/auth-es/NginxDockerfile
+++ b/backends-common/opensearch/src/test/resources/auth-es/NginxDockerfile
@@ -1,4 +1,4 @@
-FROM nginx:1.22
+FROM nginx:1.25
COPY conf/nginx-conf/ /etc/nginx/conf.d/
COPY conf/default.crt /etc/ssl/certs/default.crt
diff --git a/examples/custom-imap/docker-compose.yml b/examples/custom-imap/docker-compose.yml
index ac56ec29aa4..b8f1bb83862 100644
--- a/examples/custom-imap/docker-compose.yml
+++ b/examples/custom-imap/docker-compose.yml
@@ -6,9 +6,10 @@ services:
image: apache/james:memory-latest
container_name: james
hostname: james.local
+ command:
+ - --generate-keystore
volumes:
- - ./target/custom-imap-3.8.0-SNAPSHOT-jar-with-dependencies.jar:/root/extensions-jars/custom-imap-3.8.0-SNAPSHOT-jar-with-dependencies.jar
- - ./sample-configuration/keystore:/root/conf/keystore
+ - ./target/custom-imap-jar-with-dependencies.jar:/root/extensions-jars/custom-imap.jar
- ./sample-configuration/imapserver.xml:/root/conf/imapserver.xml
ports:
- "143:143"
diff --git a/examples/custom-imap/pom.xml b/examples/custom-imap/pom.xml
index c83831796ba..3ec23666885 100644
--- a/examples/custom-imap/pom.xml
+++ b/examples/custom-imap/pom.xml
@@ -97,6 +97,7 @@
jar-with-dependencies
+ custom-imap
diff --git a/examples/custom-imap/sample-configuration/keystore b/examples/custom-imap/sample-configuration/keystore
deleted file mode 100644
index 361cd01f43d..00000000000
Binary files a/examples/custom-imap/sample-configuration/keystore and /dev/null differ
diff --git a/examples/custom-james-assembly/pom.xml b/examples/custom-james-assembly/pom.xml
index d49138accb6..a56d151b80f 100644
--- a/examples/custom-james-assembly/pom.xml
+++ b/examples/custom-james-assembly/pom.xml
@@ -54,7 +54,7 @@
2.7.1
- eclipse-temurin:11-jre-focal
+ eclipse-temurin:11-jre-jammy
apache/james
diff --git a/examples/imap-autoconf/docker-compose.yml b/examples/imap-autoconf/docker-compose.yml
index 999529e8dcd..f8826e9644b 100644
--- a/examples/imap-autoconf/docker-compose.yml
+++ b/examples/imap-autoconf/docker-compose.yml
@@ -6,8 +6,8 @@ services:
image: apache/james:memory-latest
container_name: james
hostname: james.local
- volumes:
- - ./keystore:/root/conf/keystore
+ command:
+ - --generate-keystore
ports:
- "465:465"
- "993:993"
diff --git a/examples/imap-autoconf/keystore b/examples/imap-autoconf/keystore
deleted file mode 100644
index 361cd01f43d..00000000000
Binary files a/examples/imap-autoconf/keystore and /dev/null differ
diff --git a/examples/metrics-graphite/docker-compose.yml b/examples/metrics-graphite/docker-compose.yml
index fe8894bb2ce..218dcdd57fe 100644
--- a/examples/metrics-graphite/docker-compose.yml
+++ b/examples/metrics-graphite/docker-compose.yml
@@ -8,9 +8,10 @@ services:
image: apache/james:memory-latest
container_name: james
hostname: james.local
+ command:
+ - --generate-keystore
volumes:
- - ./james/keystore:/root/conf/keystore
- - ./target/metrics-graphite-3.8.0-SNAPSHOT-jar-with-dependencies.jar:/root/extensions-jars/metrics-graphite-3.8.0-SNAPSHOT-jar-with-dependencies.jar
+ - ./target/metrics-graphite-jar-with-dependencies.jar:/root/extensions-jars/metrics-graphite.jar
- ./james/extensions.properties:/root/conf/extensions.properties
graphite:
diff --git a/examples/metrics-graphite/james/keystore b/examples/metrics-graphite/james/keystore
deleted file mode 100644
index 361cd01f43d..00000000000
Binary files a/examples/metrics-graphite/james/keystore and /dev/null differ
diff --git a/examples/metrics-graphite/pom.xml b/examples/metrics-graphite/pom.xml
index d2f80a6e055..cf791cc03e3 100644
--- a/examples/metrics-graphite/pom.xml
+++ b/examples/metrics-graphite/pom.xml
@@ -75,6 +75,7 @@
jar-with-dependencies
+ metrics-graphite
diff --git a/examples/proxy-smtp/docker-compose.yml b/examples/proxy-smtp/docker-compose.yml
index c175a5c7f9e..cf7545e772f 100644
--- a/examples/proxy-smtp/docker-compose.yml
+++ b/examples/proxy-smtp/docker-compose.yml
@@ -6,7 +6,7 @@ services:
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
ports:
- - 25:25
+ - "25:25"
- 143:143
- 993:993
- 465:465
@@ -17,10 +17,11 @@ services:
image: apache/james:memory-latest
container_name: james
hostname: james.local
+ command:
+ - --generate-keystore
volumes:
- ./smtpserver.xml:/root/conf/smtpserver.xml:ro
- ./imapserver.xml:/root/conf/imapserver.xml:ro
- - ./keystore:/root/conf/keystore
helo:
image: alpine:latest
diff --git a/examples/proxy-smtp/keystore b/examples/proxy-smtp/keystore
deleted file mode 100644
index 361cd01f43d..00000000000
Binary files a/examples/proxy-smtp/keystore and /dev/null differ
diff --git a/server/apps/cassandra-app/README.adoc b/server/apps/cassandra-app/README.adoc
index e5af4814e20..27c75b62481 100644
--- a/server/apps/cassandra-app/README.adoc
+++ b/server/apps/cassandra-app/README.adoc
@@ -21,12 +21,12 @@ Firstly, create your own user network on Docker for the James environment:
Third party compulsory dependencies:
- * Cassandra 3.11.10
+ * Cassandra 3.11.15
* OpenSearch 2.1.0
[source]
----
-$ docker run -d --network james -p 9042:9042 --name=cassandra cassandra:3.11.10
+$ docker run -d --network james -p 9042:9042 --name=cassandra cassandra:3.11.15
$ docker run -d --network james -p 9200:9200 --name=opensearch --env 'discovery.type=single-node' opensearchproject/opensearch:2.1.0
----
diff --git a/server/apps/cassandra-app/docker-compose.yml b/server/apps/cassandra-app/docker-compose.yml
index a2627519a08..0210548d258 100644
--- a/server/apps/cassandra-app/docker-compose.yml
+++ b/server/apps/cassandra-app/docker-compose.yml
@@ -4,12 +4,19 @@ services:
james:
depends_on:
- - opensearch
- - cassandra
- - tika
+ cassandra:
+ condition: service_healthy
+ opensearch:
+ condition: service_started
+ tika:
+ condition: service_started
image: apache/james:cassandra-latest
container_name: james
hostname: james.local
+ networks:
+ - james
+ volumes:
+ - ${KEYSTORE_PATH}:/root/conf/keystore
ports:
- "80:80"
- "25:25"
@@ -21,6 +28,10 @@ services:
- "8000:8000"
opensearch:
+ networks:
+ james:
+ aliases:
+ - elasticsearch
image: opensearchproject/opensearch:2.1.0
environment:
- discovery.type=single-node
@@ -28,10 +39,21 @@ services:
- DISABLE_SECURITY_PLUGIN=true
cassandra:
- image: cassandra:3.11.10
+ image: cassandra:3.11.15
ports:
- "9042:9042"
+ healthcheck:
+ test: [ "CMD-SHELL", "[ $$(nodetool statusgossip) = running ]" ]
+ interval: 3s
+ timeout: 20s
+ retries: 5
+ networks:
+ - james
tika:
- image: apache/tika:1.28.2
+ image: apache/tika:2.8.0.0
+ networks:
+ - james
+networks:
+ james:
diff --git a/server/apps/cassandra-app/pom.xml b/server/apps/cassandra-app/pom.xml
index 8411d0356ef..46ec761c37a 100644
--- a/server/apps/cassandra-app/pom.xml
+++ b/server/apps/cassandra-app/pom.xml
@@ -335,7 +335,7 @@
jib-maven-plugin
- eclipse-temurin:11-jre-focal
+ eclipse-temurin:11-jre-jammy
apache/james
diff --git a/server/apps/distributed-app/README.adoc b/server/apps/distributed-app/README.adoc
index 72e9edb77d9..89738e8f8b0 100644
--- a/server/apps/distributed-app/README.adoc
+++ b/server/apps/distributed-app/README.adoc
@@ -10,17 +10,17 @@ Firstly, create your own user network on Docker for the James environment:
Third party compulsory dependencies:
- * Cassandra 3.11.10
+ * Cassandra 3.11.15
* OpenSearch 2.1.0
* RabbitMQ-Management 3.8.18
* Zenko Cloudserver or AWS S3
[source]
----
-$ docker run -d --network james -p 9042:9042 --name=cassandra cassandra:3.11.10
+$ docker run -d --network james -p 9042:9042 --name=cassandra cassandra:3.11.15
$ docker run -d --network james -p 9200:9200 --name=opensearch --env 'discovery.type=single-node' opensearchproject/opensearch:2.1.0
-$ docker run -d --network james -p 5672:5672 -p 15672:15672 --name=rabbitmq rabbitmq:3.9.18-management
-$ docker run -d --network james --env 'REMOTE_MANAGEMENT_DISABLE=1' --env 'SCALITY_ACCESS_KEY_ID=accessKey1' --env 'SCALITY_SECRET_ACCESS_KEY=secretKey1' --name=s3 zenko/cloudserver:8.2.6
+$ docker run -d --network james -p 5672:5672 -p 15672:15672 --name=rabbitmq rabbitmq:3.12.1-management
+$ docker run -d --network james --env 'REMOTE_MANAGEMENT_DISABLE=1' --env 'SCALITY_ACCESS_KEY_ID=accessKey1' --env 'SCALITY_SECRET_ACCESS_KEY=secretKey1' --name=s3 registry.scality.com/cloudserver/cloudserver:8.7.25
----
== Running
diff --git a/server/apps/distributed-app/docker-compose.yml b/server/apps/distributed-app/docker-compose.yml
index 70b70ec1f05..40ce9fc5d71 100644
--- a/server/apps/distributed-app/docker-compose.yml
+++ b/server/apps/distributed-app/docker-compose.yml
@@ -4,14 +4,23 @@ services:
james:
depends_on:
- - opensearch
- - cassandra
- - tika
- - rabbitmq
- - s3
+ cassandra:
+ condition: service_healthy
+ opensearch:
+ condition: service_started
+ tika:
+ condition: service_started
+ rabbitmq:
+ condition: service_started
+ s3:
+ condition: service_started
image: apache/james:distributed-latest
container_name: james
hostname: james.local
+ command:
+ - --generate-keystore
+ networks:
+ - james
ports:
- "80:80"
- "25:25"
@@ -28,23 +37,38 @@ services:
- discovery.type=single-node
- DISABLE_INSTALL_DEMO_CONFIG=true
- DISABLE_SECURITY_PLUGIN=true
+ networks:
+ james:
+ aliases:
+ - elasticsearch
cassandra:
image: cassandra:3.11.10
ports:
- "9042:9042"
+ healthcheck:
+ test: [ "CMD-SHELL", "[ $$(nodetool statusgossip) = running ]" ]
+ interval: 3s
+ timeout: 20s
+ retries: 5
+ networks:
+ - james
tika:
- image: apache/tika:1.28.2
+ image: apache/tika:2.8.0.0
+ networks:
+ - james
rabbitmq:
- image: rabbitmq:3.9.18-management
+ image: rabbitmq:3.12.1-management
ports:
- "5672:5672"
- "15672:15672"
+ networks:
+ - james
s3:
- image: zenko/cloudserver:8.2.6
+ image: registry.scality.com/cloudserver/cloudserver:8.7.25
container_name: s3.docker.test
environment:
- SCALITY_ACCESS_KEY_ID=accessKey1
@@ -52,4 +76,8 @@ services:
- S3BACKEND=mem
- LOG_LEVEL=trace
- REMOTE_MANAGEMENT_DISABLE=1
+ networks:
+ - james
+networks:
+ james:
\ No newline at end of file
diff --git a/server/apps/distributed-app/docs/modules/ROOT/pages/operate/logging.adoc b/server/apps/distributed-app/docs/modules/ROOT/pages/operate/logging.adoc
index 87f645cf4a4..b7ef18c07ee 100644
--- a/server/apps/distributed-app/docs/modules/ROOT/pages/operate/logging.adoc
+++ b/server/apps/distributed-app/docs/modules/ROOT/pages/operate/logging.adoc
@@ -200,18 +200,18 @@ services:
- discovery.type=single-node
cassandra:
- image: cassandra:3.11.10
+ image: cassandra:3.11.15
ports:
- "9042:9042"
rabbitmq:
- image: rabbitmq:3.9.18-management
+ image: rabbitmq:3.12.1-management
ports:
- "5672:5672"
- "15672:15672"
s3:
- image: zenko/cloudserver:8.2.6
+ image: registry.scality.com/cloudserver/cloudserver:8.7.25
container_name: s3.docker.test
environment:
- SCALITY_ACCESS_KEY_ID=accessKey1
diff --git a/server/apps/distributed-app/docs/modules/ROOT/pages/run/run-docker.adoc b/server/apps/distributed-app/docs/modules/ROOT/pages/run/run-docker.adoc
index b3a97f44e58..d90a10943ba 100644
--- a/server/apps/distributed-app/docs/modules/ROOT/pages/run/run-docker.adoc
+++ b/server/apps/distributed-app/docs/modules/ROOT/pages/run/run-docker.adoc
@@ -53,15 +53,15 @@ Firstly, create your own user network on Docker for the James environment:
You need a running *cassandra* in docker which connects to *james* network. To achieve this run:
- $ docker run -d --network james --name=cassandra cassandra:3.11.10
+ $ docker run -d --network james --name=cassandra cassandra:3.11.15
You need a running *rabbitmq* in docker which connects to *james* network. To achieve this run:
- $ docker run -d --network james --name=rabbitmq rabbitmq:3.9.18-management
+ $ docker run -d --network james --name=rabbitmq rabbitmq:3.12.1-management
You need a running *Zenko Cloudserver* objectstorage in docker which connects to *james* network. To achieve this run:
- $ docker run -d --network james --env 'REMOTE_MANAGEMENT_DISABLE=1' --env 'SCALITY_ACCESS_KEY_ID=accessKey1' --env 'SCALITY_SECRET_ACCESS_KEY=secretKey1' --name=s3 zenko/cloudserver:8.2.6
+ $ docker run -d --network james --env 'REMOTE_MANAGEMENT_DISABLE=1' --env 'SCALITY_ACCESS_KEY_ID=accessKey1' --env 'SCALITY_SECRET_ACCESS_KEY=secretKey1' --name=s3 registry.scality.com/cloudserver/cloudserver:8.7.25
You need a running *OpenSearch* in docker which connects to *james* network. To achieve this run:
@@ -69,7 +69,7 @@ $ docker run -d --network james -p 9200:9200 --name=opensearch --env 'discovery.
If you want to use all the JMAP search capabilities, you may also need to start Tika container which connects to *james* network:
- $ docker run -d --network james --name=tika apache/tika:1.28.2
+ $ docker run -d --network james --name=tika apache/tika:2.8.0.0
You can find more explanation on the need of Tika in this xref:configure/tika.adoc[page].
@@ -122,7 +122,7 @@ You can handle attachment text extraction before indexing in OpenSearch. This ma
Run tika connect to *james* network:
- $ docker run -d --network james --name tika apache/tika:1.28.2
+ $ docker run -d --network james --name tika apache/tika:2.8.0.0
Run James:
diff --git a/server/apps/distributed-app/docs/modules/ROOT/pages/run/run-java.adoc b/server/apps/distributed-app/docs/modules/ROOT/pages/run/run-java.adoc
index 052537523d1..6e736667e54 100644
--- a/server/apps/distributed-app/docs/modules/ROOT/pages/run/run-java.adoc
+++ b/server/apps/distributed-app/docs/modules/ROOT/pages/run/run-java.adoc
@@ -7,7 +7,7 @@
* Java 11 SDK
* Docker ∕ OpenSearch 2.1.0, RabbitMQ Management 3.8.18, S3 compatible
-ObjectStorage and Cassandra 3.11.10
+ObjectStorage and Cassandra 3.11.15
* Maven 3
=== Building the artifacts
@@ -29,7 +29,7 @@ mvn clean install
=== Requirements
-* Cassandra 3.11.10
+* Cassandra 3.11.15
* OpenSearch 2.1.0
* RabbitMQ-Management 3.8.17
* Swift ObjectStorage 2.15.1 or Zenko Cloudserver or AWS S3
@@ -50,10 +50,10 @@ running. You can either install the servers or launch them via docker:
[source,bash]
----
-$ docker run -d -p 9042:9042 --name=cassandra cassandra:3.11.10
+$ docker run -d -p 9042:9042 --name=cassandra cassandra:3.11.15
$ docker run -d --network james -p 9200:9200 --name=opensearch --env 'discovery.type=single-node' opensearchproject/opensearch:2.1.0
-$ docker run -d -p 5672:5672 -p 15672:15672 --name=rabbitmq rabbitmq:3.9.18-management
-$ docker run -d --env 'REMOTE_MANAGEMENT_DISABLE=1' --env 'SCALITY_ACCESS_KEY_ID=accessKey1' --env 'SCALITY_SECRET_ACCESS_KEY=secretKey1' --name=s3 zenko/cloudserver:8.2.6
+$ docker run -d -p 5672:5672 -p 15672:15672 --name=rabbitmq rabbitmq:3.12.1-management
+$ docker run -d --env 'REMOTE_MANAGEMENT_DISABLE=1' --env 'SCALITY_ACCESS_KEY_ID=accessKey1' --env 'SCALITY_SECRET_ACCESS_KEY=secretKey1' --name=s3 registry.scality.com/cloudserver/cloudserver:8.7.25
----
Once everything is set up, you just have to run the jar with:
diff --git a/server/apps/distributed-app/pom.xml b/server/apps/distributed-app/pom.xml
index a240fd51539..e4813deb636 100644
--- a/server/apps/distributed-app/pom.xml
+++ b/server/apps/distributed-app/pom.xml
@@ -379,7 +379,7 @@
jib-maven-plugin
- eclipse-temurin:11-jre-focal
+ eclipse-temurin:11-jre-jammy
apache/james
diff --git a/server/apps/distributed-pop3-app/README.adoc b/server/apps/distributed-pop3-app/README.adoc
index add1c010d18..7b5032bfaa6 100644
--- a/server/apps/distributed-pop3-app/README.adoc
+++ b/server/apps/distributed-pop3-app/README.adoc
@@ -13,15 +13,15 @@ Firstly, create your own user network on Docker for the James environment:
Third party compulsory dependencies:
- * Cassandra 3.11.10
+ * Cassandra 3.11.15
* RabbitMQ-Management 3.8.18
* Zenko Cloudserver or AWS S3
[source]
----
-$ docker run -d --network james -p 9042:9042 --name=cassandra cassandra:3.11.10
-$ docker run -d --network james -p 5672:5672 -p 15672:15672 --name=rabbitmq rabbitmq:3.9.18-management
-$ docker run -d --network james --env 'REMOTE_MANAGEMENT_DISABLE=1' --env 'SCALITY_ACCESS_KEY_ID=accessKey1' --env 'SCALITY_SECRET_ACCESS_KEY=secretKey1' --name=s3 zenko/cloudserver:8.2.6
+$ docker run -d --network james -p 9042:9042 --name=cassandra cassandra:3.11.15
+$ docker run -d --network james -p 5672:5672 -p 15672:15672 --name=rabbitmq rabbitmq:3.12.1-management
+$ docker run -d --network james --env 'REMOTE_MANAGEMENT_DISABLE=1' --env 'SCALITY_ACCESS_KEY_ID=accessKey1' --env 'SCALITY_SECRET_ACCESS_KEY=secretKey1' --name=s3 registry.scality.com/cloudserver/cloudserver:8.7.25
----
== Docker distribution
diff --git a/server/apps/distributed-pop3-app/docker-compose.yml b/server/apps/distributed-pop3-app/docker-compose.yml
index 36e9621b2e9..c08d9417713 100644
--- a/server/apps/distributed-pop3-app/docker-compose.yml
+++ b/server/apps/distributed-pop3-app/docker-compose.yml
@@ -4,11 +4,16 @@ services:
james:
depends_on:
- - opensearch
- - cassandra
- - tika
- - rabbitmq
- - s3
+ cassandra:
+ condition: service_healthy
+ opensearch:
+ condition: service_started
+ tika:
+ condition: service_started
+ rabbitmq:
+ condition: service_started
+ s3:
+ condition: service_started
image: apache/james:distributed-pop3-latest
container_name: james
hostname: james.local
@@ -21,6 +26,10 @@ services:
- "587:587"
- "993:993"
- "8000:8000"
+ command:
+ - --generate-keystore
+ networks:
+ - james
opensearch:
image: opensearchproject/opensearch:2.1.0
@@ -28,23 +37,38 @@ services:
- discovery.type=single-node
- DISABLE_INSTALL_DEMO_CONFIG=true
- DISABLE_SECURITY_PLUGIN=true
+ networks:
+ james:
+ aliases:
+ - elasticsearch
cassandra:
- image: cassandra:3.11.10
+ image: cassandra:3.11.15
ports:
- "9042:9042"
+ healthcheck:
+ test: [ "CMD-SHELL", "[ $$(nodetool statusgossip) = running ]" ]
+ interval: 3s
+ timeout: 20s
+ retries: 5
+ networks:
+ - james
tika:
- image: apache/tika:1.28.2
+ image: apache/tika:2.8.0.0
+ networks:
+ - james
rabbitmq:
- image: rabbitmq:3.9.18-management
+ image: rabbitmq:3.12.1-management
ports:
- "5672:5672"
- "15672:15672"
+ networks:
+ - james
s3:
- image: zenko/cloudserver:8.2.6
+ image: registry.scality.com/cloudserver/cloudserver:8.7.25
container_name: s3.docker.test
environment:
- SCALITY_ACCESS_KEY_ID=accessKey1
@@ -52,3 +76,8 @@ services:
- S3BACKEND=mem
- LOG_LEVEL=trace
- REMOTE_MANAGEMENT_DISABLE=1
+ networks:
+ - james
+
+networks:
+ james:
\ No newline at end of file
diff --git a/server/apps/distributed-pop3-app/pom.xml b/server/apps/distributed-pop3-app/pom.xml
index ccb294767af..eeaf913122b 100644
--- a/server/apps/distributed-pop3-app/pom.xml
+++ b/server/apps/distributed-pop3-app/pom.xml
@@ -387,7 +387,7 @@
jib-maven-plugin
- eclipse-temurin:11-jre-focal
+ eclipse-temurin:11-jre-jammy
apache/james
diff --git a/server/apps/distributed-pop3-app/sample-configuration/opensearch.properties b/server/apps/distributed-pop3-app/sample-configuration/opensearch.properties
new file mode 100644
index 00000000000..87011f9f5ce
--- /dev/null
+++ b/server/apps/distributed-pop3-app/sample-configuration/opensearch.properties
@@ -0,0 +1,96 @@
+# 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.
+
+# This template file can be used as example for James Server configuration
+# DO NOT USE IT AS SUCH AND ADAPT IT TO YOUR NEEDS
+
+# Configuration file for OpenSearch
+# Read https://james.apache.org/server/config-opensearch.html for further details
+
+opensearch.masterHost=opensearch
+opensearch.port=9200
+
+# Optional. Only http or https are accepted, default is http
+# opensearch.hostScheme=http
+
+# Optional, default is `default`
+# Choosing the SSL check strategy when using https scheme
+# default: Use the default SSL TrustStore of the system.
+# ignore: Ignore SSL Validation check (not recommended).
+# override: Override the SSL Context to use a custom TrustStore containing ES server's certificate.
+# opensearch.hostScheme.https.sslValidationStrategy=default
+
+# Optional. Required when using 'https' scheme and 'override' sslValidationStrategy
+# Configure OpenSearch rest client to use this trustStore file to recognize nginx's ssl certificate.
+# You need to specify both trustStorePath and trustStorePassword
+# opensearch.hostScheme.https.trustStorePath=/file/to/trust/keystore.jks
+
+# Optional. Required when using 'https' scheme and 'override' sslValidationStrategy
+# Configure OpenSearch rest client to use this trustStore file with the specified password.
+# You need to specify both trustStorePath and trustStorePassword
+# opensearch.hostScheme.https.trustStorePassword=myJKSPassword
+
+# Optional. default is `default`
+# Configure OpenSearch rest client to use host name verifier during SSL handshake
+# default: using the default hostname verifier provided by apache http client.
+# accept_any_hostname: accept any host (not recommended).
+# opensearch.hostScheme.https.hostNameVerifier=default
+
+# Optional.
+# Basic auth username to access opensearch.
+# Ignore opensearch.user and opensearch.password to not be using authentication (default behaviour).
+# Otherwise, you need to specify both properties.
+# opensearch.user=elasticsearch
+
+# Optional.
+# Basic auth password to access opensearch.
+# Ignore opensearch.user and opensearch.password to not be using authentication (default behaviour).
+# Otherwise, you need to specify both properties.
+# opensearch.password=secret
+
+# You can alternatively provide a list of hosts following this format :
+# opensearch.hosts=host1:9200,host2:9200
+# opensearch.clusterName=cluster
+
+opensearch.nb.shards=5
+opensearch.nb.replica=1
+opensearch.index.waitForActiveShards=1
+opensearch.retryConnection.maxRetries=7
+opensearch.retryConnection.minDelay=3000
+# Index or not attachments (default value: true)
+opensearch.indexAttachments=true
+
+# Search overrides allow resolution of predefined search queries against alternative sources of data
+# and allow bypassing opensearch. This is useful to handle most resynchronisation queries that
+# are simple enough to be resolved against Cassandra.
+#
+# Possible values are:
+# - `org.apache.james.mailbox.cassandra.search.AllSearchOverride` Some IMAP clients uses SEARCH ALL to fully list messages in
+# a mailbox and detect deletions. This is typically done by clients not supporting QRESYNC and from an IMAP perspective
+# is considered an optimisation as less data is transmitted compared to a FETCH command. Resolving such requests against
+# Cassandra is enabled by this search override and likely desirable.
+# - `org.apache.james.mailbox.cassandra.search.UidSearchOverride`. Same as above but restricted by ranges.
+# - `org.apache.james.mailbox.cassandra.search.DeletedSearchOverride`. Find deleted messages by looking up in the relevant Cassandra
+# table.
+# - `org.apache.james.mailbox.cassandra.search.DeletedWithRangeSearchOverride`. Same as above but limited by ranges.
+# - `org.apache.james.mailbox.cassandra.search.NotDeletedWithRangeSearchOverride`. List non deleted messages in a given range.
+# Lists all messages and filters out deleted message thus this is based on the following heuristic: most messages are not marked as deleted.
+# - `org.apache.james.mailbox.cassandra.search.UnseenSearchOverride`. List unseen messages in the corresponding cassandra projection.
+#
+# Please note that custom overrides can be defined here.
+#
+# opensearch.search.overrides=org.apache.james.mailbox.cassandra.search.AllSearchOverride,org.apache.james.mailbox.cassandra.search.DeletedSearchOverride, org.apache.james.mailbox.cassandra.search.DeletedWithRangeSearchOverride,org.apache.james.mailbox.cassandra.search.NotDeletedWithRangeSearchOverride,org.apache.james.mailbox.cassandra.search.UidSearchOverride,org.apache.james.mailbox.cassandra.search.UnseenSearchOverride
diff --git a/server/apps/jpa-app/pom.xml b/server/apps/jpa-app/pom.xml
index d45acccc491..81366e717af 100644
--- a/server/apps/jpa-app/pom.xml
+++ b/server/apps/jpa-app/pom.xml
@@ -268,7 +268,7 @@
jib-maven-plugin
- eclipse-temurin:11-jre-focal
+ eclipse-temurin:11-jre-jammy
apache/james
diff --git a/server/apps/jpa-smtp-app/pom.xml b/server/apps/jpa-smtp-app/pom.xml
index 7e395b905fc..ee5e5361e8a 100644
--- a/server/apps/jpa-smtp-app/pom.xml
+++ b/server/apps/jpa-smtp-app/pom.xml
@@ -252,7 +252,7 @@
jib-maven-plugin
- eclipse-temurin:11-jre-focal
+ eclipse-temurin:11-jre-jammy
apache/james
diff --git a/server/apps/memory-app/pom.xml b/server/apps/memory-app/pom.xml
index dfa543bc4d1..1a0e896325e 100644
--- a/server/apps/memory-app/pom.xml
+++ b/server/apps/memory-app/pom.xml
@@ -267,7 +267,7 @@
jib-maven-plugin
- eclipse-temurin:11-jre-focal
+ eclipse-temurin:11-jre-jammy
apache/james
diff --git a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/DockerAwsS3Container.java b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/DockerAwsS3Container.java
index d47469054cf..2359d6220a5 100644
--- a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/DockerAwsS3Container.java
+++ b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/DockerAwsS3Container.java
@@ -20,6 +20,7 @@
package org.apache.james.blob.objectstorage.aws;
import java.net.URI;
+import java.util.UUID;
import org.apache.james.util.Host;
import org.testcontainers.containers.GenericContainer;
@@ -27,8 +28,7 @@
public class DockerAwsS3Container {
-
- private static final String AWS_S3_DOCKER_IMAGE = "zenko/cloudserver:8.2.6";
+ private static final String AWS_S3_DOCKER_IMAGE = "registry.scality.com/cloudserver/cloudserver:8.7.25";
private static final int AWS_S3_PORT = 8000;
private static final int ONE_TIME = 1;
@@ -40,14 +40,14 @@ public class DockerAwsS3Container {
private DockerAwsS3 dockerAwsS3;
public DockerAwsS3Container() {
- this.awsS3Container = new GenericContainer<>(AWS_S3_DOCKER_IMAGE);
- this.awsS3Container
+ this.awsS3Container = new GenericContainer<>(AWS_S3_DOCKER_IMAGE)
.withExposedPorts(AWS_S3_PORT)
.withEnv("S3BACKEND", "mem")
.withEnv("SCALITY_ACCESS_KEY_ID", ACCESS_KEY_ID)
.withEnv("SCALITY_SECRET_ACCESS_KEY", SECRET_ACCESS_KEY)
.withEnv("LOG_LEVEL", "trace")
.withEnv("REMOTE_MANAGEMENT_DISABLE", "1")
+ .withCreateContainerCmdModifier(createContainerCmd -> createContainerCmd.withName("james-s3-test-" + UUID.randomUUID()))
.waitingFor(Wait.forLogMessage(".*\"message\":\"server started\".*\\n", ONE_TIME));
}
@@ -81,7 +81,7 @@ public Host getHost() {
}
public String getIp() {
- return awsS3Container.getContainerIpAddress();
+ return awsS3Container.getHost();
}
public int getPort() {
diff --git a/server/mailet/mock-smtp-server/pom.xml b/server/mailet/mock-smtp-server/pom.xml
index d868aff45b0..03a2afe1ebf 100644
--- a/server/mailet/mock-smtp-server/pom.xml
+++ b/server/mailet/mock-smtp-server/pom.xml
@@ -124,7 +124,7 @@
2.7.0
- eclipse-temurin:11-jre-focal
+ eclipse-temurin:11-jre-jammy
linagora/mock-smtp-server
diff --git a/server/mailet/rate-limiter-redis/docker-compose.yml b/server/mailet/rate-limiter-redis/docker-compose.yml
index 757396f6a8e..ce98bee9600 100644
--- a/server/mailet/rate-limiter-redis/docker-compose.yml
+++ b/server/mailet/rate-limiter-redis/docker-compose.yml
@@ -3,16 +3,20 @@ version: '3'
services:
redis:
- image: redis:6.2.6
-
+ image: redis:7.0.12
+ command:
+ - "--loglevel"
+ - "debug"
james:
image: apache/james:memory-latest
depends_on:
- redis
container_name: james
hostname: james.local
+ command:
+ - --generate-keystore
volumes:
- - $PWD/target/james-server-rate-limiter-redis-3.8.0-SNAPSHOT-jar-with-dependencies.jar:/root/extensions-jars/james-server-rate-limiter-redis.jar
+ - $PWD/target/james-server-rate-limiter-redis-jar-with-dependencies.jar:/root/extensions-jars/james-server-rate-limiter-redis.jar
- $PWD/extensions.properties:/root/conf/extensions.properties
- $PWD/redis.properties:/root/conf/redis.properties
- $PWD/mailetcontainer.xml:/root/conf/mailetcontainer.xml
diff --git a/server/mailet/rate-limiter-redis/pom.xml b/server/mailet/rate-limiter-redis/pom.xml
index fee59985e50..6782b7022bc 100644
--- a/server/mailet/rate-limiter-redis/pom.xml
+++ b/server/mailet/rate-limiter-redis/pom.xml
@@ -145,13 +145,14 @@
jar-with-dependencies
+ james-server-rate-limiter-redis
single
- compile
+ package
diff --git a/server/mailet/rate-limiter-redis/src/test/java/org/apache/james/rate/limiter/DockerRedis.java b/server/mailet/rate-limiter-redis/src/test/java/org/apache/james/rate/limiter/DockerRedis.java
index 805d4dfa30d..1dc0ceb9323 100644
--- a/server/mailet/rate-limiter-redis/src/test/java/org/apache/james/rate/limiter/DockerRedis.java
+++ b/server/mailet/rate-limiter-redis/src/test/java/org/apache/james/rate/limiter/DockerRedis.java
@@ -20,50 +20,51 @@
package org.apache.james.rate.limiter;
import java.net.URI;
-import java.net.URISyntaxException;
+import java.time.Duration;
+import java.util.UUID;
import org.apache.http.client.utils.URIBuilder;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.Network;
+import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.utility.DockerImageName;
+import com.github.fge.lambdas.Throwing;
+
import io.lettuce.core.RedisClient;
import io.lettuce.core.api.sync.RedisCommands;
public class DockerRedis {
- private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("redis");
- private static final String DEFAULT_TAG = "6.2.6";
+ private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("redis").withTag("7.0.12");
private static final int DEFAULT_PORT = 6379;
private final GenericContainer> container;
public DockerRedis() {
- this.container = new GenericContainer<>(DEFAULT_IMAGE_NAME.withTag(DEFAULT_TAG))
- .withExposedPorts(DEFAULT_PORT);
+ this.container = getContainer();
}
public DockerRedis(Network network) {
- this.container = new GenericContainer<>(DEFAULT_IMAGE_NAME.withTag(DEFAULT_TAG))
- .withExposedPorts(DEFAULT_PORT)
- .withNetwork(network)
- .withCreateContainerCmdModifier(createContainerCmd -> createContainerCmd.withName("james-redis-test"))
- .withNetworkAliases("redis");
+ this.container = getContainer()
+ .withNetwork(network);
}
- public Integer getPort() {
- return container.getMappedPort(DEFAULT_PORT);
+ private GenericContainer> getContainer() {
+ return new GenericContainer<>(DEFAULT_IMAGE_NAME)
+ .withExposedPorts(DEFAULT_PORT)
+ .withCreateContainerCmdModifier(createContainerCmd -> createContainerCmd.withName("james-redis-test-" + UUID.randomUUID()))
+ .withCommand("--loglevel", "debug")
+ .withNetworkAliases("redis")
+ .waitingFor(Wait.forLogMessage(".*Ready to accept connections.*", 1)
+ .withStartupTimeout(Duration.ofMinutes(2)));
}
public URI redisURI() {
- try {
- return new URIBuilder()
- .setScheme("redis")
- .setHost(container.getHost())
- .setPort(getPort())
- .build();
- } catch (URISyntaxException e) {
- throw new RuntimeException("Error when build redis uri. ", e);
- }
+ return Throwing.supplier(() -> new URIBuilder()
+ .setScheme("redis")
+ .setHost(container.getHost())
+ .setPort(container.getMappedPort(DEFAULT_PORT))
+ .build()).get();
}
public void start() {
diff --git a/server/mailet/rate-limiter/docker-compose.yml b/server/mailet/rate-limiter/docker-compose.yml
index 63ddeb72fee..a9b158d2b07 100644
--- a/server/mailet/rate-limiter/docker-compose.yml
+++ b/server/mailet/rate-limiter/docker-compose.yml
@@ -6,7 +6,9 @@ services:
image: apache/james:memory-latest
container_name: james
hostname: james.local
+ command:
+ - --generate-keystore
volumes:
- - $PWD/target/james-server-rate-limiter-3.8.0-SNAPSHOT-jar-with-dependencies.jar:/root/extensions-jars/james-server-rate-limiter.jar
+ - $PWD/target/james-server-rate-limiter-jar-with-dependencies.jar:/root/extensions-jars/james-server-rate-limiter.jar
- $PWD/extensions.properties:/root/conf/extensions.properties
- $PWD/mailetcontainer.xml:/root/conf/mailetcontainer.xml
diff --git a/server/mailet/rate-limiter/mailetcontainer.xml b/server/mailet/rate-limiter/mailetcontainer.xml
index 10aa8e3bca8..5a19d2642d0 100644
--- a/server/mailet/rate-limiter/mailetcontainer.xml
+++ b/server/mailet/rate-limiter/mailetcontainer.xml
@@ -121,7 +121,7 @@
200M
tooMuchMails
-
+
myPrefix
1h
1h
diff --git a/server/mailet/rate-limiter/pom.xml b/server/mailet/rate-limiter/pom.xml
index 69cfc7d4681..6273a88bdaf 100644
--- a/server/mailet/rate-limiter/pom.xml
+++ b/server/mailet/rate-limiter/pom.xml
@@ -114,13 +114,14 @@
jar-with-dependencies
+ james-server-rate-limiter
single
- compile
+ package
diff --git a/server/mailet/rate-limiter/src/test/scala/org/apache/james/transport/mailets/PerRecipientRateLimitTest.scala b/server/mailet/rate-limiter/src/test/scala/org/apache/james/transport/mailets/PerRecipientRateLimitTest.scala
index 7eb00ff45a2..7de761d5266 100644
--- a/server/mailet/rate-limiter/src/test/scala/org/apache/james/transport/mailets/PerRecipientRateLimitTest.scala
+++ b/server/mailet/rate-limiter/src/test/scala/org/apache/james/transport/mailets/PerRecipientRateLimitTest.scala
@@ -42,7 +42,7 @@ class PerRecipientRateLimitTest {
@Test
def rateLimitingShouldBeAppliedPerRecipient(): Unit = {
val mailet: PerRecipientRateLimit = testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("duration", "20s")
.setProperty("precision", "1s")
.setProperty("count", "1")
@@ -74,7 +74,7 @@ class PerRecipientRateLimitTest {
@Test
def rateLimitingShouldNotBeAppliedWhenDoNotHaveRecipient() : Unit = {
val mailet: PerRecipientRateLimit = testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("duration", "20s")
.setProperty("precision", "1s")
.setProperty("count", "1")
@@ -93,7 +93,7 @@ class PerRecipientRateLimitTest {
@Test
def rateLimitingShouldFlowToTheIntendedProcessor() : Unit = {
val mailet: PerRecipientRateLimit = testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("duration", "20s")
.setProperty("precision", "1s")
.setProperty("count", "1")
@@ -126,7 +126,7 @@ class PerRecipientRateLimitTest {
@Test
def rateLimitingShouldNOTBeAppliedPerSender() : Unit = {
val mailet: PerRecipientRateLimit = testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("duration", "20s")
.setProperty("precision", "1s")
.setProperty("count", "1")
@@ -159,7 +159,7 @@ class PerRecipientRateLimitTest {
@Test
def shouldRateLimitSizeOfEmails(): Unit = {
val mailet: PerRecipientRateLimit = testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("duration", "20s")
.setProperty("precision", "1s")
.setProperty("size", "100K")
@@ -206,7 +206,7 @@ class PerRecipientRateLimitTest {
val mailetContext = Mockito.spy(FakeMailContext.defaultContext)
val mailet: PerRecipientRateLimit = testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("duration", "20s")
.setProperty("precision", "1s")
.setProperty("count", "1")
@@ -258,7 +258,7 @@ class PerRecipientRateLimitTest {
@Test
def shouldRateLimitedWhenAllRecipientsExceeded(): Unit = {
val mailet: PerRecipientRateLimit = testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("duration", "20s")
.setProperty("precision", "1s")
.setProperty("count", "1")
@@ -292,7 +292,7 @@ class PerRecipientRateLimitTest {
@Test
def mailetShouldSupportBothCountAndSize(): Unit = {
val mailet: PerRecipientRateLimit = testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("duration", "20s")
.setProperty("precision", "1s")
.setProperty("count", "2")
@@ -354,7 +354,7 @@ class PerRecipientRateLimitTest {
@Test
def shouldFailWhenNoDuration(): Unit = {
assertThatThrownBy(() => testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.build()))
.isInstanceOf(classOf[IllegalArgumentException])
}
@@ -362,7 +362,7 @@ class PerRecipientRateLimitTest {
@Test
def shouldFailWhenEmptyDuration(): Unit = {
assertThatThrownBy(() => testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("duration", "")
.build()))
.isInstanceOf(classOf[IllegalArgumentException])
@@ -371,7 +371,7 @@ class PerRecipientRateLimitTest {
@Test
def shouldFailWhenBadDuration(): Unit = {
assertThatThrownBy(() => testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("duration", "bad")
.build()))
.isInstanceOf(classOf[IllegalArgumentException])
@@ -380,7 +380,7 @@ class PerRecipientRateLimitTest {
@Test
def shouldFailWhenNegativeDuration(): Unit = {
assertThatThrownBy(() => testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("duration", "-3s")
.build()))
.isInstanceOf(classOf[IllegalArgumentException])
@@ -389,7 +389,7 @@ class PerRecipientRateLimitTest {
@Test
def shouldFailWhenZeroDuration(): Unit = {
assertThatThrownBy(() => testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("count", "1")
.setProperty("duration", "0s")
.build()))
@@ -399,7 +399,7 @@ class PerRecipientRateLimitTest {
@Test
def shouldFailWhenTooSmallDuration(): Unit = {
assertThatThrownBy(() => testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("count", "1")
.setProperty("duration", "10ms")
.build()))
@@ -410,7 +410,7 @@ class PerRecipientRateLimitTest {
def durationWithNoUnitShouldDefaultToSeconds(): Unit = {
assertThat(
testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("duration", "10")
.build()).parseDuration().getSeconds)
.isEqualTo(10L)
@@ -420,7 +420,7 @@ class PerRecipientRateLimitTest {
def durationShouldSupportUnits(): Unit = {
assertThat(
testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("duration", "1h")
.build()).parseDuration().getSeconds)
.isEqualTo(3600L)
@@ -429,7 +429,7 @@ class PerRecipientRateLimitTest {
@Test
def shouldFailWithEmptyCount(): Unit = {
assertThatThrownBy(() => testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("count", "")
.setProperty("duration", "10s")
.build()).parseDuration().getSeconds)
@@ -439,7 +439,7 @@ class PerRecipientRateLimitTest {
@Test
def shouldFailWithZeroCount(): Unit = {
assertThatThrownBy(() => testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("count", "0")
.setProperty("duration", "10s")
.build()).parseDuration().getSeconds)
@@ -449,7 +449,7 @@ class PerRecipientRateLimitTest {
@Test
def shouldFailWithNegativeCount(): Unit = {
assertThatThrownBy(() => testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("count", "-1")
.setProperty("duration", "10s")
.build()).parseDuration().getSeconds)
@@ -459,7 +459,7 @@ class PerRecipientRateLimitTest {
@Test
def shouldFailWithBadCount(): Unit = {
assertThatThrownBy(() => testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("count", "bad")
.setProperty("duration", "10s")
.build()).parseDuration().getSeconds)
@@ -469,7 +469,7 @@ class PerRecipientRateLimitTest {
@Test
def shouldFailWithEmptySize(): Unit = {
assertThatThrownBy(() => testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("size", "")
.setProperty("duration", "10s")
.build()).parseDuration().getSeconds)
@@ -479,7 +479,7 @@ class PerRecipientRateLimitTest {
@Test
def shouldFailWithZeroSize(): Unit = {
assertThatThrownBy(() => testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("size", "0")
.setProperty("duration", "10s")
.build()).parseDuration().getSeconds)
@@ -489,7 +489,7 @@ class PerRecipientRateLimitTest {
@Test
def shouldFailWithNegativeSize(): Unit = {
assertThatThrownBy(() => testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("size", "-1000")
.setProperty("duration", "10s")
.build()).parseDuration().getSeconds)
@@ -499,7 +499,7 @@ class PerRecipientRateLimitTest {
@Test
def shouldFailWithBadSize(): Unit = {
assertThatThrownBy(() => testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("size", "bad")
.setProperty("duration", "10s")
.build()).parseDuration().getSeconds)
@@ -509,7 +509,7 @@ class PerRecipientRateLimitTest {
@Test
def sizeShouldSupportUnits(): Unit = {
assertThatCode(() => testee(FakeMailetConfig.builder()
- .mailetName("PerRecipientRateLimitMailet")
+ .mailetName("PerRecipientRateLimit")
.setProperty("size", "1k")
.setProperty("duration", "10s")
.build()).parseDuration().getSeconds)
diff --git a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/ContainerTest.java b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/ContainerTest.java
index e24e77831d9..4225e87a1ad 100644
--- a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/ContainerTest.java
+++ b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/ContainerTest.java
@@ -36,7 +36,7 @@
public class ContainerTest {
@Rule
- public DockerContainer container = DockerContainer.fromName("nginx:1.22")
+ public DockerContainer container = DockerContainer.fromName("nginx:1.25")
.withAffinityToContainer()
.withExposedPorts(80)
.waitingFor(new HttpWaitStrategy()
diff --git a/server/testing/src/main/java/org/apache/james/util/docker/Images.java b/server/testing/src/main/java/org/apache/james/util/docker/Images.java
index fd55e976462..a14371968fe 100644
--- a/server/testing/src/main/java/org/apache/james/util/docker/Images.java
+++ b/server/testing/src/main/java/org/apache/james/util/docker/Images.java
@@ -21,12 +21,12 @@
public interface Images {
String FAKE_SMTP = "weave/rest-smtp-sink:latest";
- String RABBITMQ = "rabbitmq:3.9.18-management";
+ String RABBITMQ = "rabbitmq:3.12.1-management";
String ELASTICSEARCH_2 = "elasticsearch:2.4.6";
String ELASTICSEARCH_6 = "docker.elastic.co/elasticsearch/elasticsearch:6.3.2";
String ELASTICSEARCH_7 = "docker.elastic.co/elasticsearch/elasticsearch:7.10.2";
String OPENSEARCH = "opensearchproject/opensearch:2.4.0";
- String TIKA = "apache/tika:1.28.2";
+ String TIKA = "apache/tika:2.8.0.0";
String MOCK_SMTP_SERVER = "linagora/mock-smtp-server:0.6";
String OPEN_LDAP = "osixia/openldap:1.5.0";
}
diff --git a/src/site/markdown/server/install/guice-cassandra-rabbitmq-s3.md b/src/site/markdown/server/install/guice-cassandra-rabbitmq-s3.md
index fc16946843c..7aee72c793e 100644
--- a/src/site/markdown/server/install/guice-cassandra-rabbitmq-s3.md
+++ b/src/site/markdown/server/install/guice-cassandra-rabbitmq-s3.md
@@ -5,7 +5,7 @@
### Requirements
- Java 11 SDK
- - Docker ∕ OpenSearch 2.1.0, RabbitMQ Management 3.8.18, compatible S3 ObjectStorage and Cassandra 3.11.10
+ - Docker ∕ OpenSearch 2.1.0, RabbitMQ Management 3.8.18, compatible S3 ObjectStorage and Cassandra 3.11.15
- Maven 3
### Building the artifacts
@@ -25,7 +25,7 @@ mvn clean install
### Requirements
- * Cassandra 3.11.10
+ * Cassandra 3.11.15
* OpenSearch 2.1.0
* RabbitMQ-Management 3.8.18
* Zenko Cloudserver or AWS S3 compatible API
@@ -47,10 +47,10 @@ $ keytool -genkey -alias james -keyalg RSA -keystore conf/keystore
You need to have a Cassandra, OpenSearch, S3 and RabbitMQ instance running. You can either install the servers or launch them via docker:
```bash
-$ docker run -d -p 9042:9042 --name=cassandra cassandra:3.11.10
+$ docker run -d -p 9042:9042 --name=cassandra cassandra:3.11.15
$ docker run -d --network james -p 9200:9200 --name=opensearch --env 'discovery.type=single-node' opensearchproject/opensearch:2.1.0
-$ docker run -d -p 5672:5672 -p 15672:15672 --name=rabbitmq rabbitmq:3.9.18-management
-$ docker run -d --env 'REMOTE_MANAGEMENT_DISABLE=1' --env 'SCALITY_ACCESS_KEY_ID=accessKey1' --env 'SCALITY_SECRET_ACCESS_KEY=secretKey1' --name=s3 zenko/cloudserver:8.2.6
+$ docker run -d -p 5672:5672 -p 15672:15672 --name=rabbitmq rabbitmq:3.12.1-management
+$ docker run -d --env 'REMOTE_MANAGEMENT_DISABLE=1' --env 'SCALITY_ACCESS_KEY_ID=accessKey1' --env 'SCALITY_SECRET_ACCESS_KEY=secretKey1' --name=s3 registry.scality.com/cloudserver/cloudserver:8.7.25
```
Once everything is set up, you just have to run the jar with:
diff --git a/src/site/markdown/server/install/guice-cassandra.md b/src/site/markdown/server/install/guice-cassandra.md
index 370da400808..9259cfd806d 100644
--- a/src/site/markdown/server/install/guice-cassandra.md
+++ b/src/site/markdown/server/install/guice-cassandra.md
@@ -5,7 +5,7 @@
### Requirements
- Java 11 SDK
- - Docker ∕ OpenSearch 2.1.0 and Cassandra 3.11.10
+ - Docker ∕ OpenSearch 2.1.0 and Cassandra 3.11.15
- Maven 3
*WARNING*: JAMES-3591 Cassandra is not made to store large binary content, its use will be suboptimal compared to
@@ -28,7 +28,7 @@ mvn clean install
### Requirements
- * Cassandra 3.11.10
+ * Cassandra 3.11.15
* OpenSearch 2.1.0
### James Launch
@@ -48,7 +48,7 @@ $ keytool -genkey -alias james -keyalg RSA -keystore conf/keystore
You need to have a Cassandra and an OpenSearch instance running. You can either install the servers or launch them via docker:
```bash
-$ docker run -d -p 9042:9042 --name=cassandra cassandra:3.11.10
+$ docker run -d -p 9042:9042 --name=cassandra cassandra:3.11.15
$ docker run -d --network james -p 9200:9200 --name=opensearch --env 'discovery.type=single-node' opensearchproject/opensearch:2.1.0
```
diff --git a/src/site/xdoc/server/quick-start-cassandra.xml b/src/site/xdoc/server/quick-start-cassandra.xml
index 0c71406c219..9b750de1108 100644
--- a/src/site/xdoc/server/quick-start-cassandra.xml
+++ b/src/site/xdoc/server/quick-start-cassandra.xml
@@ -64,7 +64,7 @@ Step 3: Deploy
3.1. Deploy Cassandra (optional)
You may skip this part if you already have a running Cassandra on your network.
-$ docker run --detach=true --name=cassandra cassandra:3.11.10
+$ docker run --detach=true --name=cassandra cassandra:3.11.15
3.2. Deploy OpenSearch (optional)
You may skip this part if you already have a running OpenSearch on your network.
diff --git a/third-party/clamav/docker-compose.yml b/third-party/clamav/docker-compose.yml
index e04e5aba556..c70f15c0039 100644
--- a/third-party/clamav/docker-compose.yml
+++ b/third-party/clamav/docker-compose.yml
@@ -4,18 +4,25 @@ services:
james:
depends_on:
- - opensearch
- - cassandra
- - tika
- - rabbitmq
- - s3
- - clamav
+ cassandra:
+ condition: service_healthy
+ opensearch:
+ condition: service_started
+ tika:
+ condition: service_started
+ rabbitmq:
+ condition: service_started
+ s3:
+ condition: service_started
+ clamav:
+ condition: service_started
image: apache/james:distributed-latest
container_name: james
hostname: james.local
+ command:
+ - --generate-keystore
volumes:
- - $PWD/target/apache-james-clamav-3.8.0-SNAPSHOT-jar-with-dependencies.jar:/root/extensions-jars/james-server-clamav.jar
- - $PWD/sample-configuration/keystore:/root/conf/keystore
+ - $PWD/target/apache-james-clamav-jar-with-dependencies.jar:/root/extensions-jars/james-server-clamav.jar
- $PWD/sample-configuration/mailetcontainer.xml:/root/conf/mailetcontainer.xml
ports:
- "80:80"
@@ -26,28 +33,47 @@ services:
- "587:587"
- "993:993"
- "8000:8000"
+ networks:
+ - james
opensearch:
image: opensearchproject/opensearch:2.1.0
environment:
- discovery.type=single-node
+ - DISABLE_INSTALL_DEMO_CONFIG=true
+ - DISABLE_SECURITY_PLUGIN=true
+ networks:
+ james:
+ aliases:
+ - elasticsearch
cassandra:
- image: cassandra:3.11.10
+ image: cassandra:3.11.15
ports:
- "9042:9042"
+ healthcheck:
+ test: [ "CMD-SHELL", "[ $$(nodetool statusgossip) = running ]" ]
+ interval: 3s
+ timeout: 20s
+ retries: 5
+ networks:
+ - james
tika:
- image: apache/tika:1.26
+ image: apache/tika:2.8.0.0
+ networks:
+ - james
rabbitmq:
- image: rabbitmq:3.8.18-management
+ image: rabbitmq:3.12.1-management
ports:
- "5672:5672"
- "15672:15672"
+ networks:
+ - james
s3:
- image: zenko/cloudserver:8.2.6
+ image: registry.scality.com/cloudserver/cloudserver:8.7.25
container_name: s3.docker.test
environment:
- SCALITY_ACCESS_KEY_ID=accessKey1
@@ -55,6 +81,13 @@ services:
- S3BACKEND=mem
- LOG_LEVEL=trace
- REMOTE_MANAGEMENT_DISABLE=1
+ networks:
+ - james
clamav:
- image: clamav/clamav:0.105
+ image: clamav/clamav:1.1
+ networks:
+ - james
+
+networks:
+ james:
\ No newline at end of file
diff --git a/third-party/clamav/pom.xml b/third-party/clamav/pom.xml
index 9ba8047f1ef..4e726e19e3a 100644
--- a/third-party/clamav/pom.xml
+++ b/third-party/clamav/pom.xml
@@ -70,13 +70,14 @@
jar-with-dependencies
+ apache-james-clamav
single
- compile
+ package
diff --git a/third-party/clamav/sample-configuration/mailetcontainer.xml b/third-party/clamav/sample-configuration/mailetcontainer.xml
index 976a3d900ef..ad69dbd7bd6 100644
--- a/third-party/clamav/sample-configuration/mailetcontainer.xml
+++ b/third-party/clamav/sample-configuration/mailetcontainer.xml
@@ -31,7 +31,7 @@
20
- memory://var/mail/error/
+ cassandra://var/mail/error/
@@ -51,7 +51,7 @@
ignore
- memory://var/mail/error/
+ cassandra://var/mail/error/
propagate
@@ -129,7 +129,7 @@
none
- memory://var/mail/address-error/
+ cassandra://var/mail/address-error/
@@ -141,7 +141,7 @@
none
- memory://var/mail/relay-denied/
+ cassandra://var/mail/relay-denied/
Warning: You are sending an e-mail to a remote server. You must be authenticated to perform such an operation
@@ -157,7 +157,7 @@
- memory://var/mail/rrt-error/
+ cassandra://var/mail/rrt-error/
true
diff --git a/third-party/clamav/src/test/java/org/apache/james/clamav/DockerClamAV.java b/third-party/clamav/src/test/java/org/apache/james/clamav/DockerClamAV.java
index c66d2783880..6fec1c9191e 100644
--- a/third-party/clamav/src/test/java/org/apache/james/clamav/DockerClamAV.java
+++ b/third-party/clamav/src/test/java/org/apache/james/clamav/DockerClamAV.java
@@ -20,24 +20,25 @@
package org.apache.james.clamav;
import java.time.Duration;
+import java.util.UUID;
import org.testcontainers.containers.GenericContainer;
-import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
+import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.utility.DockerImageName;
public class DockerClamAV {
- private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("clamav/clamav");
- private static final String DEFAULT_TAG = "0.105";
+ private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("clamav/clamav").withTag("1.1");
private static final int DEFAULT_PORT = 3310;
private final GenericContainer> container;
public DockerClamAV() {
- this.container = new GenericContainer<>(DEFAULT_IMAGE_NAME.withTag(DEFAULT_TAG))
+ this.container = new GenericContainer<>(DEFAULT_IMAGE_NAME)
.withExposedPorts(DEFAULT_PORT)
.withEnv("CLAMAV_NO_FRESHCLAMD", "true")
.withEnv("CLAMAV_NO_MILTERD", "true")
- .waitingFor(new LogMessageWaitStrategy().withRegEx(".*clamd started.*\\n").withTimes(1)
+ .withCreateContainerCmdModifier(createContainerCmd -> createContainerCmd.withName("james-clamav-test-" + UUID.randomUUID()))
+ .waitingFor(Wait.forHealthcheck()
.withStartupTimeout(Duration.ofMinutes(5)));
}
diff --git a/third-party/elasticsearch/conf/keystore b/third-party/elasticsearch/conf/keystore
deleted file mode 100644
index 361cd01f43d..00000000000
Binary files a/third-party/elasticsearch/conf/keystore and /dev/null differ
diff --git a/third-party/elasticsearch/docker-compose.yml b/third-party/elasticsearch/docker-compose.yml
index de788681b62..2fe73817e5d 100644
--- a/third-party/elasticsearch/docker-compose.yml
+++ b/third-party/elasticsearch/docker-compose.yml
@@ -8,9 +8,10 @@ services:
image: apache/james:memory-latest
container_name: james
hostname: james.local
+ command:
+ - --generate-keystore
volumes:
- - ./conf/keystore:/root/conf/keystore
- - ./target/apache-james-elasticsearch-3.8.0-SNAPSHOT-jar-with-dependencies.jar:/root/extensions-jars/apache-james-elasticsearch-3.8.0-SNAPSHOT-jar-with-dependencies.jar
+ - ./target/apache-james-elasticsearch-jar-with-dependencies.jar:/root/extensions-jars/apache-james-elasticsearch.jar
- ./conf/extensions.properties:/root/conf/extensions.properties
- ./conf/elasticsearch.properties:/root/conf/elasticsearch.properties
diff --git a/third-party/elasticsearch/pom.xml b/third-party/elasticsearch/pom.xml
index 8d80e8b979a..15830efcc91 100644
--- a/third-party/elasticsearch/pom.xml
+++ b/third-party/elasticsearch/pom.xml
@@ -130,6 +130,7 @@
jar-with-dependencies
+ apache-james-elasticsearch
diff --git a/third-party/rspamd/docker-compose-distributed.yml b/third-party/rspamd/docker-compose-distributed.yml
index 7bfe971c5d4..5bf833be81f 100644
--- a/third-party/rspamd/docker-compose-distributed.yml
+++ b/third-party/rspamd/docker-compose-distributed.yml
@@ -4,18 +4,25 @@ services:
james:
depends_on:
- - elasticsearch
- - cassandra
- - tika
- - rabbitmq
- - s3
- - rspamd
+ cassandra:
+ condition: service_healthy
+ opensearch:
+ condition: service_started
+ tika:
+ condition: service_started
+ rabbitmq:
+ condition: service_started
+ s3:
+ condition: service_started
+ rspamd:
+ condition: service_healthy
image: apache/james:distributed-latest
container_name: james
hostname: james.local
+ command:
+ - --generate-keystore
volumes:
- - $PWD/target/apache-james-rspamd-3.8.0-SNAPSHOT-jar-with-dependencies.jar:/root/extensions-jars/james-server-rspamd.jar
- - $PWD/sample-configuration/keystore:/root/conf/keystore
+ - $PWD/target/apache-james-rspamd-jar-with-dependencies.jar:/root/extensions-jars/james-server-rspamd.jar
- $PWD/sample-configuration/extensions.properties:/root/conf/extensions.properties
- $PWD/sample-configuration/mailetcontainer_distributed.xml:/root/conf/mailetcontainer.xml
- $PWD/sample-configuration/listeners.xml:/root/conf/listeners.xml
@@ -31,28 +38,47 @@ services:
- "587:587"
- "993:993"
- "8000:8000"
+ networks:
+ - james
opensearch:
image: opensearchproject/opensearch:2.1.0
environment:
- discovery.type=single-node
+ - DISABLE_INSTALL_DEMO_CONFIG=true
+ - DISABLE_SECURITY_PLUGIN=true
+ networks:
+ james:
+ aliases:
+ - elasticsearch
cassandra:
- image: cassandra:3.11.10
+ image: cassandra:3.11.15
ports:
- "9042:9042"
+ healthcheck:
+ test: [ "CMD-SHELL", "[ $$(nodetool statusgossip) = running ]" ]
+ interval: 3s
+ timeout: 20s
+ retries: 5
+ networks:
+ - james
tika:
- image: apache/tika:1.26
+ image: apache/tika:2.8.0.0
+ networks:
+ - james
rabbitmq:
- image: rabbitmq:3.8.18-management
+ image: rabbitmq:3.12.1-management
ports:
- "5672:5672"
- "15672:15672"
+ networks:
+ - james
s3:
- image: zenko/cloudserver:8.2.6
+ image: registry.scality.com/cloudserver/cloudserver:8.7.25
container_name: s3.docker.test
environment:
- SCALITY_ACCESS_KEY_ID=accessKey1
@@ -60,19 +86,27 @@ services:
- S3BACKEND=mem
- LOG_LEVEL=trace
- REMOTE_MANAGEMENT_DISABLE=1
+ networks:
+ - james
redis:
- image: redis:6.2.6
+ image: redis:7.0.12
+ networks:
+ - james
clamav:
- image: clamav/clamav:0.105
+ image: clamav/clamav:1.1
+ networks:
+ - james
rspamd:
depends_on:
- - redis
- - clamav
+ clamav:
+ condition: service_healthy
+ redis:
+ condition: service_started
container_name: rspamd
- image: a16bitsysop/rspamd:3.3-r0-alpine3.16.2-r0
+ image: a16bitsysop/rspamd:3.5-r7-alpine3.18.2-r0
environment:
- REDIS=redis
- CLAMAV=clamav
@@ -81,4 +115,9 @@ services:
- $PWD/sample-configuration/antivirus.conf:/etc/rspamd/override.d/antivirus.conf
- $PWD/sample-configuration/statistic.conf:/etc/rspamd/statistic.conf
ports:
- - 11334:11334
\ No newline at end of file
+ - 11334:11334
+ networks:
+ - james
+
+networks:
+ james:
\ No newline at end of file
diff --git a/third-party/rspamd/docker-compose.yml b/third-party/rspamd/docker-compose.yml
index 6efd11a8ba0..3e7a9d514fc 100644
--- a/third-party/rspamd/docker-compose.yml
+++ b/third-party/rspamd/docker-compose.yml
@@ -4,13 +4,15 @@ services:
james:
depends_on:
- - rspamd
+ rspamd:
+ condition: service_healthy
image: apache/james:memory-latest
container_name: james
hostname: james.local
+ command:
+ - --generate-keystore
volumes:
- - $PWD/target/apache-james-rspamd-3.8.0-SNAPSHOT-jar-with-dependencies.jar:/root/extensions-jars/james-server-rspamd.jar
- - $PWD/sample-configuration/keystore:/root/conf/keystore
+ - $PWD/target/apache-james-rspamd-jar-with-dependencies.jar:/root/extensions-jars/james-server-rspamd.jar
- $PWD/sample-configuration/extensions.properties:/root/conf/extensions.properties
- $PWD/sample-configuration/mailetcontainer_memory.xml:/root/conf/mailetcontainer.xml
- $PWD/sample-configuration/listeners.xml:/root/conf/listeners.xml
@@ -28,17 +30,22 @@ services:
- "8000:8000"
redis:
- image: redis:6.2.6
+ image: redis:7.0.12
+ command:
+ - "--loglevel"
+ - "debug"
clamav:
- image: clamav/clamav:0.105
+ image: clamav/clamav:1.1
rspamd:
depends_on:
- - redis
- - clamav
+ clamav:
+ condition: service_healthy
+ redis:
+ condition: service_started
container_name: rspamd
- image: a16bitsysop/rspamd:3.3-r0-alpine3.16.2-r0
+ image: a16bitsysop/rspamd:3.5-r7-alpine3.18.2-r0
environment:
- REDIS=redis
- CLAMAV=clamav
diff --git a/third-party/rspamd/pom.xml b/third-party/rspamd/pom.xml
index 11718f0eb20..ff91ce9356c 100644
--- a/third-party/rspamd/pom.xml
+++ b/third-party/rspamd/pom.xml
@@ -207,13 +207,14 @@
jar-with-dependencies
+ apache-james-rspamd
single
- compile
+ package
diff --git a/third-party/rspamd/sample-configuration/keystore b/third-party/rspamd/sample-configuration/keystore
deleted file mode 100644
index 361cd01f43d..00000000000
Binary files a/third-party/rspamd/sample-configuration/keystore and /dev/null differ
diff --git a/third-party/rspamd/src/test/java/org/apache/james/rspamd/DockerClamAV.java b/third-party/rspamd/src/test/java/org/apache/james/rspamd/DockerClamAV.java
index f2bc942c162..5b18644ec90 100644
--- a/third-party/rspamd/src/test/java/org/apache/james/rspamd/DockerClamAV.java
+++ b/third-party/rspamd/src/test/java/org/apache/james/rspamd/DockerClamAV.java
@@ -28,14 +28,13 @@
import org.testcontainers.utility.DockerImageName;
public class DockerClamAV {
- private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("clamav/clamav");
- private static final String DEFAULT_TAG = "0.105";
+ private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("clamav/clamav").withTag("1.1");
private static final int DEFAULT_PORT = 3310;
private final GenericContainer> container;
public DockerClamAV(Network network) {
- this.container = new GenericContainer<>(DEFAULT_IMAGE_NAME.withTag(DEFAULT_TAG))
+ this.container = new GenericContainer<>(DEFAULT_IMAGE_NAME)
.withExposedPorts(DEFAULT_PORT)
.withEnv("CLAMAV_NO_FRESHCLAMD", "true")
.withEnv("CLAMAV_NO_MILTERD", "true")
diff --git a/third-party/rspamd/src/test/java/org/apache/james/rspamd/DockerRspamd.java b/third-party/rspamd/src/test/java/org/apache/james/rspamd/DockerRspamd.java
index ba8ceee0b5b..1be14bd554e 100644
--- a/third-party/rspamd/src/test/java/org/apache/james/rspamd/DockerRspamd.java
+++ b/third-party/rspamd/src/test/java/org/apache/james/rspamd/DockerRspamd.java
@@ -33,7 +33,7 @@
public class DockerRspamd {
public static final String PASSWORD = "admin";
private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("a16bitsysop/rspamd");
- private static final String DEFAULT_TAG = "3.3-r0-alpine3.16.2-r0";
+ private static final String DEFAULT_TAG = "3.5-r7-alpine3.18.2-r0";
private static final int DEFAULT_PORT = 11334;
private final DockerRedis dockerRedis;
diff --git a/third-party/spamassassin/docker-compose.yml b/third-party/spamassassin/docker-compose.yml
index 618806afc1b..514717ef54c 100644
--- a/third-party/spamassassin/docker-compose.yml
+++ b/third-party/spamassassin/docker-compose.yml
@@ -8,9 +8,10 @@ services:
image: apache/james:memory-latest
container_name: james
hostname: james.local
+ command:
+ - --generate-keystore
volumes:
- - $PWD/target/apache-james-spamassassin-3.8.0-SNAPSHOT-jar-with-dependencies.jar:/root/extensions-jars/james-server-spamassassin.jar
- - $PWD/sample-configuration/keystore:/root/conf/keystore
+ - $PWD/target/apache-james-spamassassin-jar-with-dependencies.jar:/root/extensions-jars/james-server-spamassassin.jar
- $PWD/sample-configuration/extensions.properties:/root/conf/extensions.properties
- $PWD/sample-configuration/spamassassin.properties:/root/conf/spamassassin.properties
- $PWD/sample-configuration/mailetcontainer.xml:/root/conf/mailetcontainer.xml
@@ -27,6 +28,6 @@ services:
- "8000:8000"
spamassassin:
- image: instantlinux/spamassassin:3.4.6-1
+ image: instantlinux/spamassassin:4.0.0-6
ports:
- "783:783"
\ No newline at end of file
diff --git a/third-party/spamassassin/pom.xml b/third-party/spamassassin/pom.xml
index e3f6dc9710a..607e84e00a3 100644
--- a/third-party/spamassassin/pom.xml
+++ b/third-party/spamassassin/pom.xml
@@ -192,13 +192,14 @@
jar-with-dependencies
+ apache-james-spamassassin
single
- compile
+ package
diff --git a/third-party/spamassassin/sample-configuration/keystore b/third-party/spamassassin/sample-configuration/keystore
deleted file mode 100644
index 361cd01f43d..00000000000
Binary files a/third-party/spamassassin/sample-configuration/keystore and /dev/null differ
diff --git a/third-party/spamassassin/src/test/java/org/apache/james/spamassassin/SpamAssassinExtension.java b/third-party/spamassassin/src/test/java/org/apache/james/spamassassin/SpamAssassinExtension.java
index a15eb2e636a..2120de5aa4e 100644
--- a/third-party/spamassassin/src/test/java/org/apache/james/spamassassin/SpamAssassinExtension.java
+++ b/third-party/spamassassin/src/test/java/org/apache/james/spamassassin/SpamAssassinExtension.java
@@ -38,33 +38,21 @@
import org.junit.jupiter.api.extension.ParameterResolver;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.HostPortWaitStrategy;
-import org.testcontainers.images.builder.ImageFromDockerfile;
-import org.testcontainers.utility.Base58;
import com.github.fge.lambdas.Throwing;
-import com.google.common.collect.ImmutableMap;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
public class SpamAssassinExtension implements BeforeAllCallback, AfterEachCallback, ParameterResolver {
+ public static final int SPAMASSASSIN_PORT = 783;
private static final Duration STARTUP_TIMEOUT = Duration.ofMinutes(30);
- private static final String UNIQUE_IDENTIFIER = Base58.randomString(16).toLowerCase();
-
- private static final boolean DELETE_ON_EXIT = false;
- private static final GenericContainer> spamAssassinContainer = new GenericContainer<>(
- new ImageFromDockerfile("james-spamassassin/" + UNIQUE_IDENTIFIER, DELETE_ON_EXIT)
- .withFileFromClasspath("Dockerfile", "docker/spamassassin/Dockerfile")
- .withFileFromClasspath("local.cf", "docker/spamassassin/local.cf")
- .withFileFromClasspath("run.sh", "docker/spamassassin/run.sh")
- .withFileFromClasspath("spamd.sh", "docker/spamassassin/spamd.sh")
- .withFileFromClasspath("rule-update.sh", "docker/spamassassin/rule-update.sh")
- .withFileFromClasspath("bayes_pg.sql", "docker/spamassassin/bayes_pg.sql"))
- .withCreateContainerCmdModifier(cmd -> cmd.withName("spam-assassin-" + UUID.randomUUID().toString()))
+ private static final String SPAMASSASSIN_IMAGE = "instantlinux/spamassassin:4.0.0-6";
+ private static final GenericContainer> spamAssassinContainer = new GenericContainer<>(SPAMASSASSIN_IMAGE)
+ .withCreateContainerCmdModifier(cmd -> cmd.withName("james-spam-assassin-test-" + UUID.randomUUID()))
.withStartupTimeout(STARTUP_TIMEOUT)
- .withExposedPorts(783)
- .withTmpFs(ImmutableMap.of("/var/lib/postgresql/data", "rw,noexec,nosuid,size=200m"))
+ .withExposedPorts(SPAMASSASSIN_PORT)
.waitingFor(new HostPortWaitStrategy().withRateLimiter(RateLimiters.TWENTIES_PER_SECOND));
static {
@@ -106,8 +94,6 @@ public SpamAssassin getSpamAssassin() {
}
public static class SpamAssassin {
- private static final int SPAMASSASSIN_PORT = 783;
-
private final String ip;
private final int bindingPort;
private final GenericContainer> spamAssassinContainer;
@@ -155,7 +141,7 @@ private void train(String user, Path folder, TrainingKind trainingKind) throws I
private enum TrainingKind {
SPAM("--spam"), HAM("--ham");
- private String saLearnExtensionName;
+ private final String saLearnExtensionName;
TrainingKind(String saLearnExtensionName) {
this.saLearnExtensionName = saLearnExtensionName;
diff --git a/third-party/spamassassin/src/test/java/org/apache/james/spamassassin/SpamAssassinIntegrationTest.java b/third-party/spamassassin/src/test/java/org/apache/james/spamassassin/SpamAssassinIntegrationTest.java
index 2578092b5a4..2583e9ef9ba 100644
--- a/third-party/spamassassin/src/test/java/org/apache/james/spamassassin/SpamAssassinIntegrationTest.java
+++ b/third-party/spamassassin/src/test/java/org/apache/james/spamassassin/SpamAssassinIntegrationTest.java
@@ -30,7 +30,6 @@
import static org.assertj.core.api.Assertions.assertThat;
import java.io.File;
-import java.util.UUID;
import javax.mail.MessagingException;
@@ -44,8 +43,6 @@
import org.apache.james.modules.protocols.SmtpGuiceProbe;
import org.apache.james.transport.matchers.All;
import org.apache.james.util.Host;
-import org.apache.james.util.docker.DockerContainer;
-import org.apache.james.util.docker.RateLimiters;
import org.apache.james.utils.DataProbeImpl;
import org.apache.james.utils.SMTPMessageSender;
import org.apache.james.utils.TestIMAPClient;
@@ -55,7 +52,6 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.api.io.TempDir;
-import org.testcontainers.containers.wait.strategy.HostPortWaitStrategy;
import com.google.inject.Binder;
import com.google.inject.Module;
@@ -64,15 +60,9 @@
class SpamAssassinIntegrationTest {
private static final String SPAM_CONTENT = "XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X";
- private static final String SPAMASSASSIN_IMAGE = "instantlinux/spamassassin:3.4.6-1";
@RegisterExtension
- public static DockerContainer spamAssassinContainer = DockerContainer.fromName(SPAMASSASSIN_IMAGE)
- .withExposedPorts(783)
- .withAffinityToContainer()
- .waitingFor(new HostPortWaitStrategy().withRateLimiter(RateLimiters.TWENTIES_PER_SECOND))
- .withName("james-testing-spamassassin-" + UUID.randomUUID());
-
+ public static SpamAssassinExtension spamAssassinExtension = new SpamAssassinExtension();
@RegisterExtension
public TestIMAPClient messageReader = new TestIMAPClient();
@RegisterExtension
@@ -100,7 +90,7 @@ public void configure(Binder binder) {
@Provides
@Singleton
private SpamAssassinConfiguration provideSpamAssassinConfiguration(){
- return new SpamAssassinConfiguration(Host.parseConfString("localhost", spamAssassinContainer.getMappedPort(783)));
+ return new SpamAssassinConfiguration(Host.parseConfString("localhost", spamAssassinExtension.getSpamAssassin().getBindingPort()));
}
})
.build(temporaryFolder);
diff --git a/third-party/spamassassin/src/test/resources/docker/spamassassin/Dockerfile b/third-party/spamassassin/src/test/resources/docker/spamassassin/Dockerfile
deleted file mode 100644
index 51ea4af10fa..00000000000
--- a/third-party/spamassassin/src/test/resources/docker/spamassassin/Dockerfile
+++ /dev/null
@@ -1,43 +0,0 @@
-FROM postgres:15.1
-
-ENV SPAMASSASSIN_VERSION 3.4.6
-
-RUN apt-get update && \
- DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \
- gpg \
- libio-socket-ip-perl \
- libmail-dkim-perl \
- libnet-ident-perl \
- libsocket-getaddrinfo-perl \
- pyzor \
- razor \
- libdbi-perl \
- libdbd-pg-perl \
- spamassassin=${SPAMASSASSIN_VERSION}* && \
- apt-get clean && \
- rm -rf /var/lib/apt/lists/*
-
-RUN mkdir -p /etc/spamassassin/sa-update-keys && \
- chmod 700 /etc/spamassassin/sa-update-keys && \
- chown debian-spamd:debian-spamd /etc/spamassassin/sa-update-keys && \
- mkdir -p /var/lib/spamassassin/.pyzor && \
- chmod 700 /var/lib/spamassassin/.pyzor && \
- echo "public.pyzor.org:24441" > /var/lib/spamassassin/.pyzor/servers && \
- chmod 600 /var/lib/spamassassin/.pyzor/servers && \
- chown -R debian-spamd:debian-spamd /var/lib/spamassassin/.pyzor
-
-RUN sed -i 's/^logfile = .*$/logfile = \/dev\/stderr/g' /etc/razor/razor-agent.conf
-
-COPY spamd.sh /
-COPY rule-update.sh /
-COPY run.sh /
-RUN chmod 755 /spamd.sh /rule-update.sh /run.sh
-
-COPY local.cf /etc/spamassassin/
-
-# Bayes database will be created automatically by Postres
-COPY bayes_pg.sql /docker-entrypoint-initdb.d/
-
-EXPOSE 783
-
-ENTRYPOINT ["/spamd.sh"]
diff --git a/third-party/spamassassin/src/test/resources/docker/spamassassin/bayes_pg.sql b/third-party/spamassassin/src/test/resources/docker/spamassassin/bayes_pg.sql
deleted file mode 100644
index ef964728ff4..00000000000
--- a/third-party/spamassassin/src/test/resources/docker/spamassassin/bayes_pg.sql
+++ /dev/null
@@ -1,119 +0,0 @@
-
-CREATE TABLE bayes_expire (
- id integer NOT NULL default '0',
- runtime integer NOT NULL default '0'
-) WITHOUT OIDS;
-
-CREATE INDEX bayes_expire_idx1 ON bayes_expire (id);
-
-CREATE TABLE bayes_global_vars (
- variable varchar(30) NOT NULL default '',
- value varchar(200) NOT NULL default '',
- PRIMARY KEY (variable)
-) WITHOUT OIDS;
-
-INSERT INTO bayes_global_vars VALUES ('VERSION','3');
-
-CREATE TABLE bayes_seen (
- id integer NOT NULL default '0',
- msgid varchar(200) NOT NULL default '',
- flag character(1) NOT NULL default '',
- PRIMARY KEY (id,msgid)
-) WITHOUT OIDS;
-
-CREATE TABLE bayes_token (
- id integer NOT NULL default '0',
- token bytea NOT NULL default '',
- spam_count integer NOT NULL default '0',
- ham_count integer NOT NULL default '0',
- atime integer NOT NULL default '0',
- PRIMARY KEY (id,token)
-) WITHOUT OIDS;
-
-CREATE INDEX bayes_token_idx1 ON bayes_token (token);
-
-ALTER TABLE bayes_token SET (fillfactor=95);
-
-CREATE TABLE bayes_vars (
- id serial NOT NULL,
- username varchar(200) NOT NULL default '',
- spam_count integer NOT NULL default '0',
- ham_count integer NOT NULL default '0',
- token_count integer NOT NULL default '0',
- last_expire integer NOT NULL default '0',
- last_atime_delta integer NOT NULL default '0',
- last_expire_reduce integer NOT NULL default '0',
- oldest_token_age integer NOT NULL default '2147483647',
- newest_token_age integer NOT NULL default '0',
- PRIMARY KEY (id)
-) WITHOUT OIDS;
-
-CREATE UNIQUE INDEX bayes_vars_idx1 ON bayes_vars (username);
-
-CREATE OR REPLACE FUNCTION greatest_int (integer, integer)
- RETURNS INTEGER
- IMMUTABLE STRICT
- AS 'SELECT CASE WHEN $1 < $2 THEN $2 ELSE $1 END;'
- LANGUAGE SQL;
-
-CREATE OR REPLACE FUNCTION least_int (integer, integer)
- RETURNS INTEGER
- IMMUTABLE STRICT
- AS 'SELECT CASE WHEN $1 < $2 THEN $1 ELSE $2 END;'
- LANGUAGE SQL;
-
-CREATE OR REPLACE FUNCTION put_tokens(INTEGER,
- BYTEA[],
- INTEGER,
- INTEGER,
- INTEGER)
-RETURNS VOID AS '
-DECLARE
- inuserid ALIAS FOR $1;
- intokenary ALIAS FOR $2;
- inspam_count ALIAS FOR $3;
- inham_count ALIAS FOR $4;
- inatime ALIAS FOR $5;
- _token BYTEA;
- new_tokens INTEGER := 0;
-BEGIN
- for i in array_lower(intokenary, 1) .. array_upper(intokenary, 1)
- LOOP
- _token := intokenary[i];
- UPDATE bayes_token
- SET spam_count = greatest_int(spam_count + inspam_count, 0),
- ham_count = greatest_int(ham_count + inham_count, 0),
- atime = greatest_int(atime, inatime)
- WHERE id = inuserid
- AND token = _token;
- IF NOT FOUND THEN
- -- we do not insert negative counts, just return true
- IF NOT (inspam_count < 0 OR inham_count < 0) THEN
- INSERT INTO bayes_token (id, token, spam_count, ham_count, atime)
- VALUES (inuserid, _token, inspam_count, inham_count, inatime);
- IF FOUND THEN
- new_tokens := new_tokens + 1;
- END IF;
- END IF;
- END IF;
- END LOOP;
-
- IF new_tokens > 0 AND inatime > 0 THEN
- UPDATE bayes_vars
- SET token_count = token_count + new_tokens,
- newest_token_age = greatest_int(newest_token_age, inatime),
- oldest_token_age = least_int(oldest_token_age, inatime)
- WHERE id = inuserid;
- ELSIF new_tokens > 0 AND NOT inatime > 0 THEN
- UPDATE bayes_vars
- SET token_count = token_count + new_tokens
- WHERE id = inuserid;
- ELSIF NOT new_tokens > 0 AND inatime > 0 THEN
- UPDATE bayes_vars
- SET newest_token_age = greatest_int(newest_token_age, inatime),
- oldest_token_age = least_int(oldest_token_age, inatime)
- WHERE id = inuserid;
- END IF;
- RETURN;
-END;
-' LANGUAGE 'plpgsql';
diff --git a/third-party/spamassassin/src/test/resources/docker/spamassassin/local.cf b/third-party/spamassassin/src/test/resources/docker/spamassassin/local.cf
deleted file mode 100644
index 6005e55403b..00000000000
--- a/third-party/spamassassin/src/test/resources/docker/spamassassin/local.cf
+++ /dev/null
@@ -1,97 +0,0 @@
-# This is the right place to customize your installation of SpamAssassin.
-#
-# See 'perldoc Mail::SpamAssassin::Conf' for details of what can be
-# tweaked.
-#
-# Only a small subset of options are listed below
-#
-###########################################################################
-
-# Add *****SPAM***** to the Subject header of spam e-mails
-#
-# rewrite_header Subject *****SPAM*****
-
-
-# Save spam messages as a message/rfc822 MIME attachment instead of
-# modifying the original message (0: off, 2: use text/plain instead)
-#
-# report_safe 1
-
-
-# Set which networks or hosts are considered 'trusted' by your mail
-# server (i.e. not spammers)
-#
-# trusted_networks 212.17.35.
-
-
-# Set file-locking method (flock is not safe over NFS, but is faster)
-#
-# lock_method flock
-
-
-# Set the threshold at which a message is considered spam (default: 5.0)
-#
-# required_score 5.0
-
-
-# Use Bayesian classifier (default: 1)
-#
-use_bayes 1
-
-
-# Bayesian classifier auto-learning (default: 1)
-#
-#bayes_auto_learn 1
-
-bayes_store_module Mail::SpamAssassin::BayesStore::PgSQL
-
-bayes_sql_dsn DBI:Pg:dbname=postgres;host=localhost
-bayes_sql_username postgres
-
-bayes_min_spam_num 1
-bayes_min_ham_num 1
-
-
-# Set headers which may provide inappropriate cues to the Bayesian
-# classifier
-#
-# bayes_ignore_header X-Bogosity
-# bayes_ignore_header X-Spam-Flag
-# bayes_ignore_header X-Spam-Status
-
-
-# Whether to decode non- UTF-8 and non-ASCII textual parts and recode
-# them to UTF-8 before the text is given over to rules processing.
-#
-# normalize_charset 1
-
-# Some shortcircuiting, if the plugin is enabled
-#
-ifplugin Mail::SpamAssassin::Plugin::Shortcircuit
-#
-# default: strongly-whitelisted mails are *really* whitelisted now, if the
-# shortcircuiting plugin is active, causing early exit to save CPU load.
-# Uncomment to turn this on
-#
-# shortcircuit USER_IN_WHITELIST on
-# shortcircuit USER_IN_DEF_WHITELIST on
-# shortcircuit USER_IN_ALL_SPAM_TO on
-# shortcircuit SUBJECT_IN_WHITELIST on
-
-# the opposite; blacklisted mails can also save CPU
-#
-# shortcircuit USER_IN_BLACKLIST on
-# shortcircuit USER_IN_BLACKLIST_TO on
-# shortcircuit SUBJECT_IN_BLACKLIST on
-
-# if you have taken the time to correctly specify your "trusted_networks",
-# this is another good way to save CPU
-#
-# shortcircuit ALL_TRUSTED on
-
-# and a well-trained bayes DB can save running rules, too
-#
-# shortcircuit BAYES_99 spam
-# shortcircuit BAYES_00 ham
-
-endif # Mail::SpamAssassin::Plugin::Shortcircuit
diff --git a/third-party/spamassassin/src/test/resources/docker/spamassassin/rule-update.sh b/third-party/spamassassin/src/test/resources/docker/spamassassin/rule-update.sh
deleted file mode 100755
index 2867735cc4a..00000000000
--- a/third-party/spamassassin/src/test/resources/docker/spamassassin/rule-update.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-
-while true; do
- sleep 1m
- su debian-spamd -c 'sa-update' && kill -HUP `cat /var/run/spamd.pid`
- sleep 1d
-done
diff --git a/third-party/spamassassin/src/test/resources/docker/spamassassin/run.sh b/third-party/spamassassin/src/test/resources/docker/spamassassin/run.sh
deleted file mode 100755
index b4a13518da3..00000000000
--- a/third-party/spamassassin/src/test/resources/docker/spamassassin/run.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-set -m
-
-/rule-update.sh &
-/spamd.sh &
-
-pids=`jobs -p`
-
-wait
diff --git a/third-party/spamassassin/src/test/resources/docker/spamassassin/spamd.sh b/third-party/spamassassin/src/test/resources/docker/spamassassin/spamd.sh
deleted file mode 100755
index 31c22613648..00000000000
--- a/third-party/spamassassin/src/test/resources/docker/spamassassin/spamd.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-echo "Run Postgres"
-/usr/local/bin/docker-entrypoint.sh postgres &
-
-echo "Run spamd"
-spamd --username debian-spamd \
- --nouser-config \
- --syslog stderr \
- --pidfile /var/run/spamd.pid \
- --helper-home-dir /var/lib/spamassassin \
- --ip-address \
- --allowed-ips 0.0.0.0/0 \
- --allow-tell \
- --debug bayes,learn