You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2023/05/17 01:40:28 UTC

[james-project] branch master updated (3797f3d7ab -> ab09025932)

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git


    from 3797f3d7ab JAMES-3533 JMAP - Download - Fix extract blobId of MessagePartBlobResolver
     new 527eeec928 [REFACTORING] More fluent Cassandra statement recording
     new 5d908fd385 [REFACTORING] Tiny improvements of CassandraConfiguration
     new 1ab035fb7d [PERF] Allow to disable ACLs
     new 414bacdcc4 [PERF] Disable JMAP related listeners if JMAP is disabled
     new 0b26b27df1 [DOCUMENTATION] Performance checklist
     new b8cd273438 [TEST] Reduce integration test boiler plate
     new ab09025932 [TEST] Reduce integration test boiler plate

The 7 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../init/configuration/CassandraConfiguration.java |  30 +++-
 .../backends/cassandra/StatementRecorder.java      |   2 +-
 .../james/backends/cassandra/TestingSession.java   |   4 +-
 .../backends/cassandra/TestingSessionTest.java     |   9 +-
 .../mailbox/cassandra/mail/CassandraACLMapper.java |  35 ++++-
 .../cassandra/CassandraMailboxManagerTest.java     |   2 +-
 .../CassandraMessageIdManagerSideEffectTest.java   |   3 +-
 ...2Test.java => CassandraACLMapperNoACLTest.java} |  98 ++++--------
 .../cassandra/mail/CassandraACLMapperV1Test.java   |   2 +-
 .../cassandra/mail/CassandraACLMapperV2Test.java   |   2 +-
 .../mail/CassandraIndexTableHandlerTest.java       |   3 +-
 .../cassandra/mail/CassandraMailboxMapperTest.java |   2 +-
 .../mail/CassandraMessageIdMapperTest.java         |   3 +-
 .../cassandra/mail/CassandraMessageMapperTest.java |  27 ++--
 .../quota/CassandraPerUserMaxQuotaManagerTest.java |   3 +-
 .../cassandra/CassandraListingTest.java            |   9 +-
 .../james/CassandraJamesServerConfiguration.java   |  27 +++-
 .../org/apache/james/CassandraJamesServerMain.java |  13 +-
 .../distributed-app/docs/modules/ROOT/nav.adoc     |   1 +
 .../modules/ROOT/pages/configure/cassandra.adoc    |   8 +-
 .../docs/modules/ROOT/pages/operate/index.adoc     |   2 +-
 .../ROOT/pages/operate/performanceChecklist.adoc   | 164 +++++++++++++++++++++
 .../james/CassandraRabbitMQJamesConfiguration.java |  30 +++-
 .../james/CassandraRabbitMQJamesServerMain.java    |  13 +-
 .../org/apache/james/CassandraCacheQueryTest.java  |   3 +-
 .../org/apache/james/MemoryJamesConfiguration.java |  32 +++-
 .../org/apache/james/MemoryJamesServerMain.java    |  13 +-
 .../java/org/apache/james/MemoryJmapTestRule.java  |   1 +
 .../blob/cassandra/cache/CachedBlobStoreTest.java  |   3 +-
 .../modules/mailbox/CassandraMailboxModule.java    |   6 +-
 .../apache/james/jmap/draft/JMAPCommonModule.java  |   6 +-
 .../draft/JMAPListenerModule.java}                 |  19 +--
 .../org/apache/james/jmap/draft/JMAPModule.java    |  34 ++---
 .../domainlist/cassandra/CacheDomainListTest.java  |   6 +-
 .../james/jmap/memory/cucumber/MemoryStepdefs.java |   1 +
 .../cucumber/awss3/RabbitMQAwsS3Stepdefs.java      |   1 +
 ...gateSetMethodTest.java => DistributedBase.java} |   4 +-
 .../DistributedDelegateGetMethodTest.java          |  35 +----
 .../DistributedDelegateSetMethodTest.java          |  35 +----
 .../DistributedDelegatedAccountGetMethodTest.java  |  35 +----
 .../DistributedDelegatedAccountSetMethodTest.java  |  35 +----
 .../distributed/DistributedDownloadTest.java       |  32 +---
 .../distributed/DistributedEchoMethodTest.java     |  33 +----
 .../distributed/DistributedEmailGetMethodTest.java |  33 +----
 .../DistributedEmailQueryMethodTest.java           |  33 +----
 .../distributed/DistributedEmailSetMethodTest.java |  34 +----
 .../DistributedEmailSubmissionSetMethodtest.java   |  33 +----
 .../distributed/DistributedIdentityGetTest.java    |  35 +----
 .../distributed/DistributedIdentitySetTest.java    |  35 +----
 .../distributed/DistributedMDNParseMethodTest.java |  32 +---
 .../distributed/DistributedMDNSendMethodTest.java  |  33 +----
 .../DistributedMailboxGetMethodTest.java           |  32 +---
 .../DistributedMailboxQueryMethodTest.java         |  32 +---
 .../DistributedMailboxSetMethodTest.java           |  32 +---
 .../distributed/DistributedProvisioningTest.java   |  32 +---
 .../DistributedQuotaChangesMethodTest.java         |  31 +---
 .../distributed/DistributedQuotaGetMethodTest.java |  31 +---
 .../DistributedQuotaQueryMethodTest.java           |  31 +---
 .../distributed/DistributedSessionRouteTest.java   |  33 +----
 .../rfc8621/distributed/DistributedUploadTest.java |  32 +---
 .../DistributedVacationResponseGetMethodTest.java  |  32 +---
 .../DistributedVacationResponseSetMethodTest.java  |  32 +---
 .../distributed/DistributedWebPushTest.java        |   1 +
 .../distributed/DistributedWebSocketTest.java      |  33 +----
 .../jmap/rfc8621/distributed/ReadLevelTest.java    |  31 ++--
 .../rfc8621/memory/MemoryBackReferenceTest.java    |  21 +--
 ...yDelegateSetMethodTest.java => MemoryBase.java} |   7 +-
 .../memory/MemoryDelegateGetMethodTest.java        |  22 +--
 .../memory/MemoryDelegateSetMethodTest.java        |  22 +--
 .../MemoryDelegatedAccountGetMethodTest.java       |  22 +--
 .../MemoryDelegatedAccountSetMethodTest.java       |  22 +--
 .../jmap/rfc8621/memory/MemoryDownloadTest.java    |  21 +--
 .../jmap/rfc8621/memory/MemoryEchoMethodTest.java  |  21 +--
 .../rfc8621/memory/MemoryEmailGetMethodTest.java   |  22 +--
 .../jmap/rfc8621/memory/MemoryEmailImportTest.java |  21 +--
 .../rfc8621/memory/MemoryEmailQueryMethodTest.java |  21 +--
 .../rfc8621/memory/MemoryEmailSetMethodTest.java   |  23 +--
 .../memory/MemoryEmailSubmissionSetMethodTest.java |  21 +--
 .../jmap/rfc8621/memory/MemoryEventSourceTest.java |  22 +--
 .../memory/MemoryIdentityGetMethodTest.java        |  21 +--
 .../memory/MemoryIdentitySetMethodTests.java       |  22 +--
 .../rfc8621/memory/MemoryMDNParseMethodTest.java   |  21 +--
 .../rfc8621/memory/MemoryMDNSendMethodTest.java    |  21 +--
 .../rfc8621/memory/MemoryMailboxGetMethodTest.java |  21 +--
 .../memory/MemoryMailboxQueryMethodTest.java       |  21 +--
 .../rfc8621/memory/MemoryMailboxSetMethodTest.java |  21 +--
 .../rfc8621/memory/MemoryProvisioningTest.java     |  21 +--
 .../memory/MemoryQuotaChangesMethodTest.java       |  20 +--
 .../rfc8621/memory/MemoryQuotaGetMethodTest.java   |  20 +--
 .../rfc8621/memory/MemoryQuotaQueryMethodTest.java |  20 +--
 .../rfc8621/memory/MemorySessionRouteTest.java     |  21 +--
 .../memory/MemoryThreadChangesMethodTest.java      |  21 +--
 .../rfc8621/memory/MemoryThreadGetMethodTest.java  |  21 +--
 .../jmap/rfc8621/memory/MemoryUploadTest.java      |  21 +--
 .../MemoryVacationResponseGetMethodTest.java       |  21 +--
 .../MemoryVacationResponseSetMethodTest.java       |  21 +--
 .../jmap/rfc8621/memory/MemoryWebSocketTest.java   |  21 +--
 src/site/xdoc/server/config-cassandra.xml          |   4 +
 98 files changed, 554 insertions(+), 1623 deletions(-)
 copy mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/{CassandraACLMapperV2Test.java => CassandraACLMapperNoACLTest.java} (55%)
 create mode 100644 server/apps/distributed-app/docs/modules/ROOT/pages/operate/performanceChecklist.adoc
 copy server/container/guice/protocols/jmap/src/main/java/org/apache/james/{modules/protocols/JmapEventBusModule.java => jmap/draft/JMAPListenerModule.java} (67%)
 copy server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/{DistributedDelegateSetMethodTest.java => DistributedBase.java} (95%)
 copy server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/{MemoryDelegateSetMethodTest.java => MemoryBase.java} (92%)


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org


[james-project] 03/07: [PERF] Allow to disable ACLs

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 1ab035fb7d24c8091f0ab6a0b12838dc15760f56
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue May 2 09:34:09 2023 +0700

    [PERF] Allow to disable ACLs
---
 .../init/configuration/CassandraConfiguration.java | 26 ++++--
 .../mailbox/cassandra/mail/CassandraACLMapper.java | 35 +++++++-
 .../cassandra/CassandraMailboxManagerTest.java     |  2 +-
 ...2Test.java => CassandraACLMapperNoACLTest.java} | 98 +++++++---------------
 .../cassandra/mail/CassandraACLMapperV1Test.java   |  2 +-
 .../cassandra/mail/CassandraACLMapperV2Test.java   |  2 +-
 .../cassandra/mail/CassandraMailboxMapperTest.java |  2 +-
 .../modules/ROOT/pages/configure/cassandra.adoc    |  8 +-
 src/site/xdoc/server/config-cassandra.xml          |  4 +
 9 files changed, 101 insertions(+), 78 deletions(-)

diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/configuration/CassandraConfiguration.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/configuration/CassandraConfiguration.java
index a8f85d367d..b1a7fcc55e 100644
--- a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/configuration/CassandraConfiguration.java
+++ b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/configuration/CassandraConfiguration.java
@@ -82,6 +82,7 @@ public class CassandraConfiguration {
     private static final String CONSISTENCY_LEVEL_LIGHTWEIGHT_TRANSACTION = "cassandra.consistency_level.lightweight_transaction";
     private static final String OPTIMISTIC_CONSISTENCY_LEVEL = "optimistic.consistency.level.enabled";
     private static final String MAIL_REPOSITORY_STRONG_CONSISTENCY = "mailrepository.strong.consistency";
+    private static final String ACL_ENABLED = "acl.enabled";
 
     public static final CassandraConfiguration DEFAULT_CONFIGURATION = builder().build();
 
@@ -108,6 +109,7 @@ public class CassandraConfiguration {
         private Optional<Boolean> modseqReadStrongConsistency = Optional.empty();
         private Optional<Boolean> optimisticConsistencyLevel = Optional.empty();
         private Optional<Boolean> mailRepositoryStrongConsistency = Optional.empty();
+        private Optional<Boolean> aclEnabled = Optional.empty();
 
         public Builder mailboxReadStrongConsistency(boolean value) {
             this.mailboxReadStrongConsistency = Optional.of(value);
@@ -119,6 +121,11 @@ public class CassandraConfiguration {
             return this;
         }
 
+        public Builder aclEnabled(Optional<Boolean> value) {
+            this.aclEnabled = value;
+            return this;
+        }
+
         public Builder messageReadStrongConsistency(boolean value) {
             this.messageReadStrongConsistency = Optional.of(value);
             return this;
@@ -364,7 +371,8 @@ public class CassandraConfiguration {
                 optimisticConsistencyLevel.orElse(DEFAULT_OPTIMISTIC_CONSISTENCY_LEVEL),
                 mailRepositoryStrongConsistency.orElse(DEFAULT_MAIL_REPOSITORY_STRONG_CONSISTENCY),
                 uidReadStrongConsistency.orElse(DEFAULT_STRONG_CONSISTENCY),
-                modseqReadStrongConsistency.orElse(DEFAULT_STRONG_CONSISTENCY));
+                modseqReadStrongConsistency.orElse(DEFAULT_STRONG_CONSISTENCY),
+                aclEnabled.orElse(true));
         }
     }
 
@@ -418,6 +426,7 @@ public class CassandraConfiguration {
                 propertiesConfiguration.getBoolean(OPTIMISTIC_CONSISTENCY_LEVEL, null)))
             .mailRepositoryStrongConsistency(Optional.ofNullable(
                 propertiesConfiguration.getBoolean(MAIL_REPOSITORY_STRONG_CONSISTENCY, null)))
+            .aclEnabled(Optional.ofNullable(propertiesConfiguration.getBoolean(ACL_ENABLED, null)))
             .build();
     }
 
