You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2020/07/31 09:24:43 UTC

[james-project] 22/28: JAMES-3350 Allow to choose the lifecycle of JamesServerExtension

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 279baaa8fa49dd1e475f7b513b466a5457b94d97
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue Jul 28 13:03:16 2020 +0700

    JAMES-3350 Allow to choose the lifecycle of JamesServerExtension
    
    Allow to restart it:
    
     - Per test
     - Per enclosing class (no for the 'main' test class and not for each nested class
     - Per class, including nested ones
    
     Note that this feature was implemented in RabbitMQJmapExtension.java, but only for
     the distributed server, with only a specific module setup.
    
     This commit enforce Lifecycle.PER_CLASS usage where the underlying James data are not affected
     by the test.
---
 .../org/apache/james/CassandraJamesServerTest.java |   6 +-
 .../apache/james/CassandraJmapJamesServerTest.java |  35 ----
 .../org/apache/james/CassandraWithTikaTest.java    |  15 +-
 .../CassandraRabbitMQLdapJmapJamesServerTest.java  |   3 +
 .../java/org/apache/james/JamesServerBuilder.java  |  10 +-
 .../org/apache/james/JamesServerExtension.java     |  59 +++++-
 .../java/org/apache/james/JPAJamesServerTest.java  |   1 +
 ...WithAuthenticatedDatabaseSqlValidationTest.java |   1 +
 ...atabaseAuthenticaticationSqlValidationTest.java |   1 +
 .../org/apache/james/MemoryJamesServerTest.java    |   1 +
 .../distributed/DistributedAuthenticationTest.java |   1 +
 .../rfc8621/contract/AuthenticationContract.scala  |  11 +-
 .../rfc8621/memory/MemoryAuthenticationTest.java   |   1 +
 .../rabbitmq/RabbitMQAuthorizedEndpointsTest.java  |   1 +
 .../rabbitmq/RabbitMQJmapExtension.java            | 211 ---------------------
 .../RabbitMQUnauthorizedEndpointsTest.java         |  38 +++-
 .../memory/MemoryAuthorizedEndpointsTest.java      |   1 +
 .../memory/MemoryJwtFilterIntegrationTest.java     |   1 +
 .../memory/MemoryUnauthorizedEndpointsTest.java    |   1 +
 19 files changed, 134 insertions(+), 264 deletions(-)

diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJamesServerTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJamesServerTest.java
index d614d17..380cd18 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJamesServerTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJamesServerTest.java
@@ -21,19 +21,21 @@ package org.apache.james;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
+import org.apache.james.jmap.draft.JmapJamesServerContract;
 import org.apache.james.modules.ConfigurationProbe;
 import org.apache.james.modules.TestJMAPServerModule;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-class CassandraJamesServerTest implements JamesServerContract {
+class CassandraJamesServerTest implements JamesServerContract, JmapJamesServerContract {
     @RegisterExtension
     static JamesServerExtension testExtension = TestingDistributedJamesServerBuilder.withSearchConfiguration(SearchConfiguration.elasticSearch())
         .extension(new DockerElasticSearchExtension())
         .extension(new CassandraExtension())
         .server(configuration -> CassandraJamesServerMain.createServer(configuration)
             .overrideWith(new TestJMAPServerModule())
-            .overrideWith(DOMAIN_LIST_CONFIGURATION_MODULE))
+            .overrideWith(JamesServerContract.DOMAIN_LIST_CONFIGURATION_MODULE))
+        .lifeCycle(JamesServerExtension.Lifecycle.PER_CLASS)
         .build();
 
     @Test
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJmapJamesServerTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJmapJamesServerTest.java
deleted file mode 100644
index 2abb9d5..0000000
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJmapJamesServerTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/****************************************************************
- * 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;
-
-import org.apache.james.jmap.draft.JmapJamesServerContract;
-import org.apache.james.modules.TestJMAPServerModule;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class CassandraJmapJamesServerTest implements JmapJamesServerContract {
-    @RegisterExtension
-    static JamesServerExtension testExtension = TestingDistributedJamesServerBuilder.withSearchConfiguration(SearchConfiguration.elasticSearch())
-        .extension(new DockerElasticSearchExtension())
-        .extension(new CassandraExtension())
-        .server(configuration -> CassandraJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule())
-            .overrideWith(DOMAIN_LIST_CONFIGURATION_MODULE))
-        .build();
-}
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraWithTikaTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraWithTikaTest.java
index 31615a3..9467786 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraWithTikaTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraWithTikaTest.java
@@ -25,11 +25,12 @@ import org.junit.jupiter.api.extension.RegisterExtension;
 class CassandraWithTikaTest implements JamesServerContract {
     @RegisterExtension
     static JamesServerExtension testExtension = TestingDistributedJamesServerBuilder.withSearchConfiguration(SearchConfiguration.elasticSearch())
-            .extension(new CassandraExtension())
-            .extension(new  TikaExtension())
-            .extension(new DockerElasticSearchExtension())
-            .server(configuration -> CassandraJamesServerMain.createServer(configuration)
-                .overrideWith(new TestJMAPServerModule())
-                .overrideWith(DOMAIN_LIST_CONFIGURATION_MODULE))
-            .build();
+        .extension(new CassandraExtension())
+        .extension(new  TikaExtension())
+        .extension(new DockerElasticSearchExtension())
+        .server(configuration -> CassandraJamesServerMain.createServer(configuration)
+            .overrideWith(new TestJMAPServerModule())
+            .overrideWith(DOMAIN_LIST_CONFIGURATION_MODULE))
+        .lifeCycle(JamesServerExtension.Lifecycle.PER_CLASS)
+        .build();
 }
diff --git a/server/container/guice/cassandra-rabbitmq-ldap-guice/src/test/java/org/apache/james/CassandraRabbitMQLdapJmapJamesServerTest.java b/server/container/guice/cassandra-rabbitmq-ldap-guice/src/test/java/org/apache/james/CassandraRabbitMQLdapJmapJamesServerTest.java
index 91c8934..36becc4 100644
--- a/server/container/guice/cassandra-rabbitmq-ldap-guice/src/test/java/org/apache/james/CassandraRabbitMQLdapJmapJamesServerTest.java
+++ b/server/container/guice/cassandra-rabbitmq-ldap-guice/src/test/java/org/apache/james/CassandraRabbitMQLdapJmapJamesServerTest.java
@@ -62,6 +62,7 @@ class CassandraRabbitMQLdapJmapJamesServerTest {
                     .disableCache()
                     .deduplication())
             .extension(new SwiftBlobStoreExtension())
+            .lifeCycle(JamesServerExtension.Lifecycle.PER_CLASS)
             .build();
     }
 
@@ -74,6 +75,7 @@ class CassandraRabbitMQLdapJmapJamesServerTest {
                     .disableCache()
                     .deduplication())
             .extension(new AwsS3BlobStoreExtension())
+            .lifeCycle(JamesServerExtension.Lifecycle.PER_CLASS)
             .build();
     }
 
@@ -85,6 +87,7 @@ class CassandraRabbitMQLdapJmapJamesServerTest {
                 .cassandra()
                 .disableCache()
                 .passthrough())
+            .lifeCycle(JamesServerExtension.Lifecycle.PER_CLASS)
             .build();
     }
 
diff --git a/server/container/guice/guice-common/src/test/java/org/apache/james/JamesServerBuilder.java b/server/container/guice/guice-common/src/test/java/org/apache/james/JamesServerBuilder.java
index 0a749fd..cfca036 100644
--- a/server/container/guice/guice-common/src/test/java/org/apache/james/JamesServerBuilder.java
+++ b/server/container/guice/guice-common/src/test/java/org/apache/james/JamesServerBuilder.java
@@ -57,15 +57,18 @@ public class JamesServerBuilder<T extends Configuration> {
     private ServerProvider server;
     private ConfigurationProvider configuration;
     private Optional<Boolean> autoStart;
+    private JamesServerExtension.Lifecycle lifecycle;
 
     public JamesServerBuilder(ConfigurationProvider configurationProvider) {
         configuration = configurationProvider;
         extensions = ImmutableList.builder();
         folderRegistrableExtension = new TemporaryFolderRegistrableExtension();
         autoStart = Optional.empty();
+        lifecycle = JamesServerExtension.Lifecycle.PER_TEST;
         overrideModules = ImmutableList.builder();
     }
 
+
     public JamesServerBuilder<T> extensions(GuiceModuleTestExtension... extensions) {
         this.extensions.add(extensions);
         return this;
@@ -90,12 +93,17 @@ public class JamesServerBuilder<T extends Configuration> {
         return this;
     }
 
+    public JamesServerBuilder<T> lifeCycle(JamesServerExtension.Lifecycle lifecycle) {
+        this.lifecycle = lifecycle;
+        return this;
+    }
+
     public JamesServerExtension build() {
         Preconditions.checkNotNull(server);
         JamesServerExtension.AwaitCondition awaitCondition = () -> extensions.build().forEach(GuiceModuleTestExtension::await);
 
         return new JamesServerExtension(buildAggregateJunitExtension(), file -> overrideServerWithExtensionsModules(file, configuration),
-            awaitCondition, autoStart.orElse(DEFAULT_AUTO_START));
+            awaitCondition, autoStart.orElse(DEFAULT_AUTO_START), lifecycle);
     }
 
     private AggregateJunitExtension buildAggregateJunitExtension() {
diff --git a/server/container/guice/guice-common/src/test/java/org/apache/james/JamesServerExtension.java b/server/container/guice/guice-common/src/test/java/org/apache/james/JamesServerExtension.java
index 3469871..d79548c 100644
--- a/server/container/guice/guice-common/src/test/java/org/apache/james/JamesServerExtension.java
+++ b/server/container/guice/guice-common/src/test/java/org/apache/james/JamesServerExtension.java
@@ -23,6 +23,7 @@ import java.io.File;
 import java.io.IOException;
 import java.io.UncheckedIOException;
 
+import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.extension.AfterAllCallback;
 import org.junit.jupiter.api.extension.AfterEachCallback;
 import org.junit.jupiter.api.extension.BeforeAllCallback;
@@ -32,6 +33,8 @@ import org.junit.jupiter.api.extension.ParameterContext;
 import org.junit.jupiter.api.extension.ParameterResolutionException;
 import org.junit.jupiter.api.extension.ParameterResolver;
 
+import com.github.fge.lambdas.consumers.ThrowingBiConsumer;
+
 public class JamesServerExtension implements BeforeAllCallback, BeforeEachCallback, AfterEachCallback, AfterAllCallback, ParameterResolver {
 
     interface ThrowingFunction<P, T> {
@@ -42,18 +45,62 @@ public class JamesServerExtension implements BeforeAllCallback, BeforeEachCallba
         void await();
     }
 
+    public enum Lifecycle {
+        // Restarts the server for each class, including nested classes
+        PER_CLASS(JamesServerExtension::start, (extension, context) -> { }, (extension, context) -> { }, JamesServerExtension::stop),
+        // Restarts the server for the enclosing class, it will ignore nested classes
+        PER_ENCLOSING_CLASS(
+            (extension, context) -> {
+                if (!isNested(context)) {
+                    extension.start(context);
+                }
+            },
+            (extension, context) -> { },
+            (extension, context) -> { },
+            (extension, context) -> {
+                if (!isNested(context)) {
+                    extension.stop(context);
+                }
+            }),
+        // Restarts the server for each test (default)
+        PER_TEST((extension, context) -> { }, JamesServerExtension::start, JamesServerExtension::stop, (extension, context) -> { });
+
+        private static boolean isNested(ExtensionContext context) {
+            return context.getTestClass()
+                .map(clazz -> clazz.isAnnotationPresent(Nested.class))
+                .orElse(false);
+        }
+
+        private final ThrowingBiConsumer<JamesServerExtension, ExtensionContext> beforeAll;
+        private final ThrowingBiConsumer<JamesServerExtension, ExtensionContext> beforeEach;
+        private final ThrowingBiConsumer<JamesServerExtension, ExtensionContext> afterEach;
+        private final ThrowingBiConsumer<JamesServerExtension, ExtensionContext> afterAll;
+
+        Lifecycle(ThrowingBiConsumer<JamesServerExtension, ExtensionContext> beforeAll,
+                  ThrowingBiConsumer<JamesServerExtension, ExtensionContext> beforeEach,
+                  ThrowingBiConsumer<JamesServerExtension, ExtensionContext> afterEach,
+                  ThrowingBiConsumer<JamesServerExtension, ExtensionContext> afterAll) {
+            this.beforeAll = beforeAll;
+            this.beforeEach = beforeEach;
+            this.afterEach = afterEach;
+            this.afterAll = afterAll;
+        }
+    }
+
     private final TemporaryFolderRegistrableExtension folderRegistrableExtension;
     private final ThrowingFunction<File, GuiceJamesServer> serverSupplier;
     private final RegistrableExtension registrableExtension;
     private final boolean autoStart;
+    private final Lifecycle lifecycle;
     private final AwaitCondition awaitCondition;
 
     private GuiceJamesServer guiceJamesServer;
 
     JamesServerExtension(RegistrableExtension registrableExtension, ThrowingFunction<File, GuiceJamesServer> serverSupplier,
-                         AwaitCondition awaitCondition, boolean autoStart) {
+                         AwaitCondition awaitCondition, boolean autoStart, Lifecycle lifecycle) {
         this.registrableExtension = registrableExtension;
         this.serverSupplier = serverSupplier;
+        this.lifecycle = lifecycle;
         this.folderRegistrableExtension = new TemporaryFolderRegistrableExtension();
         this.autoStart = autoStart;
         this.awaitCondition = awaitCondition;
@@ -66,10 +113,15 @@ public class JamesServerExtension implements BeforeAllCallback, BeforeEachCallba
     @Override
     public void beforeAll(ExtensionContext extensionContext) throws Exception {
         registrableExtension.beforeAll(extensionContext);
+        lifecycle.beforeAll.accept(this, extensionContext);
     }
 
     @Override
     public void beforeEach(ExtensionContext extensionContext) throws Exception {
+        lifecycle.beforeEach.accept(this, extensionContext);
+    }
+
+    private void start(ExtensionContext extensionContext) throws Exception {
         folderRegistrableExtension.beforeEach(extensionContext);
         registrableExtension.beforeEach(extensionContext);
         guiceJamesServer = serverSupplier.apply(createTmpDir());
@@ -80,6 +132,10 @@ public class JamesServerExtension implements BeforeAllCallback, BeforeEachCallba
 
     @Override
     public void afterEach(ExtensionContext extensionContext) throws Exception {
+        lifecycle.afterEach.accept(this, extensionContext);
+    }
+
+    private void stop(ExtensionContext extensionContext) throws Exception {
         guiceJamesServer.stop();
         registrableExtension.afterEach(extensionContext);
         folderRegistrableExtension.afterEach(extensionContext);
@@ -87,6 +143,7 @@ public class JamesServerExtension implements BeforeAllCallback, BeforeEachCallba
 
     @Override
     public void afterAll(ExtensionContext extensionContext) throws Exception {
+        lifecycle.afterAll.accept(this, extensionContext);
         registrableExtension.afterAll(extensionContext);
     }
 
diff --git a/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerTest.java b/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerTest.java
index 6def258..f13a9ea 100644
--- a/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerTest.java
+++ b/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerTest.java
@@ -43,6 +43,7 @@ class JPAJamesServerTest implements JamesServerContract {
     static JamesServerExtension jamesServerExtension = new JamesServerBuilder<>(JamesServerBuilder.defaultConfigurationProvider())
         .server(configuration -> JPAJamesServerMain.createServer(configuration)
             .overrideWith(new TestJPAConfigurationModule(), DOMAIN_LIST_CONFIGURATION_MODULE))
+        .lifeCycle(JamesServerExtension.Lifecycle.PER_CLASS)
         .build();
 
     private static final ConditionFactory AWAIT = Awaitility.await()
diff --git a/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerWithAuthenticatedDatabaseSqlValidationTest.java b/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerWithAuthenticatedDatabaseSqlValidationTest.java
index a32d885..4880eef 100644
--- a/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerWithAuthenticatedDatabaseSqlValidationTest.java
+++ b/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerWithAuthenticatedDatabaseSqlValidationTest.java
@@ -27,5 +27,6 @@ class JPAJamesServerWithAuthenticatedDatabaseSqlValidationTest extends JPAJamesS
     static JamesServerExtension jamesServerExtension = new JamesServerBuilder<>(JamesServerBuilder.defaultConfigurationProvider())
         .server(configuration -> JPAJamesServerMain.createServer(configuration)
             .overrideWith(new TestJPAConfigurationModuleWithSqlValidation.WithDatabaseAuthentication(), DOMAIN_LIST_CONFIGURATION_MODULE))
+        .lifeCycle(JamesServerExtension.Lifecycle.PER_CLASS)
         .build();
 }
diff --git a/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerWithNoDatabaseAuthenticaticationSqlValidationTest.java b/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerWithNoDatabaseAuthenticaticationSqlValidationTest.java
index 2bad2be..4e941db 100644
--- a/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerWithNoDatabaseAuthenticaticationSqlValidationTest.java
+++ b/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerWithNoDatabaseAuthenticaticationSqlValidationTest.java
@@ -27,5 +27,6 @@ class JPAJamesServerWithNoDatabaseAuthenticaticationSqlValidationTest extends JP
     static JamesServerExtension jamesServerExtension = new JamesServerBuilder<>(JamesServerBuilder.defaultConfigurationProvider())
         .server(configuration -> JPAJamesServerMain.createServer(configuration)
             .overrideWith(new TestJPAConfigurationModuleWithSqlValidation.NoDatabaseAuthentication(), DOMAIN_LIST_CONFIGURATION_MODULE))
+        .lifeCycle(JamesServerExtension.Lifecycle.PER_CLASS)
         .build();
 }
diff --git a/server/container/guice/memory-guice/src/test/java/org/apache/james/MemoryJamesServerTest.java b/server/container/guice/memory-guice/src/test/java/org/apache/james/MemoryJamesServerTest.java
index 0dde933..8b1d9c7 100644
--- a/server/container/guice/memory-guice/src/test/java/org/apache/james/MemoryJamesServerTest.java
+++ b/server/container/guice/memory-guice/src/test/java/org/apache/james/MemoryJamesServerTest.java
@@ -28,5 +28,6 @@ class MemoryJamesServerTest implements JamesServerContract {
         .server(configuration -> MemoryJamesServerMain.createServer(configuration)
             .overrideWith(new TestJMAPServerModule())
             .overrideWith(DOMAIN_LIST_CONFIGURATION_MODULE))
+        .lifeCycle(JamesServerExtension.Lifecycle.PER_CLASS)
         .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/DistributedAuthenticationTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedAuthenticationTest.java
index 219ff54..91e8dda 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedAuthenticationTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedAuthenticationTest.java
@@ -51,5 +51,6 @@ class DistributedAuthenticationTest implements AuthenticationContract {
         .extension(new AwsS3BlobStoreExtension())
         .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
             .overrideWith(new TestJMAPServerModule()))
+        .lifeCycle(JamesServerExtension.Lifecycle.PER_ENCLOSING_CLASS)
         .build();
 }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/AuthenticationContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/AuthenticationContract.scala
index 6d2b766..c411c81 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/AuthenticationContract.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/AuthenticationContract.scala
@@ -28,11 +28,10 @@ import org.apache.james.GuiceJamesServer
 import org.apache.james.jmap.rfc8621.contract.Fixture.{ACCEPT_RFC8621_VERSION_HEADER, ALICE, ALICE_PASSWORD, AUTHORIZATION_HEADER, BOB, BOB_BASIC_AUTH_HEADER, BOB_PASSWORD, DOMAIN, DOMAIN_WITH_SPACE, ECHO_REQUEST_OBJECT, INVALID_JWT_TOKEN, UNKNOWN_USER_TOKEN, USER_TOKEN, getHeadersWith, toBase64, _}
 import org.apache.james.jmap.rfc8621.contract.tags.CategoryTags
 import org.apache.james.utils.DataProbeImpl
-import org.junit.jupiter.api.{BeforeEach, Nested, Tag, Test}
+import org.junit.jupiter.api.{BeforeAll, Nested, Tag, Test}
 
-
-trait AuthenticationContract {
-  @BeforeEach
+object AuthenticationContract {
+  @BeforeAll
   def setup(server: GuiceJamesServer): Unit = {
     server.getProbe(classOf[DataProbeImpl])
       .fluent
@@ -43,10 +42,12 @@ trait AuthenticationContract {
       .addUser(BOB.asString, BOB_PASSWORD)
 
     requestSpecification = baseRequestSpecBuilder(server)
-        .setAuth(new NoAuthScheme)
+      .setAuth(new NoAuthScheme)
       .build
   }
+}
 
+trait AuthenticationContract {
   @Nested
   class BothAuthenticationMechanisms {
     @Tag(CategoryTags.BASIC_FEATURE)
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/MemoryAuthenticationTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryAuthenticationTest.java
index 74163fd..2bebc89 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryAuthenticationTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryAuthenticationTest.java
@@ -34,5 +34,6 @@ class MemoryAuthenticationTest implements AuthenticationContract {
         .server(configuration -> GuiceJamesServer.forConfiguration(configuration)
             .combineWith(IN_MEMORY_SERVER_AGGREGATE_MODULE)
             .overrideWith(new TestJMAPServerModule()))
+        .lifeCycle(JamesServerExtension.Lifecycle.PER_ENCLOSING_CLASS)
         .build();
 }
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQAuthorizedEndpointsTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQAuthorizedEndpointsTest.java
index bebfaa3..0ce6b26 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQAuthorizedEndpointsTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQAuthorizedEndpointsTest.java
@@ -57,5 +57,6 @@ class RabbitMQAuthorizedEndpointsTest extends AuthorizedEndpointsTest {
         .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
             .overrideWith(new UnauthorizedModule())
             .overrideWith(new WebadminIntegrationTestModule()))
+        .lifeCycle(JamesServerExtension.Lifecycle.PER_CLASS)
         .build();
 }
\ No newline at end of file
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQJmapExtension.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQJmapExtension.java
deleted file mode 100644
index aaa763f..0000000
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQJmapExtension.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/****************************************************************
- * 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.webadmin.integration.rabbitmq;
-
-import java.io.IOException;
-import java.util.Optional;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-
-import org.apache.james.CassandraRabbitMQJamesConfiguration;
-import org.apache.james.CassandraRabbitMQJamesServerMain;
-import org.apache.james.CleanupTasksPerformer;
-import org.apache.james.DockerCassandraRule;
-import org.apache.james.DockerElasticSearchRule;
-import org.apache.james.GuiceJamesServer;
-import org.apache.james.SearchConfiguration;
-import org.apache.james.backends.rabbitmq.DockerRabbitMQSingleton;
-import org.apache.james.modules.TestDockerESMetricReporterModule;
-import org.apache.james.modules.TestRabbitMQModule;
-import org.apache.james.modules.blobstore.BlobStoreConfiguration;
-import org.apache.james.modules.objectstorage.aws.s3.DockerAwsS3TestRule;
-import org.apache.james.util.FunctionalUtils;
-import org.apache.james.util.Runnables;
-import org.apache.james.webadmin.integration.UnauthorizedModule;
-import org.apache.james.webadmin.integration.WebadminIntegrationTestModule;
-import org.junit.jupiter.api.extension.AfterAllCallback;
-import org.junit.jupiter.api.extension.AfterEachCallback;
-import org.junit.jupiter.api.extension.BeforeAllCallback;
-import org.junit.jupiter.api.extension.BeforeEachCallback;
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.junit.jupiter.api.extension.ParameterContext;
-import org.junit.jupiter.api.extension.ParameterResolutionException;
-import org.junit.jupiter.api.extension.ParameterResolver;
-import org.junit.rules.TemporaryFolder;
-
-import com.github.fge.lambdas.Throwing;
-
-public class RabbitMQJmapExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback, ParameterResolver {
-
-    public interface JamesLifeCyclePolicy {
-        JamesLifeCyclePolicy FOR_EACH_TEST = serverSupplier -> JamesLifecycleHandler.builder()
-            .beforeAll(Optional::empty)
-            .beforeEach(() -> Optional.of(serverSupplier.get()))
-            .afterEach(GuiceJamesServer::stop)
-            .afterAll(guiceJamesServer -> { });
-        JamesLifeCyclePolicy COMMON_TO_ALL_TESTS = serverSupplier -> JamesLifecycleHandler.builder()
-            .beforeAll(() -> Optional.of(serverSupplier.get()))
-            .beforeEach(Optional::empty)
-            .afterEach(guiceJamesServer -> { })
-            .afterAll(GuiceJamesServer::stop);
-
-        JamesLifecycleHandler createHandler(Supplier<GuiceJamesServer> serverSupplier);
-    }
-
-    public static class JamesLifecycleHandler {
-        public interface Builder {
-            @FunctionalInterface
-            interface RequiresBeforeAll {
-                RequiresBeforeEach beforeAll(Supplier<Optional<GuiceJamesServer>> beforeAll);
-
-            }
-
-            @FunctionalInterface
-            interface RequiresBeforeEach {
-                RequiresAfterEach beforeEach(Supplier<Optional<GuiceJamesServer>> beforeEach);
-            }
-
-            @FunctionalInterface
-            interface RequiresAfterEach {
-                RequiresAfterAll afterEach(Consumer<GuiceJamesServer> afterAll);
-            }
-
-            @FunctionalInterface
-            interface RequiresAfterAll {
-                JamesLifecycleHandler afterAll(Consumer<GuiceJamesServer> afterAll);
-            }
-        }
-
-        public static Builder.RequiresBeforeAll builder() {
-            return beforeAll -> beforeEach -> afterEach -> afterAll -> new JamesLifecycleHandler(beforeAll, beforeEach, afterEach, afterAll);
-        }
-
-        private final Supplier<Optional<GuiceJamesServer>> beforeAll;
-        private final Supplier<Optional<GuiceJamesServer>> beforeEach;
-        private final Consumer<GuiceJamesServer> afterEach;
-        private final Consumer<GuiceJamesServer>  afterAll;
-
-        JamesLifecycleHandler(Supplier<Optional<GuiceJamesServer>> beforeAll, Supplier<Optional<GuiceJamesServer>> beforeEach, Consumer<GuiceJamesServer> afterEach, Consumer<GuiceJamesServer> afterAll) {
-            this.beforeAll = beforeAll;
-            this.beforeEach = beforeEach;
-            this.afterEach = afterEach;
-            this.afterAll = afterAll;
-        }
-
-        Optional<GuiceJamesServer> beforeAll() {
-            return beforeAll.get()
-                .map(FunctionalUtils.toFunction(Throwing.consumer(GuiceJamesServer::start)));
-        }
-
-        Optional<GuiceJamesServer> beforeEach() {
-            return beforeEach.get()
-                .map(FunctionalUtils.toFunction(Throwing.consumer(GuiceJamesServer::start)));
-        }
-
-        void afterEach(GuiceJamesServer guiceJamesServer) {
-            afterEach.accept(guiceJamesServer);
-        }
-
-        void afterAll(GuiceJamesServer guiceJamesServer) {
-            afterAll.accept(guiceJamesServer);
-        }
-    }
-
-    private final TemporaryFolder temporaryFolder;
-    private final DockerAwsS3TestRule dockerAwsS3TestRule;
-    private final DockerCassandraRule cassandra;
-    private final DockerElasticSearchRule elasticSearchRule;
-    private final JamesLifecycleHandler jamesLifecycleHandler;
-    private GuiceJamesServer james;
-
-    public RabbitMQJmapExtension() {
-        this(JamesLifeCyclePolicy.FOR_EACH_TEST);
-    }
-
-    public RabbitMQJmapExtension(JamesLifeCyclePolicy jamesLifeCyclePolicy) {
-        this.temporaryFolder = new TemporaryFolder();
-        this.cassandra = new DockerCassandraRule();
-        this.elasticSearchRule = new DockerElasticSearchRule();
-        this.dockerAwsS3TestRule = new DockerAwsS3TestRule();
-        this.jamesLifecycleHandler = jamesLifeCyclePolicy.createHandler(jamesSupplier());
-    }
-
-    private GuiceJamesServer james() throws IOException {
-        CassandraRabbitMQJamesConfiguration configuration = CassandraRabbitMQJamesConfiguration.builder()
-            .workingDirectory(temporaryFolder.newFolder())
-            .configurationFromClasspath()
-            .blobStore(BlobStoreConfiguration.builder()
-                    .objectStorage()
-                    .disableCache()
-                    .deduplication())
-            .searchConfiguration(SearchConfiguration.elasticSearch())
-            .build();
-
-        return CassandraRabbitMQJamesServerMain.createServer(configuration)
-                .overrideWith(new TestDockerESMetricReporterModule(elasticSearchRule.getDockerEs().getHttpHost()))
-                .overrideWith(cassandra.getModule())
-                .overrideWith(elasticSearchRule.getModule())
-                .overrideWith(dockerAwsS3TestRule.getModule())
-                .overrideWith(new TestRabbitMQModule(DockerRabbitMQSingleton.SINGLETON))
-                .overrideWith(new WebadminIntegrationTestModule())
-                .overrideWith(new UnauthorizedModule())
-                .overrideWith((binder -> binder.bind(CleanupTasksPerformer.class).asEagerSingleton()));
-    }
-
-    private Supplier<GuiceJamesServer> jamesSupplier() {
-        return Throwing.supplier(this::james);
-    }
-
-    @Override
-    public void beforeAll(ExtensionContext context) throws Exception {
-        temporaryFolder.create();
-        Runnables.runParallel(cassandra::start, elasticSearchRule::start, dockerAwsS3TestRule::start);
-        james = jamesLifecycleHandler.beforeAll().orElse(james);
-    }
-
-    @Override
-    public void afterAll(ExtensionContext context) {
-        jamesLifecycleHandler.afterAll(james);
-        Runnables.runParallel(cassandra::stop, elasticSearchRule.getDockerEs()::cleanUpData, dockerAwsS3TestRule::stop);
-    }
-
-    @Override
-    public void beforeEach(ExtensionContext context) {
-        james = jamesLifecycleHandler.beforeEach().orElse(james);
-    }
-
-    @Override
-    public void afterEach(ExtensionContext context) {
-        jamesLifecycleHandler.afterEach(james);
-    }
-
-    @Override
-    public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
-        return parameterContext.getParameter().getType() == GuiceJamesServer.class;
-    }
-
-    public GuiceJamesServer getJames() {
-        return james;
-    }
-
-    @Override
-    public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
-        return james;
-    }
-}
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQUnauthorizedEndpointsTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQUnauthorizedEndpointsTest.java
index ab1a2a3..29cf1d1 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQUnauthorizedEndpointsTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQUnauthorizedEndpointsTest.java
@@ -21,8 +21,23 @@ package org.apache.james.webadmin.integration.rabbitmq;
 
 import static io.restassured.RestAssured.when;
 
+import org.apache.james.CassandraExtension;
+import org.apache.james.CassandraRabbitMQJamesConfiguration;
+import org.apache.james.CassandraRabbitMQJamesServerMain;
+import org.apache.james.CleanupTasksPerformer;
+import org.apache.james.DockerElasticSearchExtension;
+import org.apache.james.JamesServerBuilder;
+import org.apache.james.JamesServerExtension;
+import org.apache.james.SearchConfiguration;
+import org.apache.james.backends.rabbitmq.DockerRabbitMQSingleton;
 import org.apache.james.junit.categories.BasicFeature;
+import org.apache.james.modules.AwsS3BlobStoreExtension;
+import org.apache.james.modules.RabbitMQExtension;
+import org.apache.james.modules.TestRabbitMQModule;
+import org.apache.james.modules.blobstore.BlobStoreConfiguration;
 import org.apache.james.webadmin.integration.UnauthorizedEndpointsTest;
+import org.apache.james.webadmin.integration.UnauthorizedModule;
+import org.apache.james.webadmin.integration.WebadminIntegrationTestModule;
 import org.apache.james.webadmin.routes.AliasRoutes;
 import org.apache.james.webadmin.routes.CassandraMappingsRoutes;
 import org.apache.james.webadmin.routes.CassandraMigrationRoutes;
@@ -50,9 +65,28 @@ import org.junit.jupiter.params.provider.ValueSource;
 
 @Tag(BasicFeature.TAG)
 class RabbitMQUnauthorizedEndpointsTest extends UnauthorizedEndpointsTest {
-
     @RegisterExtension
-    static RabbitMQJmapExtension rabbitMQJmapExtension = new RabbitMQJmapExtension(RabbitMQJmapExtension.JamesLifeCyclePolicy.COMMON_TO_ALL_TESTS);
+    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
+        CassandraRabbitMQJamesConfiguration.builder()
+            .workingDirectory(tmpDir)
+            .configurationFromClasspath()
+            .blobStore(BlobStoreConfiguration.builder()
+                .objectStorage()
+                .disableCache()
+                .deduplication())
+            .searchConfiguration(SearchConfiguration.elasticSearch())
+            .build())
+        .extension(new DockerElasticSearchExtension())
+        .extension(new CassandraExtension())
+        .extension(new AwsS3BlobStoreExtension())
+        .extension(new RabbitMQExtension())
+        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
+            .overrideWith(new TestRabbitMQModule(DockerRabbitMQSingleton.SINGLETON))
+            .overrideWith(new WebadminIntegrationTestModule())
+            .overrideWith(new UnauthorizedModule())
+            .overrideWith((binder -> binder.bind(CleanupTasksPerformer.class).asEagerSingleton())))
+        .lifeCycle(JamesServerExtension.Lifecycle.PER_CLASS)
+        .build();
 
     @ParameterizedTest
     @ValueSource(strings = {
diff --git a/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryAuthorizedEndpointsTest.java b/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryAuthorizedEndpointsTest.java
index 1b5a462..8ab6edd 100644
--- a/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryAuthorizedEndpointsTest.java
+++ b/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryAuthorizedEndpointsTest.java
@@ -33,5 +33,6 @@ class MemoryAuthorizedEndpointsTest extends AuthorizedEndpointsTest {
         .server(configuration -> MemoryJamesServerMain.createServer(configuration)
             .overrideWith(new WebadminIntegrationTestModule())
             .overrideWith(new UnauthorizedModule()))
+        .lifeCycle(JamesServerExtension.Lifecycle.PER_CLASS)
         .build();
 }
\ No newline at end of file
diff --git a/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryJwtFilterIntegrationTest.java b/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryJwtFilterIntegrationTest.java
index c1aeca7..f724152 100644
--- a/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryJwtFilterIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryJwtFilterIntegrationTest.java
@@ -37,5 +37,6 @@ class MemoryJwtFilterIntegrationTest extends JwtFilterIntegrationTest {
             .overrideWith(new WebadminIntegrationTestModule())
             .overrideWith(binder -> binder.bind(AuthenticationFilter.class).to(JwtFilter.class))
             .overrideWith(binder -> binder.bind(JwtConfiguration.class).toInstance(jwtConfiguration())))
+        .lifeCycle(JamesServerExtension.Lifecycle.PER_CLASS)
         .build();
 }
diff --git a/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryUnauthorizedEndpointsTest.java b/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryUnauthorizedEndpointsTest.java
index 47a7c57..126097c 100644
--- a/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryUnauthorizedEndpointsTest.java
+++ b/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryUnauthorizedEndpointsTest.java
@@ -33,5 +33,6 @@ class MemoryUnauthorizedEndpointsTest extends UnauthorizedEndpointsTest {
         .server(configuration -> MemoryJamesServerMain.createServer(configuration)
             .overrideWith(new UnauthorizedModule())
             .overrideWith(new WebadminIntegrationTestModule()))
+        .lifeCycle(JamesServerExtension.Lifecycle.PER_CLASS)
         .build();
 }
\ No newline at end of file


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