@@ -443,6 +452,7 @@ public class CassandraConfiguration {
     private final boolean mailRepositoryStrongConsistency;
     private final boolean uidReadStrongConsistency;
     private final boolean modseqReadStrongConsistency;
+    private final boolean aclEnabled;
 
     @VisibleForTesting
     CassandraConfiguration(int aclMaxRetry, int expungeChunkSize,
@@ -454,7 +464,7 @@ public class CassandraConfiguration {
                            float mailboxCountersReadRepairChanceOneHundred, boolean mailboxReadStrongConsistency,
                            boolean messageReadStrongConsistency, boolean messageWriteStrongConsistency,
                            boolean optimisticConsistencyLevel, boolean mailRepositoryStrongConsistency,
-                           boolean uidReadStrongConsistency, boolean modseqReadStrongConsistency) {
+                           boolean uidReadStrongConsistency, boolean modseqReadStrongConsistency, boolean aclEnabled) {
         this.aclMaxRetry = aclMaxRetry;
         this.expungeChunkSize = expungeChunkSize;
         this.flagsUpdateMessageIdMaxRetry = flagsUpdateMessageIdMaxRetry;
@@ -477,6 +487,7 @@ public class CassandraConfiguration {
         this.mailRepositoryStrongConsistency = mailRepositoryStrongConsistency;
         this.uidReadStrongConsistency = uidReadStrongConsistency;
         this.modseqReadStrongConsistency = modseqReadStrongConsistency;
+        this.aclEnabled = aclEnabled;
     }
 
     public boolean isUidReadStrongConsistency() {
@@ -567,6 +578,10 @@ public class CassandraConfiguration {
         return mailRepositoryStrongConsistency;
     }
 
+    public boolean isAclEnabled() {
+        return aclEnabled;
+    }
+
     @Override
     public final boolean equals(Object o) {
         if (o instanceof CassandraConfiguration) {
@@ -593,8 +608,8 @@ public class CassandraConfiguration {
                 && Objects.equals(this.optimisticConsistencyLevel, that.optimisticConsistencyLevel)
                 && Objects.equals(this.uidReadStrongConsistency, that.uidReadStrongConsistency)
                 && Objects.equals(this.modseqReadStrongConsistency, that.modseqReadStrongConsistency)
-                && Objects.equals(this.mailRepositoryStrongConsistency, that.mailRepositoryStrongConsistency);
-
+                && Objects.equals(this.mailRepositoryStrongConsistency, that.mailRepositoryStrongConsistency)
+                && Objects.equals(this.aclEnabled, that.aclEnabled);
         }
         return false;
     }
@@ -608,7 +623,7 @@ public class CassandraConfiguration {
             consistencyLevelRegular, consistencyLevelLightweightTransaction, mailboxReadRepair,
             messageReadStrongConsistency, mailboxReadStrongConsistency, messageWriteStrongConsistency,
             optimisticConsistencyLevel, mailRepositoryStrongConsistency, uidReadStrongConsistency,
-            modseqReadStrongConsistency);
+            modseqReadStrongConsistency, aclEnabled);
     }
 
     @Override
@@ -636,6 +651,7 @@ public class CassandraConfiguration {
             .add("mailRepositoryStrongConsistency", mailRepositoryStrongConsistency)
             .add("modseqReadStrongConsistency", modseqReadStrongConsistency)
             .add("uidReadStrongConsistency", uidReadStrongConsistency)
+            .add("aclEnabled", aclEnabled)
             .toString();
     }
 }
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java
index da83a9adda..b050c2be23 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java
@@ -23,6 +23,8 @@ import java.util.Set;
 
 import javax.inject.Inject;
 
+import org.apache.commons.lang3.NotImplementedException;
+import org.apache.james.backends.cassandra.init.configuration.CassandraConfiguration;
 import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionManager;
 import org.apache.james.backends.cassandra.versions.SchemaVersion;
 import org.apache.james.eventsourcing.Command;
@@ -47,6 +49,7 @@ import com.google.common.collect.ImmutableSet;
 import reactor.core.publisher.Mono;
 
 public class CassandraACLMapper implements ACLMapper {
+
     public interface Store {
         Mono<MailboxACL> getACL(CassandraId cassandraId);
 
@@ -145,20 +148,50 @@ public class CassandraACLMapper implements ACLMapper {
         }
     }
 
+    public static class NaiveStore implements Store {
+        @Override
+        public Mono<MailboxACL> getACL(CassandraId cassandraId) {
+            return Mono.just(MailboxACL.EMPTY);
+        }
+
+        @Override
+        public Mono<ACLDiff> updateACL(CassandraId cassandraId, MailboxACL.ACLCommand command) {
+            return Mono.error(new NotImplementedException());
+        }
+
+        @Override
+        public Mono<ACLDiff> setACL(CassandraId cassandraId, MailboxACL mailboxACL) {
+            return Mono.error(new NotImplementedException());
+        }
+
+        @Override
+        public Mono<Void> delete(CassandraId cassandraId) {
+            // DOn't fail as the ACL never existed: this is a NOOP
+            return Mono.empty();
+        }
+    }
+
     public static final SchemaVersion ACL_V2_SCHEME_VERSION = new SchemaVersion(10);
     private final StoreV1 storeV1;
     private final StoreV2 storeV2;
+    private final NaiveStore naiveStore;
     private final CassandraSchemaVersionManager versionManager;
+    private final CassandraConfiguration cassandraConfiguration;
 
     @Inject
-    public CassandraACLMapper(StoreV1 storeV1, StoreV2 storeV2, CassandraSchemaVersionManager versionManager) {
+    public CassandraACLMapper(StoreV1 storeV1, StoreV2 storeV2, CassandraSchemaVersionManager versionManager, CassandraConfiguration cassandraConfiguration) {
         this.storeV1 = storeV1;
         this.storeV2 = storeV2;
+        naiveStore = new NaiveStore();
 
         this.versionManager = versionManager;
+        this.cassandraConfiguration = cassandraConfiguration;
     }
 
     private Mono<Store> store() {
+        if (!cassandraConfiguration.isAclEnabled()) {
+            return Mono.just(naiveStore);
+        }
         return versionManager.isBefore(ACL_V2_SCHEME_VERSION)
             .map(isBefore -> {
                 if (isBefore) {
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
index 7fff10ce0b..2e698aba26 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
@@ -830,7 +830,7 @@ public class CassandraMailboxManagerTest extends MailboxManagerTest<CassandraMai
             return new CassandraACLMapper(
                 new CassandraACLMapper.StoreV1(usersRightDAO, aclDAOV1),
                 new CassandraACLMapper.StoreV2(usersRightDAO, aclDAOv2, eventStore),
-                versionManager);
+                versionManager, CassandraConfiguration.DEFAULT_CONFIGURATION);
         }
 
         private CassandraUserMailboxRightsDAO rightsDAO(CassandraCluster cassandraCluster) {
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV2Test.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperNoACLTest.java
similarity index 55%
copy from mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV2Test.java
copy to mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperNoACLTest.java
index 16b6b2d33f..8cb14f70df 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV2Test.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperNoACLTest.java
@@ -18,18 +18,17 @@
  ****************************************************************/
 package org.apache.james.mailbox.cassandra.mail;
 
-import static org.apache.james.backends.cassandra.Scenario.Builder.awaitOn;
+import static org.apache.james.mailbox.cassandra.mail.CassandraACLMapperContract.MAILBOX_ID;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
+import java.util.Optional;
 
+import org.apache.commons.lang3.NotImplementedException;
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
-import org.apache.james.backends.cassandra.Scenario.Barrier;
+import org.apache.james.backends.cassandra.StatementRecorder;
 import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.backends.cassandra.init.configuration.CassandraConfiguration;
 import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionDAO;
@@ -47,7 +46,7 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-class CassandraACLMapperV2Test extends CassandraACLMapperContract {
+class CassandraACLMapperNoACLTest {
     @RegisterExtension
     static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(
         CassandraModule.aggregateModules(CassandraAclModule.MODULE, CassandraSchemaVersionModule.MODULE, CassandraEventStoreModule.MODULE()));
@@ -58,7 +57,7 @@ class CassandraACLMapperV2Test extends CassandraACLMapperContract {
     void setUp(CassandraCluster cassandra) {
         CassandraSchemaVersionDAO schemaVersionDAO = new CassandraSchemaVersionDAO(cassandra.getConf());
         schemaVersionDAO.truncateVersion().block();
-        schemaVersionDAO.updateVersion(new SchemaVersion(10)).block();
+        schemaVersionDAO.updateVersion(new SchemaVersion(9)).block();
         CassandraSchemaVersionManager versionManager = new CassandraSchemaVersionManager(schemaVersionDAO);
         CassandraACLDAOV1 aclDAOV1 = new CassandraACLDAOV1(cassandra.getConf(), CassandraConfiguration.DEFAULT_CONFIGURATION);
         CassandraACLDAOV2 aclDAOv2 = new CassandraACLDAOV2(cassandra.getConf());
@@ -70,77 +69,42 @@ class CassandraACLMapperV2Test extends CassandraACLMapperContract {
         cassandraACLMapper = new CassandraACLMapper(
             new CassandraACLMapper.StoreV1(usersRightDAO, aclDAOV1),
             new CassandraACLMapper.StoreV2(usersRightDAO, aclDAOv2, eventStore),
-            versionManager);
+            versionManager, CassandraConfiguration.builder()
+                .aclEnabled(Optional.of(false))
+                .build());
     }
 
-    @Override
-    CassandraACLMapper cassandraACLMapper() {
-        return cassandraACLMapper;
+    @Test
+    void getACLShouldReturnEmpty() {
+        assertThat(cassandraACLMapper.getACL(MAILBOX_ID).block()).isEqualTo(MailboxACL.EMPTY);
     }
 
     @Test
-    void twoConcurrentUpdatesWhenNoACLStoredShouldReturnACLWithTwoEntries(CassandraCluster cassandra) throws Exception {
-        Barrier barrier = new Barrier(2);
-        cassandra.getConf()
-            .registerScenario(awaitOn(barrier)
-                .thenExecuteNormally()
-                .times(2)
-                .whenQueryStartsWith("SELECT event FROM eventstore WHERE aggregateid=:aggregateid"));
-
-        MailboxACL.EntryKey keyBob = new MailboxACL.EntryKey("bob", MailboxACL.NameType.user, false);
-        MailboxACL.Rfc4314Rights rights = new MailboxACL.Rfc4314Rights(MailboxACL.Right.Read);
-        MailboxACL.EntryKey keyAlice = new MailboxACL.EntryKey("alice", MailboxACL.NameType.user, false);
-        Future<Boolean> future1 = performACLUpdateInExecutor(executor, keyBob, rights);
-        Future<Boolean> future2 = performACLUpdateInExecutor(executor, keyAlice, rights);
-
-        barrier.awaitCaller();
-        barrier.releaseCaller();
+    void getACLShouldNotIssueCassandraQueries(CassandraCluster cassandra) {
+        StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
-        awaitAll(future1, future2);
+        cassandraACLMapper.getACL(MAILBOX_ID).block();
 
-        assertThat(cassandraACLMapper.getACL(MAILBOX_ID).block())
-            .isEqualTo(new MailboxACL().union(keyBob, rights).union(keyAlice, rights));
+        assertThat(statementRecorder.listExecutedStatements()).isEmpty();
     }
 
     @Test
-    void twoConcurrentUpdatesWhenStoredShouldReturnACLWithTwoEntries(CassandraCluster cassandra) throws Exception {
-        MailboxACL.EntryKey keyBenwa = new MailboxACL.EntryKey("benwa", MailboxACL.NameType.user, false);
-        MailboxACL.Rfc4314Rights rights = new MailboxACL.Rfc4314Rights(MailboxACL.Right.Read);
-        cassandraACLMapper.updateACL(MAILBOX_ID, MailboxACL.command().key(keyBenwa).rights(rights).asAddition()).block();
-
-        Barrier barrier = new Barrier(2);
-        cassandra.getConf()
-            .registerScenario(awaitOn(barrier)
-                .thenExecuteNormally()
-                .times(2)
-                .whenQueryStartsWith("SELECT event FROM eventstore WHERE aggregateid=:aggregateid"));
-
-        MailboxACL.EntryKey keyBob = new MailboxACL.EntryKey("bob", MailboxACL.NameType.user, false);
-        MailboxACL.EntryKey keyAlice = new MailboxACL.EntryKey("alice", MailboxACL.NameType.user, false);
-        Future<Boolean> future1 = performACLUpdateInExecutor(executor, keyBob, rights);
-        Future<Boolean> future2 = performACLUpdateInExecutor(executor, keyAlice, rights);
-
-        barrier.awaitCaller();
-        barrier.releaseCaller();
-
-        awaitAll(future1, future2);
-
-        assertThat(cassandraACLMapper.getACL(MAILBOX_ID).block())
-            .isEqualTo(new MailboxACL().union(keyBob, rights).union(keyAlice, rights).union(keyBenwa, rights));
+    void deleteShouldBeSupported() {
+        assertThatCode(() -> cassandraACLMapper.delete(MAILBOX_ID).block())
+            .doesNotThrowAnyException();
     }
 
-    private void awaitAll(Future<?>... futures) 
-            throws InterruptedException, ExecutionException, TimeoutException {
-        for (Future<?> future : futures) {
-            future.get(10L, TimeUnit.SECONDS);
-        }
+    @Test
+    void setACLShouldNotBeSupported() {
+        assertThatThrownBy(() -> cassandraACLMapper.setACL(MAILBOX_ID, MailboxACL.EMPTY).block())
+            .isInstanceOf(NotImplementedException.class);
     }
 
-    private Future<Boolean> performACLUpdateInExecutor(ExecutorService executor, MailboxACL.EntryKey key, MailboxACL.Rfc4314Rights rights) {
-        return executor.submit(() -> {
-            cassandraACLMapper.updateACL(MAILBOX_ID, MailboxACL.command().key(key).rights(rights).asAddition()).block();
-            return true;
-        });
+    @Test
+    void updateACLShouldNotBeSupported() {
+        MailboxACL.EntryKey keyBenwa = new MailboxACL.EntryKey("benwa", MailboxACL.NameType.user, false);
+        MailboxACL.Rfc4314Rights rights = new MailboxACL.Rfc4314Rights(MailboxACL.Right.Read);
+        assertThatThrownBy(() -> cassandraACLMapper.updateACL(MAILBOX_ID, MailboxACL.command().key(keyBenwa).rights(rights).asAddition()).block())
+            .isInstanceOf(NotImplementedException.class);
     }
-
 }
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV1Test.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV1Test.java
index 4861556560..45bb0bb52d 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV1Test.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV1Test.java
@@ -73,7 +73,7 @@ class CassandraACLMapperV1Test extends CassandraACLMapperContract {
         cassandraACLMapper = new CassandraACLMapper(
             new CassandraACLMapper.StoreV1(usersRightDAO, aclDAOV1),
             new CassandraACLMapper.StoreV2(usersRightDAO, aclDAOv2, eventStore),
-            versionManager);
+            versionManager, CassandraConfiguration.DEFAULT_CONFIGURATION);
     }
 
     @Override
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV2Test.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV2Test.java
index 16b6b2d33f..9ce65ec9d8 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV2Test.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV2Test.java
@@ -70,7 +70,7 @@ class CassandraACLMapperV2Test extends CassandraACLMapperContract {
         cassandraACLMapper = new CassandraACLMapper(
             new CassandraACLMapper.StoreV1(usersRightDAO, aclDAOV1),
             new CassandraACLMapper.StoreV2(usersRightDAO, aclDAOv2, eventStore),
-            versionManager);
+            versionManager, CassandraConfiguration.DEFAULT_CONFIGURATION);
     }
 
     @Override
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
index d8b3ee9810..f617f5d7d2 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
@@ -124,7 +124,7 @@ class CassandraMailboxMapperTest {
         CassandraACLMapper aclMapper = new CassandraACLMapper(
             new CassandraACLMapper.StoreV1(usersRightDAO, aclDAOV1),
             new CassandraACLMapper.StoreV2(usersRightDAO, aclDAOv2, eventStore),
-            versionManager);
+            versionManager, CassandraConfiguration.DEFAULT_CONFIGURATION);
         testee = new CassandraMailboxMapper(
             mailboxDAO,
             mailboxPathV3DAO,
diff --git a/server/apps/distributed-app/docs/modules/ROOT/pages/configure/cassandra.adoc b/server/apps/distributed-app/docs/modules/ROOT/pages/configure/cassandra.adoc
index 5cadd23c04..0f26f36efa 100644
--- a/server/apps/distributed-app/docs/modules/ROOT/pages/configure/cassandra.adoc
+++ b/server/apps/distributed-app/docs/modules/ROOT/pages/configure/cassandra.adoc
@@ -145,5 +145,11 @@ by turning it off. Reads performed as part of write transaction are also perform
 
 | mailrepository.strong.consistency
 | Optional. Boolean, defaults to true. Allows not to use lightweight transactions in CassandraMailRepository.
-| If disabled we implement an idempotent behaviour (duplicates are overridden, missing entries upon deletes are ignored).
+ If disabled we implement an idempotent behaviour (duplicates are overridden, missing entries upon deletes are ignored).
+
+| acl.enabled
+| Optional. Boolean, defaults to true. Allows disabling ACLs: if set to false, delegation will fail and users will only
+have access to the mailboxes they own. ACLs can represent a high volume of requests. If you do not propose mailbox sharing
+features to your users, you can consider disabling them in order to improve performance.
+
 |===
\ No newline at end of file
diff --git a/src/site/xdoc/server/config-cassandra.xml b/src/site/xdoc/server/config-cassandra.xml
index 8aa0dc4265..9909bd1d35 100644
--- a/src/site/xdoc/server/config-cassandra.xml
+++ b/src/site/xdoc/server/config-cassandra.xml
@@ -122,6 +122,10 @@
         <dt><strong>mailrepository.strong.consistency</strong></dt>
         <dd>Optional. Defaults to true. Allows not to use lightweight transactions in CassandraMailRepository.
             If disabled we implement an idempotent behaviour (duplicates are overridden, missing entries upon deletes are ignored).</dd>
+        <dt><strong>acl.enabled</strong></dt>
+        <dd>Optional. Boolean, defaults to true. Allows disabling ACLs: if set to false, delegation will fail and users will only
+            have access to the mailboxes they own. ACLs can represent a high volume of requests. If you do not propose mailbox sharing
+            features to your users, you can consider disabling them in order to improve performance.</dd>
       </dl>
 
 


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org


[james-project] 04/07: [PERF] Disable JMAP related listeners if JMAP is disabled

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 414bacdcc443bcacd59f779e4a6be47b4db344c9
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue May 2 10:17:36 2023 +0700

    [PERF] Disable JMAP related listeners if JMAP is disabled
    
     -> There are procedures to populate JMAP projections if need be
     -> JMAP listeners are expensive performance wise and there is no reason IMAP only
     users pays that price
---
 .../james/CassandraJamesServerConfiguration.java   | 27 +++++++++++++--
 .../org/apache/james/CassandraJamesServerMain.java | 13 +++++++-
 .../james/CassandraRabbitMQJamesConfiguration.java | 25 ++++++++++++--
 .../james/CassandraRabbitMQJamesServerMain.java    | 13 +++++++-
 .../org/apache/james/MemoryJamesConfiguration.java | 27 +++++++++++++--
 .../org/apache/james/MemoryJamesServerMain.java    | 13 +++++++-
 .../apache/james/jmap/draft/JMAPCommonModule.java  |  6 +---
 .../james/jmap/draft/JMAPListenerModule.java       | 38 ++++++++++++++++++++++
 .../org/apache/james/jmap/draft/JMAPModule.java    | 34 +++++++++----------
 9 files changed, 164 insertions(+), 32 deletions(-)

diff --git a/server/apps/cassandra-app/src/main/java/org/apache/james/CassandraJamesServerConfiguration.java b/server/apps/cassandra-app/src/main/java/org/apache/james/CassandraJamesServerConfiguration.java
index cad9040715..7d93448da5 100644
--- a/server/apps/cassandra-app/src/main/java/org/apache/james/CassandraJamesServerConfiguration.java
+++ b/server/apps/cassandra-app/src/main/java/org/apache/james/CassandraJamesServerConfiguration.java
@@ -20,12 +20,14 @@
 package org.apache.james;
 
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.util.Optional;
 
 import org.apache.commons.configuration2.ex.ConfigurationException;
 import org.apache.james.data.UsersRepositoryModuleChooser;
 import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.filesystem.api.JamesDirectoriesProvider;
+import org.apache.james.jmap.draft.JMAPModule;
 import org.apache.james.server.core.JamesServerResourceLoader;
 import org.apache.james.server.core.MissingArgumentException;
 import org.apache.james.server.core.configuration.Configuration;
@@ -52,6 +54,7 @@ public class CassandraJamesServerConfiguration implements Configuration {
         private Optional<BlobStoreConfiguration> blobStoreConfiguration;
         private Optional<UsersRepositoryModuleChooser.Implementation> usersRepositoryImplementation;
         private Optional<VaultConfiguration> vaultConfiguration;
+        private Optional<Boolean> jmapEnabled;
 
         private Builder() {
             rootDirectory = Optional.empty();
@@ -60,6 +63,7 @@ public class CassandraJamesServerConfiguration implements Configuration {
             usersRepositoryImplementation = Optional.empty();
             blobStoreConfiguration = Optional.empty();
             vaultConfiguration = Optional.empty();
+            jmapEnabled = Optional.empty();
         }
 
         public Builder workingDirectory(String path) {
@@ -138,7 +142,17 @@ public class CassandraJamesServerConfiguration implements Configuration {
                 }
             });
 
-            return new CassandraJamesServerConfiguration(configurationPath, directories, searchConfiguration, blobStoreConfiguration, usersRepositoryChoice, vaultConfiguration);
+            boolean jmapEnabled = this.jmapEnabled.orElseGet(() -> {
+                try {
+                    return JMAPModule.parseConfiguration(propertiesProvider).isEnabled();
+                } catch (FileNotFoundException e) {
+                    return false;
+                } catch (ConfigurationException e) {
+                    throw new RuntimeException(e);
+                }
+            });
+
+            return new CassandraJamesServerConfiguration(configurationPath, directories, searchConfiguration, blobStoreConfiguration, usersRepositoryChoice, vaultConfiguration, jmapEnabled);
         }
     }
 
@@ -152,14 +166,19 @@ public class CassandraJamesServerConfiguration implements Configuration {
     private final BlobStoreConfiguration blobStoreConfiguration;
     private final UsersRepositoryModuleChooser.Implementation usersRepositoryImplementation;
     private final VaultConfiguration vaultConfiguration;
+    private final boolean jmapEnabled;
 
-    private CassandraJamesServerConfiguration(ConfigurationPath configurationPath, JamesDirectoriesProvider directories, SearchConfiguration searchConfiguration, BlobStoreConfiguration blobStoreConfiguration, UsersRepositoryModuleChooser.Implementation usersRepositoryImplementation, VaultConfiguration vaultConfiguration) {
+    private CassandraJamesServerConfiguration(ConfigurationPath configurationPath, JamesDirectoriesProvider directories,
+                                              SearchConfiguration searchConfiguration, BlobStoreConfiguration blobStoreConfiguration,
+                                              UsersRepositoryModuleChooser.Implementation usersRepositoryImplementation,
+                                              VaultConfiguration vaultConfiguration, boolean jmapEnabled) {
         this.configurationPath = configurationPath;
         this.directories = directories;
         this.searchConfiguration = searchConfiguration;
         this.blobStoreConfiguration = blobStoreConfiguration;
         this.usersRepositoryImplementation = usersRepositoryImplementation;
         this.vaultConfiguration = vaultConfiguration;
+        this.jmapEnabled = jmapEnabled;
     }
 
     @Override
@@ -187,4 +206,8 @@ public class CassandraJamesServerConfiguration implements Configuration {
     public BlobStoreConfiguration getBlobStoreConfiguration() {
         return blobStoreConfiguration;
     }
+
+    public boolean isJmapEnabled() {
+        return jmapEnabled;
+    }
 }
diff --git a/server/apps/cassandra-app/src/main/java/org/apache/james/CassandraJamesServerMain.java b/server/apps/cassandra-app/src/main/java/org/apache/james/CassandraJamesServerMain.java
index 47906848d1..c0cf0d93ab 100644
--- a/server/apps/cassandra-app/src/main/java/org/apache/james/CassandraJamesServerMain.java
+++ b/server/apps/cassandra-app/src/main/java/org/apache/james/CassandraJamesServerMain.java
@@ -23,6 +23,7 @@ import java.util.Set;
 
 import org.apache.james.data.UsersRepositoryModuleChooser;
 import org.apache.james.eventsourcing.eventstore.cassandra.EventNestedTypes;
+import org.apache.james.jmap.draft.JMAPListenerModule;
 import org.apache.james.json.DTOModule;
 import org.apache.james.modules.BlobExportMechanismModule;
 import org.apache.james.modules.CassandraConsistencyTaskSerializationModule;
@@ -194,7 +195,8 @@ public class CassandraJamesServerMain implements JamesServerMain {
             .combineWith(SearchModuleChooser.chooseModules(configuration.searchConfiguration()))
             .combineWith(new UsersRepositoryModuleChooser(new CassandraUsersRepositoryModule())
                 .chooseModules(configuration.getUsersRepositoryImplementation()))
-            .combineWith(chooseDeletedMessageVault(configuration.getVaultConfiguration()));
+            .combineWith(chooseDeletedMessageVault(configuration.getVaultConfiguration()))
+            .combineWith(chooseJmapModule(configuration));
     }
 
     private static Module chooseDeletedMessageVault(VaultConfiguration vaultConfiguration) {
@@ -207,4 +209,13 @@ public class CassandraJamesServerMain implements JamesServerMain {
 
         };
     }
+
+    private static Module chooseJmapModule(CassandraJamesServerConfiguration configuration) {
+        if (configuration.isJmapEnabled()) {
+            return new JMAPListenerModule();
+        }
+        return binder -> {
+
+        };
+    }
 }
diff --git a/server/apps/distributed-app/src/main/java/org/apache/james/CassandraRabbitMQJamesConfiguration.java b/server/apps/distributed-app/src/main/java/org/apache/james/CassandraRabbitMQJamesConfiguration.java
index 3c5ccac9f4..2be534aaaf 100644
--- a/server/apps/distributed-app/src/main/java/org/apache/james/CassandraRabbitMQJamesConfiguration.java
+++ b/server/apps/distributed-app/src/main/java/org/apache/james/CassandraRabbitMQJamesConfiguration.java
@@ -20,12 +20,14 @@
 package org.apache.james;
 
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.util.Optional;
 
 import org.apache.commons.configuration2.ex.ConfigurationException;
 import org.apache.james.data.UsersRepositoryModuleChooser;
 import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.filesystem.api.JamesDirectoriesProvider;
+import org.apache.james.jmap.draft.JMAPModule;
 import org.apache.james.modules.blobstore.BlobStoreConfiguration;
 import org.apache.james.modules.queue.rabbitmq.MailQueueViewChoice;
 import org.apache.james.server.core.JamesServerResourceLoader;
@@ -47,6 +49,7 @@ public class CassandraRabbitMQJamesConfiguration implements Configuration {
         private Optional<MailQueueViewChoice> mailQueueViewChoice;
         private Optional<UsersRepositoryModuleChooser.Implementation> usersRepositoryImplementation;
         private Optional<VaultConfiguration> vaultConfiguration;
+        private Optional<Boolean> jmapEnabled;
 
         private Builder() {
             searchConfiguration = Optional.empty();
@@ -56,6 +59,7 @@ public class CassandraRabbitMQJamesConfiguration implements Configuration {
             usersRepositoryImplementation = Optional.empty();
             mailQueueViewChoice = Optional.empty();
             vaultConfiguration = Optional.empty();
+            jmapEnabled = Optional.empty();
         }
 
         public Builder workingDirectory(String path) {
@@ -142,13 +146,24 @@ public class CassandraRabbitMQJamesConfiguration implements Configuration {
                 }
             });
 
+            boolean jmapEnabled = this.jmapEnabled.orElseGet(() -> {
+                try {
+                    return JMAPModule.parseConfiguration(propertiesProvider).isEnabled();
+                } catch (FileNotFoundException e) {
+                    return false;
+                } catch (ConfigurationException e) {
+                    throw new RuntimeException(e);
+                }
+            });
+
             return new CassandraRabbitMQJamesConfiguration(
                 configurationPath,
                 directories,
                 blobStoreConfiguration,
                 searchConfiguration,
                 usersRepositoryChoice,
-                mailQueueViewChoice, vaultConfiguration);
+                mailQueueViewChoice, vaultConfiguration,
+                jmapEnabled);
         }
     }
 
@@ -163,8 +178,9 @@ public class CassandraRabbitMQJamesConfiguration implements Configuration {
     private final UsersRepositoryModuleChooser.Implementation usersRepositoryImplementation;
     private final MailQueueViewChoice mailQueueViewChoice;
     private final VaultConfiguration vaultConfiguration;
+    private final boolean jmapEnabled;
 
-    public CassandraRabbitMQJamesConfiguration(ConfigurationPath configurationPath, JamesDirectoriesProvider directories, BlobStoreConfiguration blobStoreConfiguration, SearchConfiguration searchConfiguration, UsersRepositoryModuleChooser.Implementation usersRepositoryImplementation, MailQueueViewChoice mailQueueViewChoice, VaultConfiguration vaultConfiguration) {
+    public CassandraRabbitMQJamesConfiguration(ConfigurationPath configurationPath, JamesDirectoriesProvider directories, BlobStoreConfiguration blobStoreConfiguration, SearchConfiguration searchConfiguration, UsersRepositoryModuleChooser.Implementation usersRepositoryImplementation, MailQueueViewChoice mailQueueViewChoice, VaultConfiguration vaultConfiguration, boolean jmapEnabled) {
         this.configurationPath = configurationPath;
         this.directories = directories;
         this.blobStoreConfiguration = blobStoreConfiguration;
@@ -172,6 +188,7 @@ public class CassandraRabbitMQJamesConfiguration implements Configuration {
         this.usersRepositoryImplementation = usersRepositoryImplementation;
         this.mailQueueViewChoice = mailQueueViewChoice;
         this.vaultConfiguration = vaultConfiguration;
+        this.jmapEnabled = jmapEnabled;
     }
 
     public MailQueueViewChoice getMailQueueViewChoice() {
@@ -203,4 +220,8 @@ public class CassandraRabbitMQJamesConfiguration implements Configuration {
     public VaultConfiguration getVaultConfiguration() {
         return vaultConfiguration;
     }
+
+    public boolean isJmapEnabled() {
+        return jmapEnabled;
+    }
 }
diff --git a/server/apps/distributed-app/src/main/java/org/apache/james/CassandraRabbitMQJamesServerMain.java b/server/apps/distributed-app/src/main/java/org/apache/james/CassandraRabbitMQJamesServerMain.java
index 703a75986c..e94f99be7d 100644
--- a/server/apps/distributed-app/src/main/java/org/apache/james/CassandraRabbitMQJamesServerMain.java
+++ b/server/apps/distributed-app/src/main/java/org/apache/james/CassandraRabbitMQJamesServerMain.java
@@ -23,6 +23,7 @@ import java.util.Set;
 
 import org.apache.james.data.UsersRepositoryModuleChooser;
 import org.apache.james.eventsourcing.eventstore.cassandra.EventNestedTypes;
+import org.apache.james.jmap.draft.JMAPListenerModule;
 import org.apache.james.json.DTO;
 import org.apache.james.json.DTOModule;
 import org.apache.james.modules.BlobExportMechanismModule;
@@ -200,7 +201,8 @@ public class CassandraRabbitMQJamesServerMain implements JamesServerMain {
             .combineWith(SearchModuleChooser.chooseModules(searchConfiguration))
             .combineWith(new UsersRepositoryModuleChooser(new CassandraUsersRepositoryModule())
                 .chooseModules(configuration.getUsersRepositoryImplementation()))
-            .combineWith(chooseDeletedMessageVault(configuration.getVaultConfiguration()));
+            .combineWith(chooseDeletedMessageVault(configuration.getVaultConfiguration()))
+            .combineWith(chooseJmapModule(configuration));
     }
 
     private static Module chooseDeletedMessageVault(VaultConfiguration vaultConfiguration) {
@@ -213,4 +215,13 @@ public class CassandraRabbitMQJamesServerMain implements JamesServerMain {
 
         };
     }
+
+    private static Module chooseJmapModule(CassandraRabbitMQJamesConfiguration configuration) {
+        if (configuration.isJmapEnabled()) {
+            return new JMAPListenerModule();
+        }
+        return binder -> {
+
+        };
+    }
 }
diff --git a/server/apps/memory-app/src/main/java/org/apache/james/MemoryJamesConfiguration.java b/server/apps/memory-app/src/main/java/org/apache/james/MemoryJamesConfiguration.java
index b8b34298ec..530df09e2b 100644
--- a/server/apps/memory-app/src/main/java/org/apache/james/MemoryJamesConfiguration.java
+++ b/server/apps/memory-app/src/main/java/org/apache/james/MemoryJamesConfiguration.java
@@ -20,27 +20,33 @@
 package org.apache.james;
 
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.util.Optional;
 
+import org.apache.commons.configuration2.ex.ConfigurationException;
 import org.apache.james.data.UsersRepositoryModuleChooser;
 import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.filesystem.api.JamesDirectoriesProvider;
+import org.apache.james.jmap.draft.JMAPModule;
 import org.apache.james.server.core.JamesServerResourceLoader;
 import org.apache.james.server.core.MissingArgumentException;
 import org.apache.james.server.core.configuration.Configuration;
 import org.apache.james.server.core.configuration.FileConfigurationProvider;
 import org.apache.james.server.core.filesystem.FileSystemImpl;
+import org.apache.james.utils.PropertiesProvider;
 
 public class MemoryJamesConfiguration implements Configuration {
     public static class Builder {
         private Optional<String> rootDirectory;
         private Optional<ConfigurationPath> configurationPath;
         private Optional<UsersRepositoryModuleChooser.Implementation> usersRepositoryImplementation;
+        private Optional<Boolean> jmapEnabled;
 
         private Builder() {
             rootDirectory = Optional.empty();
             configurationPath = Optional.empty();
             usersRepositoryImplementation = Optional.empty();
+            jmapEnabled = Optional.empty();
         }
 
         public Builder workingDirectory(String path) {
@@ -90,10 +96,21 @@ public class MemoryJamesConfiguration implements Configuration {
             UsersRepositoryModuleChooser.Implementation usersRepositoryChoice = usersRepositoryImplementation.orElseGet(
                 () -> UsersRepositoryModuleChooser.Implementation.parse(configurationProvider));
 
+            boolean jmapEnabled = this.jmapEnabled.orElseGet(() -> {
+                PropertiesProvider propertiesProvider = new PropertiesProvider(fileSystem, configurationPath);
+                try {
+                    return JMAPModule.parseConfiguration(propertiesProvider).isEnabled();
+                } catch (FileNotFoundException e) {
+                    return false;
+                } catch (ConfigurationException e) {
+                    throw new RuntimeException(e);
+                }
+            });
+
             return new MemoryJamesConfiguration(
                 configurationPath,
                 directories,
-                usersRepositoryChoice);
+                usersRepositoryChoice, jmapEnabled);
         }
     }
 
@@ -104,11 +121,13 @@ public class MemoryJamesConfiguration implements Configuration {
     private final ConfigurationPath configurationPath;
     private final JamesDirectoriesProvider directories;
     private final UsersRepositoryModuleChooser.Implementation usersRepositoryImplementation;
+    private final boolean jmapEnabled;
 
-    public MemoryJamesConfiguration(ConfigurationPath configurationPath, JamesDirectoriesProvider directories, UsersRepositoryModuleChooser.Implementation usersRepositoryImplementation) {
+    public MemoryJamesConfiguration(ConfigurationPath configurationPath, JamesDirectoriesProvider directories, UsersRepositoryModuleChooser.Implementation usersRepositoryImplementation, boolean jmapEnabled) {
         this.configurationPath = configurationPath;
         this.directories = directories;
         this.usersRepositoryImplementation = usersRepositoryImplementation;
+        this.jmapEnabled = jmapEnabled;
     }
 
     @Override
@@ -124,4 +143,8 @@ public class MemoryJamesConfiguration implements Configuration {
     public UsersRepositoryModuleChooser.Implementation getUsersRepositoryImplementation() {
         return usersRepositoryImplementation;
     }
+
+    public boolean isJmapEnabled() {
+        return jmapEnabled;
+    }
 }
diff --git a/server/apps/memory-app/src/main/java/org/apache/james/MemoryJamesServerMain.java b/server/apps/memory-app/src/main/java/org/apache/james/MemoryJamesServerMain.java
index b206505a58..c3a4ef8498 100644
--- a/server/apps/memory-app/src/main/java/org/apache/james/MemoryJamesServerMain.java
+++ b/server/apps/memory-app/src/main/java/org/apache/james/MemoryJamesServerMain.java
@@ -22,6 +22,7 @@ package org.apache.james;
 import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
 import org.apache.james.data.UsersRepositoryModuleChooser;
 import org.apache.james.jmap.api.identity.CustomIdentityDAO;
+import org.apache.james.jmap.draft.JMAPListenerModule;
 import org.apache.james.jmap.memory.identity.MemoryCustomIdentityDAO;
 import org.apache.james.jmap.memory.pushsubscription.MemoryPushSubscriptionModule;
 import org.apache.james.jwt.JwtConfiguration;
@@ -168,7 +169,17 @@ public class MemoryJamesServerMain implements JamesServerMain {
         return GuiceJamesServer.forConfiguration(configuration)
             .combineWith(IN_MEMORY_SERVER_AGGREGATE_MODULE)
             .combineWith(new UsersRepositoryModuleChooser(new MemoryUsersRepositoryModule())
-                .chooseModules(configuration.getUsersRepositoryImplementation()));
+                .chooseModules(configuration.getUsersRepositoryImplementation()))
+            .combineWith(chooseJmapModule(configuration));
+    }
+
+    private static Module chooseJmapModule(MemoryJamesConfiguration configuration) {
+        if (configuration.isJmapEnabled()) {
+            return new JMAPListenerModule();
+        }
+        return binder -> {
+
+        };
     }
 
 }
diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPCommonModule.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPCommonModule.java
index e43c402e34..db07f8f3e8 100644
--- a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPCommonModule.java
+++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPCommonModule.java
@@ -20,7 +20,6 @@ package org.apache.james.jmap.draft;
 
 import java.util.concurrent.TimeUnit;
 
-import org.apache.james.events.EventListener;
 import org.apache.james.jmap.api.access.AccessTokenRepository;
 import org.apache.james.jmap.draft.api.AccessTokenManager;
 import org.apache.james.jmap.draft.api.SimpleTokenFactory;
@@ -37,7 +36,6 @@ import org.apache.james.jmap.draft.model.message.view.MessageFullViewFactory;
 import org.apache.james.jmap.draft.model.message.view.MessageHeaderViewFactory;
 import org.apache.james.jmap.draft.model.message.view.MessageMetadataViewFactory;
 import org.apache.james.jmap.draft.send.MailSpool;
-import org.apache.james.jmap.event.ComputeMessageFastViewProjectionListener;
 import org.apache.james.lifecycle.api.ConfigurationSanitizer;
 import org.apache.james.lifecycle.api.StartUpCheck;
 import org.apache.james.util.date.DefaultZonedDateTimeProvider;
@@ -81,9 +79,7 @@ public class JMAPCommonModule extends AbstractModule {
         bindConstant().annotatedWith(Names.named(AccessTokenRepository.TOKEN_EXPIRATION_IN_MS)).to(DEFAULT_TOKEN_EXPIRATION_IN_MS);
         bind(AccessTokenManager.class).to(AccessTokenManagerImpl.class);
 
-        Multibinder.newSetBinder(binder(), EventListener.ReactiveGroupEventListener.class)
-            .addBinding()
-            .to(ComputeMessageFastViewProjectionListener.class);
+
 
         Multibinder.newSetBinder(binder(), StartUpCheck.class)
             .addBinding().to(JMAPConfigurationStartUpCheck.class);
diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPListenerModule.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPListenerModule.java
new file mode 100644
index 0000000000..7be302bfae
--- /dev/null
+++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPListenerModule.java
@@ -0,0 +1,38 @@
+/****************************************************************
+ * 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.                                           *
+ ****************************************************************/
+package org.apache.james.jmap.draft;
+
+import org.apache.james.events.EventListener;
+import org.apache.james.jmap.change.MailboxChangeListener;
+import org.apache.james.jmap.event.ComputeMessageFastViewProjectionListener;
+import org.apache.james.jmap.event.PropagateLookupRightListener;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.multibindings.Multibinder;
+
+public class JMAPListenerModule extends AbstractModule {
+    @Override
+    protected void configure() {
+        Multibinder.newSetBinder(binder(), EventListener.GroupEventListener.class).addBinding().to(PropagateLookupRightListener.class);
+        Multibinder.newSetBinder(binder(), EventListener.ReactiveGroupEventListener.class).addBinding().to(MailboxChangeListener.class);
+        Multibinder.newSetBinder(binder(), EventListener.ReactiveGroupEventListener.class)
+            .addBinding()
+            .to(ComputeMessageFastViewProjectionListener.class);
+    }
+}
diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPModule.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPModule.java
index 0844923902..2f43328ffe 100644
--- a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPModule.java
+++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPModule.java
@@ -31,12 +31,10 @@ import javax.inject.Named;
 import org.apache.commons.configuration2.Configuration;
 import org.apache.commons.configuration2.ex.ConfigurationException;
 import org.apache.commons.io.FileUtils;
-import org.apache.james.events.EventListener;
 import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.jmap.JMAPConfiguration;
 import org.apache.james.jmap.JMAPServer;
 import org.apache.james.jmap.Version;
-import org.apache.james.jmap.change.MailboxChangeListener;
 import org.apache.james.jmap.core.CapabilityFactory;
 import org.apache.james.jmap.core.CoreCapabilityFactory;
 import org.apache.james.jmap.core.DelegationCapabilityFactory$;
@@ -53,7 +51,6 @@ import org.apache.james.jmap.core.WebSocketCapabilityFactory$;
 import org.apache.james.jmap.draft.methods.RequestHandler;
 import org.apache.james.jmap.draft.send.PostDequeueDecoratorFactory;
 import org.apache.james.jmap.draft.utils.JsoupHtmlTextExtractor;
-import org.apache.james.jmap.event.PropagateLookupRightListener;
 import org.apache.james.jmap.mailet.filter.JMAPFiltering;
 import org.apache.james.jmap.rfc8621.RFC8621MethodsModule;
 import org.apache.james.jwt.JwtConfiguration;
@@ -137,9 +134,6 @@ public class JMAPModule extends AbstractModule {
 
         bind(MailQueueItemDecoratorFactory.class).to(PostDequeueDecoratorFactory.class).in(Scopes.SINGLETON);
 
-        Multibinder.newSetBinder(binder(), EventListener.GroupEventListener.class).addBinding().to(PropagateLookupRightListener.class);
-        Multibinder.newSetBinder(binder(), EventListener.ReactiveGroupEventListener.class).addBinding().to(MailboxChangeListener.class);
-
         Multibinder<Version> supportedVersions = Multibinder.newSetBinder(binder(), Version.class);
         supportedVersions.addBinding().toInstance(Version.DRAFT);
         supportedVersions.addBinding().toInstance(Version.RFC8621);
@@ -190,18 +184,7 @@ public class JMAPModule extends AbstractModule {
     @Singleton
     JMAPConfiguration provideConfiguration(PropertiesProvider propertiesProvider) throws ConfigurationException {
         try {
-            Configuration configuration = propertiesProvider.getConfiguration("jmap");
-            return JMAPConfiguration.builder()
-                .enabled(configuration.getBoolean("enabled", true))
-                .port(Port.of(configuration.getInt("jmap.port", DEFAULT_JMAP_PORT)))
-                .enableEmailQueryView(Optional.ofNullable(configuration.getBoolean("view.email.query.enabled", null)))
-                .userProvisioningEnabled(Optional.ofNullable(configuration.getBoolean("user.provisioning.enabled", null)))
-                .defaultVersion(Optional.ofNullable(configuration.getString("jmap.version.default", null))
-                    .map(Version::of))
-                .maximumSendSize(Optional.ofNullable(configuration.getString("email.send.max.size", null))
-                    .map(Throwing.function(Size::parse))
-                    .map(Size::asBytes))
-                .build();
+            return parseConfiguration(propertiesProvider);
         } catch (FileNotFoundException e) {
             LOGGER.warn("Could not find JMAP configuration file. JMAP server will not be enabled.");
             return JMAPConfiguration.builder()
@@ -210,6 +193,21 @@ public class JMAPModule extends AbstractModule {
         }
     }
 
+    public static JMAPConfiguration parseConfiguration(PropertiesProvider propertiesProvider) throws FileNotFoundException, ConfigurationException {
+        Configuration configuration = propertiesProvider.getConfiguration("jmap");
+        return JMAPConfiguration.builder()
+            .enabled(configuration.getBoolean("enabled", true))
+            .port(Port.of(configuration.getInt("jmap.port", DEFAULT_JMAP_PORT)))
+            .enableEmailQueryView(Optional.ofNullable(configuration.getBoolean("view.email.query.enabled", null)))
+            .userProvisioningEnabled(Optional.ofNullable(configuration.getBoolean("user.provisioning.enabled", null)))
+            .defaultVersion(Optional.ofNullable(configuration.getString("jmap.version.default", null))
+                .map(Version::of))
+            .maximumSendSize(Optional.ofNullable(configuration.getString("email.send.max.size", null))
+                .map(Throwing.function(Size::parse))
+                .map(Size::asBytes))
+            .build();
+    }
+
     @Provides
     @Singleton
     JMAPDraftConfiguration provideDraftConfiguration(PropertiesProvider propertiesProvider, FileSystem fileSystem) throws ConfigurationException, IOException {


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org


[james-project] 05/07: [DOCUMENTATION] Performance checklist

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 0b26b27df158dfd961b6d66966afad63005c701d
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue May 2 11:26:22 2023 +0700

    [DOCUMENTATION] Performance checklist
---
 .../distributed-app/docs/modules/ROOT/nav.adoc     |   1 +
 .../docs/modules/ROOT/pages/operate/index.adoc     |   2 +-
 .../ROOT/pages/operate/performanceChecklist.adoc   | 164 +++++++++++++++++++++
 3 files changed, 166 insertions(+), 1 deletion(-)

diff --git a/server/apps/distributed-app/docs/modules/ROOT/nav.adoc b/server/apps/distributed-app/docs/modules/ROOT/nav.adoc
index 14b3a379f2..d415d64d67 100644
--- a/server/apps/distributed-app/docs/modules/ROOT/nav.adoc
+++ b/server/apps/distributed-app/docs/modules/ROOT/nav.adoc
@@ -52,6 +52,7 @@
 **** xref:configure/dsn.adoc[ESMTP DSN support]
 ** xref:operate/index.adoc[Operate]
 *** xref:operate/guide.adoc[]
+*** xref:operate/performanceChecklist.adoc[]
 *** xref:operate/logging.adoc[]
 *** xref:operate/webadmin.adoc[]
 *** xref:operate/metrics.adoc[]
diff --git a/server/apps/distributed-app/docs/modules/ROOT/pages/operate/index.adoc b/server/apps/distributed-app/docs/modules/ROOT/pages/operate/index.adoc
index 487cdc8100..e3d2816cd5 100644
--- a/server/apps/distributed-app/docs/modules/ROOT/pages/operate/index.adoc
+++ b/server/apps/distributed-app/docs/modules/ROOT/pages/operate/index.adoc
@@ -20,7 +20,7 @@ The xref:operate/metrics.adoc[metrics] allows to build latency and throughput
 graphs, that can be visualized, for instance in *Grafana*.
 
 We did put together a xref:operate/guide.adoc[detailed guide] for
-distributed James operators.
+distributed James operators. We also propose a xref:operate/performanceChecklist.adoc[performance checklist].
 
 We also included a guide for xref:operate/migrating.adoc[migrating existing data] into the distributed server.
 
diff --git a/server/apps/distributed-app/docs/modules/ROOT/pages/operate/performanceChecklist.adoc b/server/apps/distributed-app/docs/modules/ROOT/pages/operate/performanceChecklist.adoc
new file mode 100644
index 0000000000..b231880ae1
--- /dev/null
+++ b/server/apps/distributed-app/docs/modules/ROOT/pages/operate/performanceChecklist.adoc
@@ -0,0 +1,164 @@
+= Distributed James Server &mdash; Performance checklist
+:navtitle: Performance checklist
+
+This guide aims to help James operators refine their James configuration and set up to achieve better performance.
+
+== Database setup
+
+Cassandra, OpenSearch, RabbitMQ is a large topic in itself that we do not intend to cover here. Yet, here are some
+very basic recommendation that are always beneficial to keep in mind.
+
+We recommend:
+
+* Running Cassandra, OpenSearch on commodity hardware with attached SSD. SAN disks are known to cause performance
+issues for these technologies. HDD disks are to be banned for these performance related applications.
+* We recommend getting an Object Storage SaaS offering that suites your needs. Most generalist S3 offers will suite
+James needs.
+* We do provide a guide on xref:[Database benchmarks] that can help identify and fix issues.
+
+== James configuration
+
+=== Cassandra
+
+People tunning for performance would likely accept relaxing their consistency needs. James allows doing this.
+
+**LightWeight Transactions (LWT)** can be disabled where they are not essential. This can be done within
+xref:[cassandra.properties]:
+
+....
+mailbox.read.strong.consistency=false
+message.read.strong.consistency=false
+message.write.strong.consistency.unsafe=false
+mailrepository.strong.consistency=false
+....
+
+Also, James allows for **Read repairs** where consistency checks are piggy backed on reads randomly. This of course
+comes at a performance cost as it generates extre reads, thus minimizing read repair probability can help improving
+performance. This can be done within
+xref:[cassandra.properties]:
+
+....
+mailbox.read.repair.chance=0.00
+mailbox.counters.read.repair.chance.max=0.000
+mailbox.counters.read.repair.chance.one.hundred=0.000
+....
+
+One can also avoid some Cassandra requests by disabling ACLs (meaning users will only access to the mailboxes they own,
+all mailbox-sharing features will thus not be achievable). This can be done within
+xref:[cassandra.properties]:
+
+....
+acl.enabled=false
+....
+
+Important settings in the `` file includes:
+
+* Throttling: if too low then the Cassandra cluster is under-utilized. If too high, request bursts can cause significant
+Cassandra overload.
+
+....
+  advanced.throttler {
+    class = org.apache.james.backends.cassandra.utils.LockLessConcurrencyLimitingRequestThrottler
+
+    max-queue-size = 10000
+
+    max-concurrent-requests = 192
+  }
+....
+
+=== Object storage
+
+We recommend the use of the blob store cache, which will be populated by email headers which shall be treated as metadata.
+
+`blob.properties`:
+
+....
+cache.enable=true
+cache.cassandra.ttl=1year
+cache.cassandra.timeout=100ms
+cache.sizeThresholdInBytes=16 KiB
+....
+
+=== RabbitMQ
+
+We recommend against the use of the CassandraMailQueueView, as browsing and advanced queue management features
+is unnecessary for Mail Delivery Agent and are not meaningful in the absence of delays.
+
+Similarly, we recommend turning off queue size metrics, which are expensive to compute.
+
+We also recommend against the use of publish confirms, which comes at a high performance price.
+
+In `rabbitmq.properties`:
+
+....
+cassandra.view.enabled=false
+
+mailqueue.size.metricsEnabled=false
+
+event.bus.publish.confirm.enabled=false
+mailqueue.publish.confirm.enabled=false
+....
+
+=== JMAP protocol
+
+If you are not using JMAP, disabling it will avoid you the cost of populating related projections and thus is recommended.
+Within `jmap.properties`:
+
+....
+enabled=false
+....
+
+We recommend turning on EmailQueryView as it enables resolution of mailbox listing against Cassandra, thus unlocking massive
+stability / performance gains. Within `jmap.properties`:
+
+....
+view.email.query.enabled=true
+....
+
+=== IMAP / SMTP
+
+We recommend against resolving client connection DNS names. This behaviour can be disabled via a system property within
+`jvm.properties`:
+
+....
+james.protocols.mdc.hostname=false
+....
+
+Concurrent IMAP request count is the critical setting. In `imapServer.xml`:
+
+....
+<concurrentRequests>200</concurrentRequests>
+<maxQueueSize>4096</maxQueueSize>
+....
+
+Other recommendation includes avoiding unecessary work upon IMAP IDLE, not starting dedicated BOSS threads:
+
+....
+<ignoreIDLEUponProcessing>false</ignoreIDLEUponProcessing>
+<bossWorkerCount>0</bossWorkerCount>
+....
+
+=== Other generic recommendations
+
+* Remove unneeded listeners / mailets
+* Reduce duplication of Matchers within mailetcontainer.xml
+* Limit usage of "DEBUG" loglevel. INFO should be more than decent in most cases.
+* While GC tunning is a science in itself, we had good results with G1GC and a low pause time:
+
+....
+-Xlog:gc*:file=/root/gc.log -XX:MaxGCPauseMillis=20 -XX:ParallelGCThreads=2
+....
+
+* We recommand tunning bach sizes: `batchsizes.properties`. This allows, limiting parallel S3 reads, while loading many
+messages concurrently on Cassandra, and improves IMAP massive operations support.
+
+....
+fetch.metadata=200
+fetch.headers=30
+fetch.body=30
+fetch.full=30
+
+copy=8192
+
+move=8192
+....
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org


[james-project] 01/07: [REFACTORING] More fluent Cassandra statement recording

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 527eeec9281bf0cf2507de57371c3244412f0cf9
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue May 2 09:28:48 2023 +0700

    [REFACTORING] More fluent Cassandra statement recording
---
 .../backends/cassandra/StatementRecorder.java      |  2 +-
 .../james/backends/cassandra/TestingSession.java   |  4 ++-
 .../backends/cassandra/TestingSessionTest.java     |  9 +++----
 .../CassandraMessageIdManagerSideEffectTest.java   |  3 +--
 .../mail/CassandraIndexTableHandlerTest.java       |  3 +--
 .../mail/CassandraMessageIdMapperTest.java         |  3 +--
 .../cassandra/mail/CassandraMessageMapperTest.java | 27 +++++++------------
 .../quota/CassandraPerUserMaxQuotaManagerTest.java |  3 +--
 .../cassandra/CassandraListingTest.java            |  9 +++----
 .../org/apache/james/CassandraCacheQueryTest.java  |  3 +--
 .../blob/cassandra/cache/CachedBlobStoreTest.java  |  3 +--
 .../modules/mailbox/CassandraMailboxModule.java    |  6 +++--
 .../domainlist/cassandra/CacheDomainListTest.java  |  6 ++---
 .../jmap/rfc8621/distributed/ReadLevelTest.java    | 30 +++++++++-------------
 14 files changed, 44 insertions(+), 67 deletions(-)

diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/StatementRecorder.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/StatementRecorder.java
index 412bc15162..99a0d59908 100644
--- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/StatementRecorder.java
+++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/StatementRecorder.java
@@ -54,7 +54,7 @@ public class StatementRecorder {
 
     private final ConcurrentLinkedDeque statements;
 
-    public StatementRecorder() {
+    StatementRecorder() {
         statements = new ConcurrentLinkedDeque();
     }
 
diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/TestingSession.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/TestingSession.java
index 40cfa5404f..226c60ae5c 100644
--- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/TestingSession.java
+++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/TestingSession.java
@@ -84,8 +84,10 @@ public class TestingSession implements CqlSession {
         this.scenario = Scenario.combine(hooks);
     }
 
-    public void recordStatements(StatementRecorder statementRecorder) {
+    public StatementRecorder recordStatements() {
+        StatementRecorder statementRecorder = new StatementRecorder();
         this.statementRecorder = Optional.of(statementRecorder);
+        return statementRecorder;
     }
 
     public void stopRecordingStatements() {
diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/TestingSessionTest.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/TestingSessionTest.java
index 7ba95d0395..537051313a 100644
--- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/TestingSessionTest.java
+++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/TestingSessionTest.java
@@ -94,8 +94,7 @@ class TestingSessionTest {
 
     @Test
     void recordStatementsShouldKeepTraceOfExecutedStatement(CassandraCluster cassandra) {
-        StatementRecorder statementRecorder = new StatementRecorder();
-        cassandra.getConf().recordStatements(statementRecorder);
+        StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
         dao.getCurrentSchemaVersion().block();
 
@@ -106,8 +105,7 @@ class TestingSessionTest {
 
     @Test
     void recordStatementsShouldKeepTraceOfExecutedStatements(CassandraCluster cassandra) {
-        StatementRecorder statementRecorder = new StatementRecorder();
-        cassandra.getConf().recordStatements(statementRecorder);
+        StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
         dao.updateVersion(new SchemaVersion(36)).block();
         dao.getCurrentSchemaVersion().block();
@@ -123,8 +121,7 @@ class TestingSessionTest {
     void recordStatementsShouldNotKeepTraceOfExecutedStatementsBeforeRecording(CassandraCluster cassandra) {
         dao.getCurrentSchemaVersion().block();
 
-        StatementRecorder statementRecorder = new StatementRecorder();
-        cassandra.getConf().recordStatements(statementRecorder);
+        StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
         assertThat(statementRecorder.listExecutedStatements())
             .isEmpty();
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerSideEffectTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerSideEffectTest.java
index f42072662f..53a30ed462 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerSideEffectTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerSideEffectTest.java
@@ -59,8 +59,7 @@ class CassandraMessageIdManagerSideEffectTest extends AbstractMessageIdManagerSi
         givenUnlimitedQuota();
         MessageId messageId = testingData.persist(mailbox2.getMailboxId(), messageUid1, FLAGS, session);
 
-        StatementRecorder statementRecorder = new StatementRecorder();
-        cassandra.getConf().recordStatements(statementRecorder);
+        StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId()), session);
 
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandlerTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandlerTest.java
index 9ce0044338..bced64eb7f 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandlerTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandlerTest.java
@@ -139,8 +139,7 @@ class CassandraIndexTableHandlerTest {
                 .times(1)
                 .whenQueryStartsWith("UPDATE mailboxcounters SET count=count+1, unseen=unseen+1 WHERE mailboxid=:mailboxid"));
 
-            StatementRecorder statementRecorder = new StatementRecorder();
-            cassandra.getConf().recordStatements(statementRecorder);
+            StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
             testee.updateIndexOnAdd(message, MAILBOX_ID)
                 .block();
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdMapperTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdMapperTest.java
index f493c188d3..2c1cb4f8eb 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdMapperTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdMapperTest.java
@@ -129,8 +129,7 @@ class CassandraMessageIdMapperTest extends MessageIdMapperTest {
 
         saveMessages();
 
-        StatementRecorder statementRecorder = new StatementRecorder();
-        cassandra.getConf().recordStatements(statementRecorder);
+        StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
         mapperFactory.getMessageIdMapper(MAILBOX_SESSION).setFlags(message1.getMessageId(),
             ImmutableList.of(message1.getMailboxId()),
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapperTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapperTest.java
index e6bc711bdf..2cf24fbbfc 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapperTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapperTest.java
@@ -107,8 +107,7 @@ class CassandraMessageMapperTest extends MessageMapperTest {
                 // expected
             }
 
-            StatementRecorder statementRecorder = new StatementRecorder();
-            cassandra.getConf().recordStatements(statementRecorder);
+            StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
             FlagsUpdateCalculator markAsRead = new FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), MessageManager.FlagsUpdateMode.ADD);
             messageMapper.updateFlags(benwaInboxMailbox, markAsRead, MessageRange.all());
@@ -122,8 +121,7 @@ class CassandraMessageMapperTest extends MessageMapperTest {
         void deleteMessagesShouldGroupMessageReads(CassandraCluster cassandra) throws MailboxException {
             saveMessages();
 
-            StatementRecorder statementRecorder = new StatementRecorder();
-            cassandra.getConf().recordStatements(statementRecorder);
+            StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
             messageMapper.deleteMessages(benwaInboxMailbox, ImmutableList.of(message1.getUid(), message2.getUid(), message3.getUid()));
 
@@ -136,8 +134,7 @@ class CassandraMessageMapperTest extends MessageMapperTest {
         void deleteMessagesShouldGroupCounterUpdates(CassandraCluster cassandra) throws MailboxException {
             saveMessages();
 
-            StatementRecorder statementRecorder = new StatementRecorder();
-            cassandra.getConf().recordStatements(statementRecorder);
+            StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
             messageMapper.deleteMessages(benwaInboxMailbox, ImmutableList.of(message1.getUid(), message2.getUid(), message3.getUid()));
 
@@ -150,8 +147,7 @@ class CassandraMessageMapperTest extends MessageMapperTest {
         void deleteMessagesShouldNotDeleteMessageNotMarkedAsDeletedInDeletedProjection(CassandraCluster cassandra) throws MailboxException {
             saveMessages();
 
-            StatementRecorder statementRecorder = new StatementRecorder();
-            cassandra.getConf().recordStatements(statementRecorder);
+            StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
             messageMapper.deleteMessages(benwaInboxMailbox, ImmutableList.of(message1.getUid(), message2.getUid(), message3.getUid()));
 
@@ -164,8 +160,7 @@ class CassandraMessageMapperTest extends MessageMapperTest {
         void deleteMessagesShouldNotDeleteMessageNotMarkedAsRecentInRecentProjection(CassandraCluster cassandra) throws MailboxException {
             saveMessages();
 
-            StatementRecorder statementRecorder = new StatementRecorder();
-            cassandra.getConf().recordStatements(statementRecorder);
+            StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
             messageMapper.deleteMessages(benwaInboxMailbox, ImmutableList.of(message1.getUid(), message2.getUid(), message3.getUid()));
 
@@ -180,8 +175,7 @@ class CassandraMessageMapperTest extends MessageMapperTest {
             FlagsUpdateCalculator markAsRead = new FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), MessageManager.FlagsUpdateMode.ADD);
             messageMapper.updateFlags(benwaInboxMailbox, markAsRead, MessageRange.all());
 
-            StatementRecorder statementRecorder = new StatementRecorder();
-            cassandra.getConf().recordStatements(statementRecorder);
+            StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
             messageMapper.deleteMessages(benwaInboxMailbox, ImmutableList.of(message1.getUid(), message2.getUid(), message3.getUid()));
 
@@ -194,8 +188,7 @@ class CassandraMessageMapperTest extends MessageMapperTest {
         void updateFlagsShouldUpdateMailboxCountersOnce(CassandraCluster cassandra) throws MailboxException {
             saveMessages();
 
-            StatementRecorder statementRecorder = new StatementRecorder();
-            cassandra.getConf().recordStatements(statementRecorder);
+            StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
             messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), MessageManager.FlagsUpdateMode.REPLACE), MessageRange.all());
 
@@ -209,8 +202,7 @@ class CassandraMessageMapperTest extends MessageMapperTest {
         void findInMailboxLimitShouldLimitProjectionReadCassandraQueries(CassandraCluster cassandra) throws MailboxException {
             saveMessages();
 
-            StatementRecorder statementRecorder = new StatementRecorder();
-            cassandra.getConf().recordStatements(statementRecorder);
+            StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
             int limit = 2;
             consume(messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.all(), FetchType.FULL, limit));
@@ -225,8 +217,7 @@ class CassandraMessageMapperTest extends MessageMapperTest {
         void updateFlagsShouldLimitModSeqAllocation(CassandraCluster cassandra) throws MailboxException {
             saveMessages();
 
-            StatementRecorder statementRecorder = new StatementRecorder();
-            cassandra.getConf().recordStatements(statementRecorder);
+            StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
             messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.ANSWERED), MessageManager.FlagsUpdateMode.REPLACE), MessageRange.all());
 
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManagerTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManagerTest.java
index d678b014e4..140ac4a522 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManagerTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManagerTest.java
@@ -48,8 +48,7 @@ class CassandraPerUserMaxQuotaManagerTest extends GenericMaxQuotaManagerTest {
 
     @Test
     void quotaDetailsShouldGroupStatements(CassandraCluster cassandra) {
-        StatementRecorder statementRecorder = new StatementRecorder();
-        cassandra.getConf().recordStatements(statementRecorder);
+        StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
         maxQuotaManager.quotaDetails(QUOTA_ROOT);
 
diff --git a/mpt/impl/imap-mailbox/cassandra/src/test/java/org/apache/james/mpt/imapmailbox/cassandra/CassandraListingTest.java b/mpt/impl/imap-mailbox/cassandra/src/test/java/org/apache/james/mpt/imapmailbox/cassandra/CassandraListingTest.java
index 4284d14b58..baeca2f41d 100644
--- a/mpt/impl/imap-mailbox/cassandra/src/test/java/org/apache/james/mpt/imapmailbox/cassandra/CassandraListingTest.java
+++ b/mpt/impl/imap-mailbox/cassandra/src/test/java/org/apache/james/mpt/imapmailbox/cassandra/CassandraListingTest.java
@@ -31,7 +31,7 @@ import org.apache.james.mpt.imapmailbox.suite.Listing;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class CassandraListingTest extends Listing {
+class CassandraListingTest extends Listing {
     @RegisterExtension
     static CassandraHostSystemExtension hostSystemExtension = new CassandraHostSystemExtension();
 
@@ -41,12 +41,11 @@ public class CassandraListingTest extends Listing {
     }
 
     @Test
-    public void listShouldNotReadCounters() throws Exception {
+    void listShouldNotReadCounters() throws Exception {
         CassandraHostSystem cassandraHostSystem = (CassandraHostSystem) this.system;
-        StatementRecorder statementRecorder = new StatementRecorder();
-        cassandraHostSystem.getCassandra()
+        StatementRecorder statementRecorder = cassandraHostSystem.getCassandra()
             .getConf()
-            .recordStatements(statementRecorder);
+            .recordStatements();
 
         simpleScriptedTestProtocol
             .withLocale(Locale.US)
diff --git a/server/apps/distributed-app/src/test/java/org/apache/james/CassandraCacheQueryTest.java b/server/apps/distributed-app/src/test/java/org/apache/james/CassandraCacheQueryTest.java
index f67644828f..b24511891a 100644
--- a/server/apps/distributed-app/src/test/java/org/apache/james/CassandraCacheQueryTest.java
+++ b/server/apps/distributed-app/src/test/java/org/apache/james/CassandraCacheQueryTest.java
@@ -117,7 +117,6 @@ class CassandraCacheQueryTest {
 
     @BeforeAll
     static void beforeEach(GuiceJamesServer server) throws Exception {
-        statementRecorder = new StatementRecorder();
         server.getProbe(DataProbeImpl.class).fluent()
             .addDomain(DOMAIN)
             .addUser(JAMES_USER, PASSWORD);
@@ -125,7 +124,7 @@ class CassandraCacheQueryTest {
         MailboxProbeImpl mailboxProbe = server.getProbe(MailboxProbeImpl.class);
         mailboxProbe.createMailbox("#private", JAMES_USER, DefaultMailboxes.INBOX);
 
-        server.getProbe(TestingSessionProbe.class).getTestingSession().recordStatements(statementRecorder);
+        statementRecorder = server.getProbe(TestingSessionProbe.class).getTestingSession().recordStatements();
 
         sendAMail(server);
         readAMail(server);
diff --git a/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/cache/CachedBlobStoreTest.java b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/cache/CachedBlobStoreTest.java
index c273a25316..d4ced32241 100644
--- a/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/cache/CachedBlobStoreTest.java
+++ b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/cache/CachedBlobStoreTest.java
@@ -370,8 +370,7 @@ public class CachedBlobStoreTest implements BlobStoreContract {
             .save(message)
             .block();
 
-        StatementRecorder statementRecorder = new StatementRecorder();
-        cassandra.getConf().recordStatements(statementRecorder);
+        StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
         mimeMessageStore.read(partsId).block();
 
diff --git a/server/container/guice/cassandra/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java b/server/container/guice/cassandra/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
index cd0a699521..174ed29b0b 100644
--- a/server/container/guice/cassandra/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
+++ b/server/container/guice/cassandra/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
@@ -27,6 +27,7 @@ import org.apache.james.adapter.mailbox.MailboxUsernameChangeTaskStep;
 import org.apache.james.adapter.mailbox.QuotaUsernameChangeTaskStep;
 import org.apache.james.adapter.mailbox.UserRepositoryAuthenticator;
 import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.backends.cassandra.init.configuration.CassandraConfiguration;
 import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionManager;
 import org.apache.james.blob.api.BlobReferenceSource;
 import org.apache.james.events.EventListener;
@@ -257,11 +258,12 @@ public class CassandraMailboxModule extends AbstractModule {
                                  CassandraUserMailboxRightsDAO userMailboxRightsDAO,
                                  CassandraACLDAOV2 cassandraACLDAOV2,
                                  CqlSession session,
-                                 CassandraSchemaVersionManager cassandraSchemaVersionManager) {
+                                 CassandraSchemaVersionManager cassandraSchemaVersionManager,
+                                 CassandraConfiguration cassandraConfiguration) {
         return new CassandraACLMapper(storeV1,
             new CassandraACLMapper.StoreV2(userMailboxRightsDAO, cassandraACLDAOV2,
                 new CassandraEventStore(new EventStoreDao(session, JsonEventSerializer.forModules(ACLModule.ACL_UPDATE).withoutNestedType()))),
-            cassandraSchemaVersionManager);
+            cassandraSchemaVersionManager, cassandraConfiguration);
     }
     
     @Singleton
diff --git a/server/data/data-cassandra/src/test/java/org/apache/james/domainlist/cassandra/CacheDomainListTest.java b/server/data/data-cassandra/src/test/java/org/apache/james/domainlist/cassandra/CacheDomainListTest.java
index 39585a42f1..08a9c21981 100644
--- a/server/data/data-cassandra/src/test/java/org/apache/james/domainlist/cassandra/CacheDomainListTest.java
+++ b/server/data/data-cassandra/src/test/java/org/apache/james/domainlist/cassandra/CacheDomainListTest.java
@@ -66,8 +66,7 @@ class CacheDomainListTest {
     void containsShouldBeCached(CassandraCluster cassandra) throws DomainListException {
         domainList.addDomain(DOMAIN_1);
 
-        StatementRecorder statementRecorder = new StatementRecorder();
-        cassandra.getConf().recordStatements(statementRecorder);
+        StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
         Flux.range(0, 10)
             .doOnNext(Throwing.consumer(i -> domainList.containsDomain(DOMAIN_1)))
@@ -82,8 +81,7 @@ class CacheDomainListTest {
     void cacheShouldBeRefreshedPeriodicallyUnderReadLoad(CassandraCluster cassandra) throws DomainListException {
         domainList.addDomain(DOMAIN_1);
 
-        StatementRecorder statementRecorder = new StatementRecorder();
-        cassandra.getConf().recordStatements(statementRecorder);
+        StatementRecorder statementRecorder = cassandra.getConf().recordStatements();
 
         Flux.range(0, 6)
             .delayElements(Duration.ofMillis(500))
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/ReadLevelTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/ReadLevelTest.java
index 6fb0301786..8752eb5897 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/ReadLevelTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/ReadLevelTest.java
@@ -142,10 +142,9 @@ class ReadLevelTest {
 
     @Test
     void gettingEmailMetadataShouldNotReadBlobs(GuiceJamesServer server) {
-        StatementRecorder statementRecorder = new StatementRecorder();
-        server.getProbe(TestingSessionProbe.class)
+        StatementRecorder statementRecorder = server.getProbe(TestingSessionProbe.class)
             .getTestingSession()
-            .recordStatements(statementRecorder);
+            .recordStatements();
 
         String request = "{" +
             "  \"using\": [\"urn:ietf:params:jmap:core\", \"urn:ietf:params:jmap:mail\"]," +
@@ -171,10 +170,9 @@ class ReadLevelTest {
 
     @Test
     void gettingEmailHeadersShouldReadBlobOnce(GuiceJamesServer server) {
-        StatementRecorder statementRecorder = new StatementRecorder();
-        server.getProbe(TestingSessionProbe.class)
+        StatementRecorder statementRecorder = server.getProbe(TestingSessionProbe.class)
             .getTestingSession()
-            .recordStatements(statementRecorder);
+            .recordStatements();
 
         String request = "{" +
             "  \"using\": [\"urn:ietf:params:jmap:core\", \"urn:ietf:params:jmap:mail\"]," +
@@ -202,10 +200,9 @@ class ReadLevelTest {
 
     @Test
     void gettingEmailFastViewShouldReadBlobOnce(GuiceJamesServer server) {
-        StatementRecorder statementRecorder = new StatementRecorder();
-        server.getProbe(TestingSessionProbe.class)
+        StatementRecorder statementRecorder = server.getProbe(TestingSessionProbe.class)
             .getTestingSession()
-            .recordStatements(statementRecorder);
+            .recordStatements();
 
         String request = "{" +
             "  \"using\": [\"urn:ietf:params:jmap:core\", \"urn:ietf:params:jmap:mail\"]," +
@@ -236,10 +233,9 @@ class ReadLevelTest {
     void gettingEmailFastViewShouldReadBlobTwiceUponCacheMisses(GuiceJamesServer server) {
         server.getProbe(JmapGuiceProbe.class).clearMessageFastViewProjection();
 
-        StatementRecorder statementRecorder = new StatementRecorder();
-        server.getProbe(TestingSessionProbe.class)
+        StatementRecorder statementRecorder = server.getProbe(TestingSessionProbe.class)
             .getTestingSession()
-            .recordStatements(statementRecorder);
+            .recordStatements();
 
         String request = "{" +
             "  \"using\": [\"urn:ietf:params:jmap:core\", \"urn:ietf:params:jmap:mail\"]," +
@@ -292,10 +288,9 @@ class ReadLevelTest {
             .then()
             .statusCode(SC_OK);
 
-        StatementRecorder statementRecorder = new StatementRecorder();
-        server.getProbe(TestingSessionProbe.class)
+        StatementRecorder statementRecorder = server.getProbe(TestingSessionProbe.class)
             .getTestingSession()
-            .recordStatements(statementRecorder);
+            .recordStatements();
         with()
             .header(HttpHeaderNames.ACCEPT.toString(), Fixture.ACCEPT_RFC8621_VERSION_HEADER())
             .body(request)
@@ -308,10 +303,9 @@ class ReadLevelTest {
 
     @Test
     void gettingEmailBodyShouldReadBlobTwice(GuiceJamesServer server) {
-        StatementRecorder statementRecorder = new StatementRecorder();
-        server.getProbe(TestingSessionProbe.class)
+        StatementRecorder statementRecorder = server.getProbe(TestingSessionProbe.class)
             .getTestingSession()
-            .recordStatements(statementRecorder);
+            .recordStatements();
 
         String request = "{" +
             "  \"using\": [\"urn:ietf:params:jmap:core\", \"urn:ietf:params:jmap:mail\"]," +


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org


[james-project] 02/07: [REFACTORING] Tiny improvements of CassandraConfiguration

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 5d908fd3857992cc449913f833fc63664f0618f5
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue May 2 11:24:56 2023 +0700

    [REFACTORING] Tiny improvements of CassandraConfiguration
---
 .../backends/cassandra/init/configuration/CassandraConfiguration.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/configuration/CassandraConfiguration.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/configuration/CassandraConfiguration.java
index 76c90968d6..a8f85d367d 100644
--- a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/configuration/CassandraConfiguration.java
+++ b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/configuration/CassandraConfiguration.java
@@ -28,6 +28,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.function.Predicate;
 
 import org.apache.commons.configuration2.Configuration;
+import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -36,9 +37,8 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
 public class CassandraConfiguration {
-    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(CassandraConfiguration.class);
+    private static final Logger LOGGER = LoggerFactory.getLogger(CassandraConfiguration.class);
 
-    public static final int DEFAULT_MESSAGE_CHUNK_SIZE_ON_READ = 100;
     public static final float DEFAULT_MAILBOX_READ_REPAIR = 0.1f;
     public static final float DEFAULT_MAX_MAILBOX_COUNTERS_READ_REPAIR_CHANCE = 0.1f;
     public static final float DEFAULT_ONE_HUNDRED_MAILBOX_COUNTERS_READ_REPAIR_CHANCE = 0.01f;


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org


[james-project] 06/07: [TEST] Reduce integration test boiler plate

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit b8cd273438a2bd3b98174a259e101251518f6a2b
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue May 9 18:09:02 2023 +0700

    [TEST] Reduce integration test boiler plate
---
 .../james/CassandraRabbitMQJamesConfiguration.java |  5 ++++
 .../org/apache/james/MemoryJamesConfiguration.java |  5 ++++
 .../java/org/apache/james/MemoryJmapTestRule.java  |  1 +
 .../james/jmap/memory/cucumber/MemoryStepdefs.java |  1 +
 .../cucumber/awss3/RabbitMQAwsS3Stepdefs.java      |  1 +
 ...gateSetMethodTest.java => DistributedBase.java} |  4 +--
 .../DistributedDelegateGetMethodTest.java          | 35 ++--------------------
 .../DistributedDelegateSetMethodTest.java          | 35 ++--------------------
 .../DistributedDelegatedAccountGetMethodTest.java  | 35 ++--------------------
 .../DistributedDelegatedAccountSetMethodTest.java  | 35 ++--------------------
 .../distributed/DistributedDownloadTest.java       | 32 +-------------------
 .../distributed/DistributedEchoMethodTest.java     | 33 +-------------------
 .../distributed/DistributedEmailGetMethodTest.java | 33 +-------------------
 .../DistributedEmailQueryMethodTest.java           | 33 +-------------------
 .../distributed/DistributedEmailSetMethodTest.java | 34 +--------------------
 .../DistributedEmailSubmissionSetMethodtest.java   | 33 +-------------------
 .../distributed/DistributedIdentityGetTest.java    | 35 ++--------------------
 .../distributed/DistributedIdentitySetTest.java    | 35 ++--------------------
 .../distributed/DistributedMDNParseMethodTest.java | 32 +-------------------
 .../distributed/DistributedMDNSendMethodTest.java  | 33 +-------------------
 .../DistributedMailboxGetMethodTest.java           | 32 +-------------------
 .../DistributedMailboxQueryMethodTest.java         | 32 +-------------------
 .../DistributedMailboxSetMethodTest.java           | 32 +-------------------
 .../distributed/DistributedProvisioningTest.java   | 32 ++------------------
 .../DistributedQuotaChangesMethodTest.java         | 31 +------------------
 .../distributed/DistributedQuotaGetMethodTest.java | 31 +------------------
 .../DistributedQuotaQueryMethodTest.java           | 31 +------------------
 .../distributed/DistributedSessionRouteTest.java   | 33 ++------------------
 .../rfc8621/distributed/DistributedUploadTest.java | 32 ++------------------
 .../DistributedVacationResponseGetMethodTest.java  | 32 ++------------------
 .../DistributedVacationResponseSetMethodTest.java  | 32 ++------------------
 .../distributed/DistributedWebPushTest.java        |  1 +
 .../distributed/DistributedWebSocketTest.java      | 33 ++------------------
 .../jmap/rfc8621/distributed/ReadLevelTest.java    |  1 +
 .../rfc8621/memory/MemoryBackReferenceTest.java    | 21 ++-----------
 .../james/jmap/rfc8621/memory/MemoryBase.java      | 26 ++++++++++++++++
 .../memory/MemoryDelegateGetMethodTest.java        | 22 ++------------
 .../memory/MemoryDelegateSetMethodTest.java        | 22 ++------------
 .../MemoryDelegatedAccountGetMethodTest.java       | 22 ++------------
 .../MemoryDelegatedAccountSetMethodTest.java       | 22 ++------------
 .../jmap/rfc8621/memory/MemoryDownloadTest.java    | 21 +------------
 .../jmap/rfc8621/memory/MemoryEchoMethodTest.java  | 21 ++-----------
 .../rfc8621/memory/MemoryEmailGetMethodTest.java   | 22 +-------------
 .../jmap/rfc8621/memory/MemoryEmailImportTest.java | 21 +------------
 .../rfc8621/memory/MemoryEmailQueryMethodTest.java | 21 +------------
 .../rfc8621/memory/MemoryEmailSetMethodTest.java   | 23 +-------------
 .../memory/MemoryEmailSubmissionSetMethodTest.java | 21 +------------
 .../jmap/rfc8621/memory/MemoryEventSourceTest.java | 22 ++------------
 .../memory/MemoryIdentityGetMethodTest.java        | 21 +------------
 .../memory/MemoryIdentitySetMethodTests.java       | 22 ++------------
 .../rfc8621/memory/MemoryMDNParseMethodTest.java   | 21 +------------
 .../rfc8621/memory/MemoryMDNSendMethodTest.java    | 21 +------------
 .../rfc8621/memory/MemoryMailboxGetMethodTest.java | 21 +------------
 .../memory/MemoryMailboxQueryMethodTest.java       | 21 ++-----------
 .../rfc8621/memory/MemoryMailboxSetMethodTest.java | 21 +------------
 .../rfc8621/memory/MemoryProvisioningTest.java     | 21 ++-----------
 .../memory/MemoryQuotaChangesMethodTest.java       | 20 +------------
 .../rfc8621/memory/MemoryQuotaGetMethodTest.java   | 20 +------------
 .../rfc8621/memory/MemoryQuotaQueryMethodTest.java | 20 +------------
 .../rfc8621/memory/MemorySessionRouteTest.java     | 21 ++-----------
 .../memory/MemoryThreadChangesMethodTest.java      | 21 ++-----------
 .../rfc8621/memory/MemoryThreadGetMethodTest.java  | 21 +------------
 .../jmap/rfc8621/memory/MemoryUploadTest.java      | 21 ++-----------
 .../MemoryVacationResponseGetMethodTest.java       | 21 ++-----------
 .../MemoryVacationResponseSetMethodTest.java       | 21 ++-----------
 .../jmap/rfc8621/memory/MemoryWebSocketTest.java   | 21 +------------
 66 files changed, 127 insertions(+), 1431 deletions(-)

diff --git a/server/apps/distributed-app/src/main/java/org/apache/james/CassandraRabbitMQJamesConfiguration.java b/server/apps/distributed-app/src/main/java/org/apache/james/CassandraRabbitMQJamesConfiguration.java
index 2be534aaaf..1f9913b770 100644
--- a/server/apps/distributed-app/src/main/java/org/apache/james/CassandraRabbitMQJamesConfiguration.java
+++ b/server/apps/distributed-app/src/main/java/org/apache/james/CassandraRabbitMQJamesConfiguration.java
@@ -115,6 +115,11 @@ public class CassandraRabbitMQJamesConfiguration implements Configuration {
             return this;
         }
 
+        public Builder enableJMAP() {
+            this.jmapEnabled = Optional.of(true);
+            return this;
+        }
+
         public CassandraRabbitMQJamesConfiguration build() {
             ConfigurationPath configurationPath = this.configurationPath.orElse(new ConfigurationPath(FileSystem.FILE_PROTOCOL_AND_CONF));
             JamesServerResourceLoader directories = new JamesServerResourceLoader(rootDirectory
diff --git a/server/apps/memory-app/src/main/java/org/apache/james/MemoryJamesConfiguration.java b/server/apps/memory-app/src/main/java/org/apache/james/MemoryJamesConfiguration.java
index 530df09e2b..d186b9504d 100644
--- a/server/apps/memory-app/src/main/java/org/apache/james/MemoryJamesConfiguration.java
+++ b/server/apps/memory-app/src/main/java/org/apache/james/MemoryJamesConfiguration.java
@@ -82,6 +82,11 @@ public class MemoryJamesConfiguration implements Configuration {
             return this;
         }
 
+        public Builder enableJMAP() {
+            this.jmapEnabled = Optional.of(true);
+            return this;
+        }
+
         public MemoryJamesConfiguration build() {
             ConfigurationPath configurationPath = this.configurationPath.orElse(new ConfigurationPath(FileSystem.FILE_PROTOCOL_AND_CONF));
             JamesServerResourceLoader directories = new JamesServerResourceLoader(rootDirectory
diff --git a/server/apps/memory-app/src/test/java/org/apache/james/MemoryJmapTestRule.java b/server/apps/memory-app/src/test/java/org/apache/james/MemoryJmapTestRule.java
index b58ee329c9..07d4cc3e71 100644
--- a/server/apps/memory-app/src/test/java/org/apache/james/MemoryJmapTestRule.java
+++ b/server/apps/memory-app/src/test/java/org/apache/james/MemoryJmapTestRule.java
@@ -37,6 +37,7 @@ public class MemoryJmapTestRule implements TestRule {
 
     public GuiceJamesServer jmapServer(Module... modules) throws IOException {
         MemoryJamesConfiguration configuration = MemoryJamesConfiguration.builder()
+            .enableJMAP()
             .workingDirectory(temporaryFolder.newFolder())
             .configurationFromClasspath()
             .usersRepository(DEFAULT)
diff --git a/server/protocols/jmap-draft-integration-testing/memory-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/memory/cucumber/MemoryStepdefs.java b/server/protocols/jmap-draft-integration-testing/memory-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/memory/cucumber/MemoryStepdefs.java
index e2e994e41a..623728808f 100644
--- a/server/protocols/jmap-draft-integration-testing/memory-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/memory/cucumber/MemoryStepdefs.java
+++ b/server/protocols/jmap-draft-integration-testing/memory-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/memory/cucumber/MemoryStepdefs.java
@@ -55,6 +55,7 @@ public class MemoryStepdefs {
     public void init() throws Exception {
         temporaryFolder.create();
         MemoryJamesConfiguration configuration = MemoryJamesConfiguration.builder()
+            .enableJMAP()
             .workingDirectory(temporaryFolder.newFolder())
             .configurationFromClasspath()
             .usersRepository(DEFAULT)
diff --git a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/cucumber/awss3/RabbitMQAwsS3Stepdefs.java b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/cucumber/awss3/RabbitMQAwsS3Stepdefs.java
index 5954e479c1..43f42b294f 100644
--- a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/cucumber/awss3/RabbitMQAwsS3Stepdefs.java
+++ b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/cucumber/awss3/RabbitMQAwsS3Stepdefs.java
@@ -74,6 +74,7 @@ public class RabbitMQAwsS3Stepdefs {
         temporaryFolder.create();
         mainStepdefs.messageIdFactory = new CassandraMessageId.Factory();
         CassandraRabbitMQJamesConfiguration configuration = CassandraRabbitMQJamesConfiguration.builder()
+            .enableJMAP()
             .workingDirectory(temporaryFolder.newFolder())
             .configurationFromClasspath()
             .blobStore(BlobStoreConfiguration.builder()
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegateSetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedBase.java
similarity index 95%
copy from server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegateSetMethodTest.java
copy to server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedBase.java
index 681da1bcbe..03a7df3053 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegateSetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedBase.java
@@ -26,7 +26,6 @@ import org.apache.james.DockerOpenSearchExtension;
 import org.apache.james.JamesServerBuilder;
 import org.apache.james.JamesServerExtension;
 import org.apache.james.SearchConfiguration;
-import org.apache.james.jmap.rfc8621.contract.DelegateSetContract;
 import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
 import org.apache.james.modules.AwsS3BlobStoreExtension;
 import org.apache.james.modules.RabbitMQExtension;
@@ -34,12 +33,13 @@ import org.apache.james.modules.TestJMAPServerModule;
 import org.apache.james.modules.blobstore.BlobStoreConfiguration;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedDelegateSetMethodTest implements DelegateSetContract {
+public class DistributedBase {
     @RegisterExtension
     static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
         CassandraRabbitMQJamesConfiguration.builder()
             .workingDirectory(tmpDir)
             .configurationFromClasspath()
+            .enableJMAP()
             .blobStore(BlobStoreConfiguration.builder()
                 .s3()
                 .disableCache()
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegateGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegateGetMethodTest.java
index af2279103f..0b74af09e2 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegateGetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegateGetMethodTest.java
@@ -19,39 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.SearchConfiguration;
 import org.apache.james.jmap.rfc8621.contract.DelegateGetMethodContract;
-import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedDelegateGetMethodTest implements DelegateGetMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .searchConfiguration(SearchConfiguration.openSearch())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
-        .build();
+public class DistributedDelegateGetMethodTest extends DistributedBase implements DelegateGetMethodContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegateSetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegateSetMethodTest.java
index 681da1bcbe..fb0ac95c6a 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegateSetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegateSetMethodTest.java
@@ -19,39 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.SearchConfiguration;
 import org.apache.james.jmap.rfc8621.contract.DelegateSetContract;
-import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedDelegateSetMethodTest implements DelegateSetContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .searchConfiguration(SearchConfiguration.openSearch())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
-        .build();
+public class DistributedDelegateSetMethodTest extends DistributedBase implements DelegateSetContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegatedAccountGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegatedAccountGetMethodTest.java
index c57e381db7..39eeb4ba66 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegatedAccountGetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegatedAccountGetMethodTest.java
@@ -19,39 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.SearchConfiguration;
 import org.apache.james.jmap.rfc8621.contract.DelegatedAccountGetMethodContract;
-import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedDelegatedAccountGetMethodTest implements DelegatedAccountGetMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .searchConfiguration(SearchConfiguration.openSearch())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
-        .build();
+public class DistributedDelegatedAccountGetMethodTest extends DistributedBase implements DelegatedAccountGetMethodContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegatedAccountSetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegatedAccountSetMethodTest.java
index caa9c36e6d..c6a7657157 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegatedAccountSetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDelegatedAccountSetMethodTest.java
@@ -19,39 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.SearchConfiguration;
 import org.apache.james.jmap.rfc8621.contract.DelegatedAccountSetContract;
-import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedDelegatedAccountSetMethodTest implements DelegatedAccountSetContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .searchConfiguration(SearchConfiguration.openSearch())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
-        .build();
+public class DistributedDelegatedAccountSetMethodTest extends DistributedBase implements DelegatedAccountSetContract {
+
 }
\ No newline at end of file
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDownloadTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDownloadTest.java
index e48c526d39..9515c70f6a 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDownloadTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedDownloadTest.java
@@ -19,45 +19,15 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.DownloadContract;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
 import com.datastax.oss.driver.api.core.uuid.Uuids;
 
-public class DistributedDownloadTest implements DownloadContract {
+public class DistributedDownloadTest extends DistributedBase implements DownloadContract {
     public static final CassandraMessageId.Factory MESSAGE_ID_FACTORY = new CassandraMessageId.Factory();
 
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
-
     @Override
     public MessageId randomMessageId() {
         return MESSAGE_ID_FACTORY.of(Uuids.timeBased());
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEchoMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEchoMethodTest.java
index 89786c0dc8..4f9a3d5ff3 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEchoMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEchoMethodTest.java
@@ -19,39 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.SearchConfiguration;
 import org.apache.james.jmap.rfc8621.contract.EchoMethodContract;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedEchoMethodTest implements EchoMethodContract {
+public class DistributedEchoMethodTest extends DistributedBase implements EchoMethodContract {
 
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                    .s3()
-                    .disableCache()
-                    .deduplication()
-                    .noCryptoConfig())
-            .searchConfiguration(SearchConfiguration.openSearch())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailGetMethodTest.java
index 9da6c601b9..b24bf9c689 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailGetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailGetMethodTest.java
@@ -19,46 +19,15 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.EmailGetMethodContract;
-import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
 import com.datastax.oss.driver.api.core.uuid.Uuids;
 
-public class DistributedEmailGetMethodTest implements EmailGetMethodContract {
+public class DistributedEmailGetMethodTest extends DistributedBase implements EmailGetMethodContract {
     public static final CassandraMessageId.Factory MESSAGE_ID_FACTORY = new CassandraMessageId.Factory();
 
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
-        .build();
-
     @Override
     public MessageId randomMessageId() {
         return MESSAGE_ID_FACTORY.of(Uuids.timeBased());
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailQueryMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailQueryMethodTest.java
index 7f59a9e8fd..59b9324e04 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailQueryMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailQueryMethodTest.java
@@ -19,40 +19,9 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
 import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.SearchConfiguration;
 import org.apache.james.jmap.rfc8621.contract.EmailQueryMethodContract;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedEmailQueryMethodTest implements EmailQueryMethodContract {
+public class DistributedEmailQueryMethodTest extends DistributedBase implements EmailQueryMethodContract {
     public static final DockerOpenSearchExtension ELASTIC_SEARCH_EXTENSION = new DockerOpenSearchExtension();
-
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                    .s3()
-                    .disableCache()
-                    .deduplication()
-                    .noCryptoConfig())
-            .searchConfiguration(SearchConfiguration.openSearch())
-            .build())
-        .extension(ELASTIC_SEARCH_EXTENSION)
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailSetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailSetMethodTest.java
index 5c37b4bd45..193ab7e37a 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailSetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailSetMethodTest.java
@@ -19,50 +19,18 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
 import org.apache.james.GuiceJamesServer;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.EmailSetMethodContract;
-import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
 import com.datastax.oss.driver.api.core.uuid.Uuids;
 
-public class DistributedEmailSetMethodTest implements EmailSetMethodContract {
-    public static final DockerOpenSearchExtension ELASTIC_SEARCH_EXTENSION = new DockerOpenSearchExtension();
+public class DistributedEmailSetMethodTest extends DistributedBase implements EmailSetMethodContract {
     public static final CassandraMessageId.Factory MESSAGE_ID_FACTORY = new CassandraMessageId.Factory();
 
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .build())
-        .extension(ELASTIC_SEARCH_EXTENSION)
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
-        .build();
-
     @Override
     public MessageId randomMessageId() {
         return MESSAGE_ID_FACTORY.of(Uuids.timeBased());
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailSubmissionSetMethodtest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailSubmissionSetMethodtest.java
index 606ac4e179..6f0f8ca27c 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailSubmissionSetMethodtest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailSubmissionSetMethodtest.java
@@ -19,46 +19,15 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.EmailSubmissionSetMethodContract;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
 import com.datastax.oss.driver.api.core.uuid.Uuids;
 
-class DistributedEmailSubmissionSetMethodtest implements EmailSubmissionSetMethodContract {
-    public static final DockerOpenSearchExtension ELASTIC_SEARCH_EXTENSION = new DockerOpenSearchExtension();
+class DistributedEmailSubmissionSetMethodtest extends DistributedBase implements EmailSubmissionSetMethodContract {
     public static final CassandraMessageId.Factory MESSAGE_ID_FACTORY = new CassandraMessageId.Factory();
 
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .build())
-        .extension(ELASTIC_SEARCH_EXTENSION)
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
-
     @Override
     public MessageId randomMessageId() {
         return MESSAGE_ID_FACTORY.of(Uuids.timeBased());
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedIdentityGetTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedIdentityGetTest.java
index a8ce325c31..660f96c4b4 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedIdentityGetTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedIdentityGetTest.java
@@ -19,39 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.SearchConfiguration;
 import org.apache.james.jmap.rfc8621.contract.IdentityGetContract;
-import org.apache.james.jmap.rfc8621.contract.IdentityProbeModule;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-class DistributedIdentityGetTest implements IdentityGetContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                    .s3()
-                    .disableCache()
-                    .deduplication()
-                    .noCryptoConfig())
-            .searchConfiguration(SearchConfiguration.openSearch())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new IdentityProbeModule()))
-        .build();
+class DistributedIdentityGetTest extends DistributedBase implements IdentityGetContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedIdentitySetTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedIdentitySetTest.java
index 7c967365b7..bcde6ba22a 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedIdentitySetTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedIdentitySetTest.java
@@ -19,39 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.SearchConfiguration;
-import org.apache.james.jmap.rfc8621.contract.IdentityProbeModule;
 import org.apache.james.jmap.rfc8621.contract.IdentitySetContract;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedIdentitySetTest implements IdentitySetContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .searchConfiguration(SearchConfiguration.openSearch())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new IdentityProbeModule()))
-        .build();
+public class DistributedIdentitySetTest extends DistributedBase implements IdentitySetContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMDNParseMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMDNParseMethodTest.java
index d53caf2204..ebf4e9632f 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMDNParseMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMDNParseMethodTest.java
@@ -19,45 +19,15 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.MDNParseMethodContract;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
 import com.datastax.oss.driver.api.core.uuid.Uuids;
 
-public class DistributedMDNParseMethodTest implements MDNParseMethodContract {
+public class DistributedMDNParseMethodTest extends DistributedBase implements MDNParseMethodContract {
     public static final CassandraMessageId.Factory MESSAGE_ID_FACTORY = new CassandraMessageId.Factory();
 
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
-
     @Override
     public MessageId randomMessageId() {
         return MESSAGE_ID_FACTORY.of(Uuids.timeBased());
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMDNSendMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMDNSendMethodTest.java
index e036536e96..809cfdf753 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMDNSendMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMDNSendMethodTest.java
@@ -19,46 +19,15 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.MDNSendMethodContract;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
 import com.datastax.oss.driver.api.core.uuid.Uuids;
 
-class DistributedMDNSendMethodTest implements MDNSendMethodContract {
-    public static final DockerOpenSearchExtension ELASTIC_SEARCH_EXTENSION = new DockerOpenSearchExtension();
+class DistributedMDNSendMethodTest extends DistributedBase implements MDNSendMethodContract {
     public static final CassandraMessageId.Factory MESSAGE_ID_FACTORY = new CassandraMessageId.Factory();
 
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .build())
-        .extension(ELASTIC_SEARCH_EXTENSION)
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
-
     @Override
     public MessageId randomMessageId() {
         return MESSAGE_ID_FACTORY.of(Uuids.timeBased());
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxGetMethodTest.java
index 3d21ebca45..c254b360c3 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxGetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxGetMethodTest.java
@@ -19,43 +19,13 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.MailboxGetMethodContract;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
 import com.datastax.oss.driver.api.core.uuid.Uuids;
 
-public class DistributedMailboxGetMethodTest implements MailboxGetMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
-
+public class DistributedMailboxGetMethodTest extends DistributedBase implements MailboxGetMethodContract {
     @Override
     public MailboxId randomMailboxId() {
         return CassandraId.of(Uuids.timeBased());
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxQueryMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxQueryMethodTest.java
index a1e7b5b9b8..82bfbe7e98 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxQueryMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxQueryMethodTest.java
@@ -19,38 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.MailboxQueryMethodContract;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedMailboxQueryMethodTest implements MailboxQueryMethodContract {
-    public static final DockerOpenSearchExtension ELASTIC_SEARCH_EXTENSION = new DockerOpenSearchExtension();
+public class DistributedMailboxQueryMethodTest extends DistributedBase implements MailboxQueryMethodContract {
 
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                    .s3()
-                    .disableCache()
-                    .deduplication()
-                    .noCryptoConfig())
-            .build())
-        .extension(ELASTIC_SEARCH_EXTENSION)
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxSetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxSetMethodTest.java
index b548a93800..fc80a4c631 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxSetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxSetMethodTest.java
@@ -19,46 +19,16 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
 import org.apache.james.GuiceJamesServer;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.MailboxSetMethodContract;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
 import com.datastax.oss.driver.api.core.uuid.Uuids;
 
-public class DistributedMailboxSetMethodTest implements MailboxSetMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                    .s3()
-                    .disableCache()
-                    .deduplication()
-                    .noCryptoConfig())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
-
+public class DistributedMailboxSetMethodTest extends DistributedBase implements MailboxSetMethodContract {
     @Override
     public MailboxId randomMailboxId() {
         return CassandraId.of(Uuids.timeBased());
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedProvisioningTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedProvisioningTest.java
index 8e485329c2..132c540614 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedProvisioningTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedProvisioningTest.java
@@ -19,36 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.ProvisioningContract;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedProvisioningTest implements ProvisioningContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
+public class DistributedProvisioningTest extends DistributedBase implements ProvisioningContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedQuotaChangesMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedQuotaChangesMethodTest.java
index 3f274d9523..1245a3a8b5 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedQuotaChangesMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedQuotaChangesMethodTest.java
@@ -19,37 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.QuotaChangesMethodContract;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedQuotaChangesMethodTest implements QuotaChangesMethodContract {
+public class DistributedQuotaChangesMethodTest extends DistributedBase implements QuotaChangesMethodContract {
 
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedQuotaGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedQuotaGetMethodTest.java
index eb6612b099..cd8e230710 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedQuotaGetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedQuotaGetMethodTest.java
@@ -19,37 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.QuotaGetMethodContract;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedQuotaGetMethodTest implements QuotaGetMethodContract {
+public class DistributedQuotaGetMethodTest extends DistributedBase implements QuotaGetMethodContract {
 
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedQuotaQueryMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedQuotaQueryMethodTest.java
index 91b3b68e29..d5056abd93 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedQuotaQueryMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedQuotaQueryMethodTest.java
@@ -19,37 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.QuotaQueryMethodContract;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedQuotaQueryMethodTest implements QuotaQueryMethodContract {
+public class DistributedQuotaQueryMethodTest extends DistributedBase implements QuotaQueryMethodContract {
 
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedSessionRouteTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedSessionRouteTest.java
index 4478878945..18a721e711 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedSessionRouteTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedSessionRouteTest.java
@@ -19,37 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.SearchConfiguration;
 import org.apache.james.jmap.rfc8621.contract.SessionRoutesContract;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedSessionRouteTest implements SessionRoutesContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.s3()
-                .disableCache()
-                .passthrough()
-                .noCryptoConfig())
-            .searchConfiguration(SearchConfiguration.openSearch())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
+public class DistributedSessionRouteTest extends DistributedBase implements SessionRoutesContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedUploadTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedUploadTest.java
index 824d61d998..6927255ed2 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedUploadTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedUploadTest.java
@@ -19,36 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.UploadContract;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedUploadTest implements UploadContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
+public class DistributedUploadTest extends DistributedBase implements UploadContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedVacationResponseGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedVacationResponseGetMethodTest.java
index 9d0dd3c34a..01c679dcf6 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedVacationResponseGetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedVacationResponseGetMethodTest.java
@@ -19,36 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.VacationResponseGetMethodContract;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedVacationResponseGetMethodTest implements VacationResponseGetMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
+public class DistributedVacationResponseGetMethodTest extends DistributedBase implements VacationResponseGetMethodContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedVacationResponseSetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedVacationResponseSetMethodTest.java
index 812c190a04..a39b90adb0 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedVacationResponseSetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedVacationResponseSetMethodTest.java
@@ -19,36 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.VacationResponseSetMethodContract;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedVacationResponseSetMethodTest implements VacationResponseSetMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
+public class DistributedVacationResponseSetMethodTest extends DistributedBase implements VacationResponseSetMethodContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedWebPushTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedWebPushTest.java
index c22c8eb912..c194d5c187 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedWebPushTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedWebPushTest.java
@@ -44,6 +44,7 @@ class DistributedWebPushTest implements WebPushContract {
         CassandraRabbitMQJamesConfiguration.builder()
             .workingDirectory(tmpDir)
             .configurationFromClasspath()
+            .enableJMAP()
             .blobStore(BlobStoreConfiguration.builder()
                 .s3()
                 .disableCache()
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedWebSocketTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedWebSocketTest.java
index 83cc84e857..cdc66e9fca 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedWebSocketTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedWebSocketTest.java
@@ -19,37 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.distributed;
 
-import org.apache.james.CassandraExtension;
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.DockerOpenSearchExtension;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.WebSocketContract;
-import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
-import org.apache.james.modules.AwsS3BlobStoreExtension;
-import org.apache.james.modules.RabbitMQExtension;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class DistributedWebSocketTest implements WebSocketContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
-        CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                .s3()
-                .disableCache()
-                .deduplication()
-                .noCryptoConfig())
-            .build())
-        .extension(new DockerOpenSearchExtension())
-        .extension(new CassandraExtension())
-        .extension(new RabbitMQExtension())
-        .extension(new AwsS3BlobStoreExtension())
-        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
-        .build();
+public class DistributedWebSocketTest extends DistributedBase implements WebSocketContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/ReadLevelTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/ReadLevelTest.java
index 8752eb5897..b87673b189 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/ReadLevelTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/ReadLevelTest.java
@@ -105,6 +105,7 @@ class ReadLevelTest {
         CassandraRabbitMQJamesConfiguration.builder()
             .workingDirectory(tmpDir)
             .configurationFromClasspath()
+            .enableJMAP()
             .blobStore(BlobStoreConfiguration.builder()
                 .cassandra()
                 .disableCache()
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryBackReferenceTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryBackReferenceTest.java
index db6a71038a..331a1408ad 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryBackReferenceTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryBackReferenceTest.java
@@ -19,25 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.BackReferenceContract;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryBackReferenceTest implements BackReferenceContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
+public class MemoryBackReferenceTest extends MemoryBase implements BackReferenceContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryBase.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryBase.java
new file mode 100644
index 0000000000..10d13e2bfd
--- /dev/null
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryBase.java
@@ -0,0 +1,26 @@
+package org.apache.james.jmap.rfc8621.memory;
+
+import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
+
+import org.apache.james.JamesServerBuilder;
+import org.apache.james.JamesServerExtension;
+import org.apache.james.MemoryJamesConfiguration;
+import org.apache.james.MemoryJamesServerMain;
+import org.apache.james.jmap.rfc8621.contract.IdentityProbeModule;
+import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
+import org.apache.james.modules.TestJMAPServerModule;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+public class MemoryBase {
+    @RegisterExtension
+    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
+        MemoryJamesConfiguration.builder()
+            .workingDirectory(tmpDir)
+            .configurationFromClasspath()
+            .usersRepository(DEFAULT)
+            .enableJMAP()
+            .build())
+        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
+            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule(), new IdentityProbeModule()))
+        .build();
+}
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDelegateGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDelegateGetMethodTest.java
index 3dc00b2dd0..13ce0b8e77 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDelegateGetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDelegateGetMethodTest.java
@@ -19,26 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.DelegateGetMethodContract;
-import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryDelegateGetMethodTest implements DelegateGetMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
-        .build();
+public class MemoryDelegateGetMethodTest extends MemoryBase  implements DelegateGetMethodContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDelegateSetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDelegateSetMethodTest.java
index d80abf70f5..f502713f9e 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDelegateSetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDelegateSetMethodTest.java
@@ -19,26 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.DelegateSetContract;
-import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryDelegateSetMethodTest implements DelegateSetContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
-        .build();
+public class MemoryDelegateSetMethodTest extends MemoryBase implements DelegateSetContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDelegatedAccountGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDelegatedAccountGetMethodTest.java
index b70015ccf1..27c5f62d67 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDelegatedAccountGetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDelegatedAccountGetMethodTest.java
@@ -19,26 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.DelegatedAccountGetMethodContract;
-import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryDelegatedAccountGetMethodTest implements DelegatedAccountGetMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
-        .build();
+public class MemoryDelegatedAccountGetMethodTest extends MemoryBase implements DelegatedAccountGetMethodContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDelegatedAccountSetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDelegatedAccountSetMethodTest.java
index 0f15e36429..dc18798a96 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDelegatedAccountSetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDelegatedAccountSetMethodTest.java
@@ -19,26 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.DelegatedAccountSetContract;
-import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryDelegatedAccountSetMethodTest implements DelegatedAccountSetContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
-        .build();
+public class MemoryDelegatedAccountSetMethodTest extends MemoryBase implements DelegatedAccountSetContract {
+
 }
\ No newline at end of file
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDownloadTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDownloadTest.java
index a0d1f5f4c8..dec489a75a 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDownloadTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryDownloadTest.java
@@ -19,32 +19,13 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
 import java.util.concurrent.ThreadLocalRandom;
 
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.DownloadContract;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-public class MemoryDownloadTest implements DownloadContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 
+public class MemoryDownloadTest extends MemoryBase implements DownloadContract {
     @Override
     public MessageId randomMessageId() {
         return InMemoryMessageId.of(ThreadLocalRandom.current().nextInt(100000) + 100);
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEchoMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEchoMethodTest.java
index 50b1802443..553a271efe 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEchoMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEchoMethodTest.java
@@ -19,25 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.EchoMethodContract;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryEchoMethodTest implements EchoMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
+public class MemoryEchoMethodTest extends MemoryBase implements EchoMethodContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailGetMethodTest.java
index 2e07e0d2f1..4abe7dcd67 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailGetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailGetMethodTest.java
@@ -19,33 +19,13 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
 import java.util.concurrent.ThreadLocalRandom;
 
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.EmailGetMethodContract;
-import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-public class MemoryEmailGetMethodTest implements EmailGetMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
-        .build();
 
+public class MemoryEmailGetMethodTest extends MemoryBase implements EmailGetMethodContract {
     @Override
     public MessageId randomMessageId() {
         return InMemoryMessageId.of(ThreadLocalRandom.current().nextInt(100000) + 100);
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailImportTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailImportTest.java
index b2a7e95e39..ef0207584b 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailImportTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailImportTest.java
@@ -19,34 +19,15 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
 import java.util.concurrent.ThreadLocalRandom;
 
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.EmailImportContract;
 import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-public class MemoryEmailImportTest implements EmailImportContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 
+public class MemoryEmailImportTest extends MemoryBase implements EmailImportContract {
     @Override
     public MessageId randomMessageId() {
         return InMemoryMessageId.of(ThreadLocalRandom.current().nextInt(100000) + 100);
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailQueryMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailQueryMethodTest.java
index 0a93ad2abb..369de1b0fc 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailQueryMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailQueryMethodTest.java
@@ -19,33 +19,14 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
 import org.apache.james.GuiceJamesServer;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.EmailQueryMethodContract;
 import org.apache.james.junit.categories.Unstable;
-import org.apache.james.modules.TestJMAPServerModule;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-public class MemoryEmailQueryMethodTest implements EmailQueryMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 
+public class MemoryEmailQueryMethodTest extends MemoryBase implements EmailQueryMethodContract {
     @Test
     @Override
     @Disabled("JAMES-3377 Not supported for in-memory test")
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailSetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailSetMethodTest.java
index 65ecf0e03a..0bd25eee94 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailSetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailSetMethodTest.java
@@ -19,34 +19,13 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
 import java.util.concurrent.ThreadLocalRandom;
 
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.EmailSetMethodContract;
-import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-public class MemoryEmailSetMethodTest implements EmailSetMethodContract {
-
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
-        .build();
 
+public class MemoryEmailSetMethodTest extends MemoryBase implements EmailSetMethodContract {
     @Override
     public MessageId randomMessageId() {
         return InMemoryMessageId.of(ThreadLocalRandom.current().nextInt(100000) + 100);
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailSubmissionSetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailSubmissionSetMethodTest.java
index 54d952dbe2..7f0931afa1 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailSubmissionSetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailSubmissionSetMethodTest.java
@@ -19,32 +19,13 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
 import java.util.concurrent.ThreadLocalRandom;
 
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.EmailSubmissionSetMethodContract;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class MemoryEmailSubmissionSetMethodTest implements EmailSubmissionSetMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 
+class MemoryEmailSubmissionSetMethodTest extends MemoryBase implements EmailSubmissionSetMethodContract {
     @Override
     public MessageId randomMessageId() {
         return InMemoryMessageId.of(ThreadLocalRandom.current().nextInt(100000) + 100);
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEventSourceTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEventSourceTest.java
index 8edd7c503f..74f3c2d071 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEventSourceTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEventSourceTest.java
@@ -19,26 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.EventSourceContract;
-import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryEventSourceTest implements EventSourceContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
-        .build();
+public class MemoryEventSourceTest extends MemoryBase implements EventSourceContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryIdentityGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryIdentityGetMethodTest.java
index 994bbffabc..39d71d1313 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryIdentityGetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryIdentityGetMethodTest.java
@@ -19,26 +19,7 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.IdentityGetContract;
-import org.apache.james.jmap.rfc8621.contract.IdentityProbeModule;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryIdentityGetMethodTest implements IdentityGetContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new IdentityProbeModule()))
-        .build();
+public class MemoryIdentityGetMethodTest extends MemoryBase implements IdentityGetContract {
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryIdentitySetMethodTests.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryIdentitySetMethodTests.java
index 2a7e81a6b0..f558f32860 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryIdentitySetMethodTests.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryIdentitySetMethodTests.java
@@ -19,26 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
-import org.apache.james.jmap.rfc8621.contract.IdentityProbeModule;
 import org.apache.james.jmap.rfc8621.contract.IdentitySetContract;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryIdentitySetMethodTests implements IdentitySetContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new IdentityProbeModule()))
-        .build();
+public class MemoryIdentitySetMethodTests extends MemoryBase implements IdentitySetContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMDNParseMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMDNParseMethodTest.java
index fb1d3a8333..b784d478c6 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMDNParseMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMDNParseMethodTest.java
@@ -19,32 +19,13 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
 import java.util.concurrent.ThreadLocalRandom;
 
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.MDNParseMethodContract;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-public class MemoryMDNParseMethodTest implements MDNParseMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 
+public class MemoryMDNParseMethodTest extends MemoryBase implements MDNParseMethodContract {
     @Override
     public MessageId randomMessageId() {
         return InMemoryMessageId.of(ThreadLocalRandom.current().nextInt(100000) + 100);
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMDNSendMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMDNSendMethodTest.java
index a1c36203de..8980d6c366 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMDNSendMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMDNSendMethodTest.java
@@ -19,32 +19,13 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
 import java.util.concurrent.ThreadLocalRandom;
 
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.MDNSendMethodContract;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-public class MemoryMDNSendMethodTest implements MDNSendMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 
+public class MemoryMDNSendMethodTest extends MemoryBase implements MDNSendMethodContract {
     @Override
     public MessageId randomMessageId() {
         return InMemoryMessageId.of(ThreadLocalRandom.current().nextInt(100000) + 100);
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMailboxGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMailboxGetMethodTest.java
index 6f178f5f52..cab0bebac8 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMailboxGetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMailboxGetMethodTest.java
@@ -19,32 +19,13 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
 import java.util.concurrent.ThreadLocalRandom;
 
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.MailboxGetMethodContract;
 import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-public class MemoryMailboxGetMethodTest implements MailboxGetMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 
+public class MemoryMailboxGetMethodTest extends MemoryBase implements MailboxGetMethodContract {
     @Override
     public MailboxId randomMailboxId() {
         return InMemoryId.of(ThreadLocalRandom.current().nextInt(100000) + 100);
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMailboxQueryMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMailboxQueryMethodTest.java
index bebc5308e2..986dacb587 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMailboxQueryMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMailboxQueryMethodTest.java
@@ -19,25 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.MailboxQueryMethodContract;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryMailboxQueryMethodTest implements MailboxQueryMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
+public class MemoryMailboxQueryMethodTest extends MemoryBase implements MailboxQueryMethodContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMailboxSetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMailboxSetMethodTest.java
index abffafa488..4971ca7519 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMailboxSetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMailboxSetMethodTest.java
@@ -19,32 +19,13 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
 import java.util.concurrent.ThreadLocalRandom;
 
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.MailboxSetMethodContract;
 import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-public class MemoryMailboxSetMethodTest implements MailboxSetMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 
+public class MemoryMailboxSetMethodTest extends MemoryBase implements MailboxSetMethodContract {
     @Override
     public MailboxId randomMailboxId() {
         return InMemoryId.of(ThreadLocalRandom.current().nextInt(100000) + 100);
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryProvisioningTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryProvisioningTest.java
index a40734dbf1..6afccc6da2 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryProvisioningTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryProvisioningTest.java
@@ -19,25 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.ProvisioningContract;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-class MemoryProvisioningTest implements ProvisioningContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
+class MemoryProvisioningTest extends MemoryBase implements ProvisioningContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryQuotaChangesMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryQuotaChangesMethodTest.java
index c2606b3d9d..73c4593b61 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryQuotaChangesMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryQuotaChangesMethodTest.java
@@ -19,26 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.QuotaChangesMethodContract;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryQuotaChangesMethodTest implements QuotaChangesMethodContract {
+public class MemoryQuotaChangesMethodTest extends MemoryBase implements QuotaChangesMethodContract {
 
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryQuotaGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryQuotaGetMethodTest.java
index e2bfac204c..5c76e3ccf8 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryQuotaGetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryQuotaGetMethodTest.java
@@ -19,26 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.QuotaGetMethodContract;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryQuotaGetMethodTest implements QuotaGetMethodContract {
+public class MemoryQuotaGetMethodTest extends MemoryBase implements QuotaGetMethodContract {
 
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryQuotaQueryMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryQuotaQueryMethodTest.java
index 05198b98c8..d61ce0f232 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryQuotaQueryMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryQuotaQueryMethodTest.java
@@ -19,26 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.QuotaQueryMethodContract;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryQuotaQueryMethodTest implements QuotaQueryMethodContract {
+public class MemoryQuotaQueryMethodTest extends MemoryBase implements QuotaQueryMethodContract {
 
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemorySessionRouteTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemorySessionRouteTest.java
index 34dfc69ae7..54004c7c3d 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemorySessionRouteTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemorySessionRouteTest.java
@@ -19,25 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.SessionRoutesContract;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemorySessionRouteTest implements SessionRoutesContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
+public class MemorySessionRouteTest extends MemoryBase implements SessionRoutesContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryThreadChangesMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryThreadChangesMethodTest.java
index 7da44470c8..733d3f70b3 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryThreadChangesMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryThreadChangesMethodTest.java
@@ -19,25 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.ThreadChangesContract;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryThreadChangesMethodTest implements ThreadChangesContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
+public class MemoryThreadChangesMethodTest extends MemoryBase implements ThreadChangesContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryThreadGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryThreadGetMethodTest.java
index c0d41f6635..6e438a39a7 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryThreadGetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryThreadGetMethodTest.java
@@ -19,32 +19,13 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
 import java.util.List;
 
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.ThreadGetContract;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.SearchQuery;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-public class MemoryThreadGetMethodTest implements ThreadGetContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
 
+public class MemoryThreadGetMethodTest extends MemoryBase implements ThreadGetContract {
     @Override
     public void awaitMessageCount(List<MailboxId> mailboxIds, SearchQuery query, long messageCount) {
 
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryUploadTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryUploadTest.java
index 5db6eaee30..e6482ddc43 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryUploadTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryUploadTest.java
@@ -19,25 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.UploadContract;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryUploadTest implements UploadContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
+public class MemoryUploadTest extends MemoryBase implements UploadContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryVacationResponseGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryVacationResponseGetMethodTest.java
index fa9e3b8b6a..6408c36969 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryVacationResponseGetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryVacationResponseGetMethodTest.java
@@ -19,25 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.VacationResponseGetMethodContract;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryVacationResponseGetMethodTest implements VacationResponseGetMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
+public class MemoryVacationResponseGetMethodTest extends MemoryBase implements VacationResponseGetMethodContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryVacationResponseSetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryVacationResponseSetMethodTest.java
index 42ce51f3b4..23b620b431 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryVacationResponseSetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryVacationResponseSetMethodTest.java
@@ -19,25 +19,8 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.VacationResponseSetMethodContract;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryVacationResponseSetMethodTest implements VacationResponseSetMethodContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
-        .build();
+public class MemoryVacationResponseSetMethodTest extends MemoryBase implements VacationResponseSetMethodContract {
+
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryWebSocketTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryWebSocketTest.java
index 9cd2c2f863..ecae80d554 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryWebSocketTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryWebSocketTest.java
@@ -19,26 +19,7 @@
 
 package org.apache.james.jmap.rfc8621.memory;
 
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
-
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.WebSocketContract;
-import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class MemoryWebSocketTest implements WebSocketContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
-        MemoryJamesConfiguration.builder()
-            .workingDirectory(tmpDir)
-            .configurationFromClasspath()
-            .usersRepository(DEFAULT)
-            .build())
-        .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
-        .build();
+public class MemoryWebSocketTest extends MemoryBase implements WebSocketContract {
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org


[james-project] 07/07: [TEST] Reduce integration test boiler plate

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit ab09025932aa73a48166ba12e0fea430039f8aa7
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed May 10 09:58:42 2023 +0700

    [TEST] Reduce integration test boiler plate
---
 .../apache/james/jmap/rfc8621/memory/MemoryBase.java  | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryBase.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryBase.java
index 10d13e2bfd..44d40c4ba0 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryBase.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryBase.java
@@ -1,3 +1,22 @@
+/****************************************************************
+ * 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.                                           *
+ ****************************************************************/
+
 package org.apache.james.jmap.rfc8621.memory;
 
 import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org