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 2021/02/17 01:46:44 UTC

[james-project] 06/13: JAMES-3500 Leverage PER_CLASS James server test lifecycle where possible

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 775f4a0d7ec46e21ba1e35ec816aab72e356a4dc
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Sun Feb 14 16:30:00 2021 +0700

    JAMES-3500 Leverage PER_CLASS James server test lifecycle where possible
---
 .../rabbitmq/RabbitMQJwtFilterIntegrationTest.java |   3 +
 ...tMQWebAdminServerIntegrationImmutableTest.java} | 129 +--------
 .../RabbitMQWebAdminServerIntegrationTest.java     |  56 ----
 ...rTaskSerializationIntegrationImmutableTest.java | 309 +++++++++++++++++++++
 ...dminServerTaskSerializationIntegrationTest.java | 260 ++---------------
 .../memory/MemoryJwtFilterIntegrationTest.java     |   4 +-
 ...oryWebAdminServerIntegrationImmutableTest.java} |  29 +-
 .../integration/JwtFilterIntegrationTest.java      |  11 +-
 .../WebAdminServerIntegrationImmutableTest.java    | 169 +++++++++++
 .../integration/WebAdminServerIntegrationTest.java |  12 +
 10 files changed, 546 insertions(+), 436 deletions(-)

diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQJwtFilterIntegrationTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQJwtFilterIntegrationTest.java
index e9c190d..42e975a 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQJwtFilterIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQJwtFilterIntegrationTest.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.webadmin.integration.rabbitmq;
 
+import static org.apache.james.JamesServerExtension.Lifecycle.PER_CLASS;
+
 import org.apache.james.CassandraExtension;
 import org.apache.james.CassandraRabbitMQJamesConfiguration;
 import org.apache.james.CassandraRabbitMQJamesServerMain;
@@ -60,5 +62,6 @@ class RabbitMQJwtFilterIntegrationTest extends JwtFilterIntegrationTest {
                 .annotatedWith(Names.named("webadmin"))
                 .toInstance(() -> JwtTokenVerifier.create(jwtConfiguration())))
             .overrideWith(new WebadminIntegrationTestModule()))
+        .lifeCycle(PER_CLASS)
         .build();
 }
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerIntegrationTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerIntegrationImmutableTest.java
similarity index 60%
copy from server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerIntegrationTest.java
copy to server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerIntegrationImmutableTest.java
index 3384b31..038fad2 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerIntegrationImmutableTest.java
@@ -22,10 +22,8 @@ package org.apache.james.webadmin.integration.rabbitmq;
 import static io.restassured.RestAssured.given;
 import static io.restassured.RestAssured.when;
 import static io.restassured.RestAssured.with;
+import static org.apache.james.JamesServerExtension.Lifecycle.PER_CLASS;
 import static org.apache.james.webadmin.Constants.JSON_CONTENT_TYPE;
-import static org.apache.james.webadmin.Constants.SEPARATOR;
-import static org.awaitility.Durations.TEN_SECONDS;
-import static org.hamcrest.CoreMatchers.hasItems;
 import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.is;
@@ -44,22 +42,17 @@ import org.apache.james.modules.RabbitMQExtension;
 import org.apache.james.modules.blobstore.BlobStoreConfiguration;
 import org.apache.james.webadmin.RandomPortSupplier;
 import org.apache.james.webadmin.WebAdminConfiguration;
-import org.apache.james.webadmin.integration.WebAdminServerIntegrationTest;
+import org.apache.james.webadmin.integration.WebAdminServerIntegrationImmutableTest;
 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.TasksRoutes;
 import org.apache.james.webadmin.swagger.routes.SwaggerRoutes;
-import org.awaitility.Awaitility;
 import org.eclipse.jetty.http.HttpStatus;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-import io.restassured.http.ContentType;
-
 @Tag(BasicFeature.TAG)
-class RabbitMQWebAdminServerIntegrationTest extends WebAdminServerIntegrationTest {
+class RabbitMQWebAdminServerIntegrationImmutableTest extends WebAdminServerIntegrationImmutableTest {
 
     @RegisterExtension
     static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
@@ -86,6 +79,7 @@ class RabbitMQWebAdminServerIntegrationTest extends WebAdminServerIntegrationTes
                     .port(new RandomPortSupplier())
                     .additionalRoute("org.apache.james.webadmin.dropwizard.MetricsRoutes")
                     .build())))
+        .lifeCycle(PER_CLASS)
         .build();
 
     private static final String VERSION = "/cassandra/version";
@@ -94,16 +88,6 @@ class RabbitMQWebAdminServerIntegrationTest extends WebAdminServerIntegrationTes
     private static final String UPGRADE_TO_LATEST_VERSION = UPGRADE_VERSION + "/latest";
 
     @Test
-    void getCurrentVersionShouldReturnNullForCurrentVersionAsBeginning() {
-        when()
-            .get(VERSION)
-        .then()
-            .statusCode(HttpStatus.OK_200)
-            .contentType(JSON_CONTENT_TYPE)
-            .body(is("{\"version\":null}"));
-    }
-
-    @Test
     void getLatestVersionShouldReturnTheConfiguredLatestVersion() {
         when()
             .get(VERSION_LATEST)
@@ -114,111 +98,6 @@ class RabbitMQWebAdminServerIntegrationTest extends WebAdminServerIntegrationTes
     }
 
     @Test
-    void postShouldDoMigrationAndUpdateCurrentVersion() {
-        String taskId = with()
-            .body(String.valueOf(CassandraSchemaVersionManager.MAX_VERSION.getValue()))
-        .post(UPGRADE_VERSION)
-            .jsonPath()
-            .get("taskId");
-
-        with()
-            .get("/tasks/" + taskId + "/await")
-        .then()
-            .body("status", is("completed"));
-
-        Awaitility.await()
-            .atMost(TEN_SECONDS)
-            .await()
-            .untilAsserted(() ->
-                when()
-                    .get(VERSION)
-                .then()
-                    .statusCode(HttpStatus.OK_200)
-                    .contentType(JSON_CONTENT_TYPE)
-                    .body(is("{\"version\":" + CassandraSchemaVersionManager.MAX_VERSION.getValue() + "}")));
-    }
-
-    @Test
-    void postShouldDoMigrationAndUpdateToTheLatestVersion() {
-        String taskId = with().post(UPGRADE_TO_LATEST_VERSION)
-            .jsonPath()
-            .get("taskId");
-
-        with()
-            .get("/tasks/" + taskId + "/await")
-        .then()
-            .body("status", is("completed"));
-
-        when()
-            .get(VERSION)
-        .then()
-            .statusCode(HttpStatus.OK_200)
-            .contentType(JSON_CONTENT_TYPE)
-            .body(is("{\"version\":" + CassandraSchemaVersionManager.MAX_VERSION.getValue() + "}"));
-    }
-
-    @Test
-    void cassandraMappingsEndpointShouldKeepDataConsistencyWhenDataValid() {
-        with()
-            .put(AliasRoutes.ROOT_PATH + SEPARATOR + USERNAME + "/sources/" + ALIAS_1);
-        with()
-            .put(AliasRoutes.ROOT_PATH + SEPARATOR + USERNAME + "/sources/" + ALIAS_2);
-
-        String taskId = with()
-            .queryParam("action", "SolveInconsistencies")
-        .post(CassandraMappingsRoutes.ROOT_PATH)
-            .jsonPath()
-            .get("taskId");
-
-        given()
-            .basePath(TasksRoutes.BASE)
-        .when()
-            .get(taskId + "/await")
-        .then()
-            .body("status", is("completed"));
-
-        when()
-            .get(AliasRoutes.ROOT_PATH + SEPARATOR + USERNAME)
-        .then()
-            .contentType(ContentType.JSON)
-        .statusCode(HttpStatus.OK_200)
-            .body("source", hasItems(ALIAS_1, ALIAS_2));
-    }
-
-    @Test
-    void solveMailboxInconsistenciesTaskShouldBeExposed() {
-        // schema version 6 or higher required to run solve mailbox inconsistencies task
-        String taskId = with().post(UPGRADE_TO_LATEST_VERSION)
-            .jsonPath()
-            .get("taskId");
-
-        with()
-            .get("/tasks/" + taskId + "/await")
-        .then()
-            .body("status", is("completed"));
-
-        taskId = with()
-            .header("I-KNOW-WHAT-I-M-DOING", "ALL-SERVICES-ARE-OFFLINE")
-            .queryParam("task", "SolveInconsistencies")
-        .post("/mailboxes")
-            .jsonPath()
-            .get("taskId");
-
-        given()
-            .basePath(TasksRoutes.BASE)
-        .when()
-            .get(taskId + "/await")
-        .then()
-            .body("status", is("completed"))
-            .body("type", is("solve-mailbox-inconsistencies"))
-            .body("additionalInformation.processedMailboxEntries", is(0))
-            .body("additionalInformation.processedMailboxPathEntries", is(0))
-            .body("additionalInformation.errors", is(0))
-            .body("additionalInformation.fixedInconsistencies", hasSize(0))
-            .body("additionalInformation.conflictingEntries", hasSize(0));
-    }
-
-    @Test
     void solveMessageInconsistenciesTasksShouldBeExposed() {
         String taskId = with().post(UPGRADE_TO_LATEST_VERSION)
             .jsonPath()
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerIntegrationTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerIntegrationTest.java
index 3384b31..64cf61d 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerIntegrationTest.java
@@ -26,7 +26,6 @@ import static org.apache.james.webadmin.Constants.JSON_CONTENT_TYPE;
 import static org.apache.james.webadmin.Constants.SEPARATOR;
 import static org.awaitility.Durations.TEN_SECONDS;
 import static org.hamcrest.CoreMatchers.hasItems;
-import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.is;
 
@@ -49,7 +48,6 @@ 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.TasksRoutes;
-import org.apache.james.webadmin.swagger.routes.SwaggerRoutes;
 import org.awaitility.Awaitility;
 import org.eclipse.jetty.http.HttpStatus;
 import org.junit.jupiter.api.Tag;
@@ -104,16 +102,6 @@ class RabbitMQWebAdminServerIntegrationTest extends WebAdminServerIntegrationTes
     }
 
     @Test
-    void getLatestVersionShouldReturnTheConfiguredLatestVersion() {
-        when()
-            .get(VERSION_LATEST)
-        .then()
-            .statusCode(HttpStatus.OK_200)
-            .contentType(JSON_CONTENT_TYPE)
-            .body(is("{\"version\":" + CassandraSchemaVersionManager.MAX_VERSION.getValue() + "}"));
-    }
-
-    @Test
     void postShouldDoMigrationAndUpdateCurrentVersion() {
         String taskId = with()
             .body(String.valueOf(CassandraSchemaVersionManager.MAX_VERSION.getValue()))
@@ -217,48 +205,4 @@ class RabbitMQWebAdminServerIntegrationTest extends WebAdminServerIntegrationTes
             .body("additionalInformation.fixedInconsistencies", hasSize(0))
             .body("additionalInformation.conflictingEntries", hasSize(0));
     }
-
-    @Test
-    void solveMessageInconsistenciesTasksShouldBeExposed() {
-        String taskId = with().post(UPGRADE_TO_LATEST_VERSION)
-            .jsonPath()
-            .get("taskId");
-
-        with()
-            .get("/tasks/" + taskId + "/await")
-        .then()
-            .body("status", is("completed"));
-
-        taskId = with()
-            .queryParam("task", "SolveInconsistencies")
-            .post("/messages")
-            .jsonPath()
-            .get("taskId");
-
-        given()
-            .basePath(TasksRoutes.BASE)
-        .when()
-            .get(taskId + "/await")
-        .then()
-            .body("status", is("completed"))
-            .body("type", is("solve-message-inconsistencies"))
-            .body("additionalInformation.processedImapUidEntries", is(0))
-            .body("additionalInformation.processedMessageIdEntries", is(0))
-            .body("additionalInformation.addedMessageIdEntries", is(0))
-            .body("additionalInformation.updatedMessageIdEntries", is(0))
-            .body("additionalInformation.removedMessageIdEntries", is(0))
-            .body("additionalInformation.runningOptions.messagesPerSecond", is(100))
-            .body("additionalInformation.fixedInconsistencies", hasSize(0))
-            .body("additionalInformation.errors", hasSize(0));
-    }
-
-    @Test
-    void getSwaggerShouldContainDistributedEndpoints() {
-        when()
-            .get(SwaggerRoutes.SWAGGER_ENDPOINT)
-        .then()
-            .statusCode(HttpStatus.OK_200)
-            .body(containsString("\"tags\":[\"Cassandra Mappings Operations\"]"))
-            .body(containsString("{\"name\":\"MessageIdReIndexing\"}"));
-    }
 }
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerTaskSerializationIntegrationImmutableTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerTaskSerializationIntegrationImmutableTest.java
new file mode 100644
index 0000000..b969e49
--- /dev/null
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerTaskSerializationIntegrationImmutableTest.java
@@ -0,0 +1,309 @@
+/****************************************************************
+ * 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 static io.restassured.RestAssured.given;
+import static io.restassured.RestAssured.with;
+import static org.apache.james.JamesServerExtension.Lifecycle.PER_CLASS;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.collection.IsMapWithSize.anEmptyMap;
+
+import org.apache.james.CassandraExtension;
+import org.apache.james.CassandraRabbitMQJamesConfiguration;
+import org.apache.james.CassandraRabbitMQJamesServerMain;
+import org.apache.james.DockerElasticSearchExtension;
+import org.apache.james.GuiceJamesServer;
+import org.apache.james.JamesServerBuilder;
+import org.apache.james.JamesServerExtension;
+import org.apache.james.SearchConfiguration;
+import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionManager;
+import org.apache.james.backends.cassandra.versions.SchemaVersion;
+import org.apache.james.junit.categories.BasicFeature;
+import org.apache.james.modules.AwsS3BlobStoreExtension;
+import org.apache.james.modules.RabbitMQExtension;
+import org.apache.james.modules.blobstore.BlobStoreConfiguration;
+import org.apache.james.probe.DataProbe;
+import org.apache.james.utils.DataProbeImpl;
+import org.apache.james.utils.WebAdminGuiceProbe;
+import org.apache.james.webadmin.WebAdminUtils;
+import org.apache.james.webadmin.integration.WebadminIntegrationTestModule;
+import org.apache.james.webadmin.routes.CassandraMappingsRoutes;
+import org.apache.james.webadmin.routes.MailQueueRoutes;
+import org.apache.james.webadmin.routes.MailRepositoriesRoutes;
+import org.apache.james.webadmin.routes.TasksRoutes;
+import org.apache.james.webadmin.vault.routes.DeletedMessagesVaultRoutes;
+import org.eclipse.jetty.http.HttpStatus;
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+
+@Tag(BasicFeature.TAG)
+class RabbitMQWebAdminServerTaskSerializationIntegrationImmutableTest {
+
+    @RegisterExtension
+    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
+        CassandraRabbitMQJamesConfiguration.builder()
+            .workingDirectory(tmpDir)
+            .configurationFromClasspath()
+            .blobStore(BlobStoreConfiguration.builder()
+                    .s3()
+                    .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 WebadminIntegrationTestModule()))
+        .lifeCycle(PER_CLASS)
+        .build();
+
+    private static final String DOMAIN = "domain";
+    private static final String USERNAME = "username@" + DOMAIN;
+
+    @BeforeAll
+    static void setUp(GuiceJamesServer guiceJamesServer) throws Exception {
+        DataProbe dataProbe = guiceJamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DOMAIN);
+        WebAdminGuiceProbe webAdminGuiceProbe = guiceJamesServer.getProbe(WebAdminGuiceProbe.class);
+
+        RestAssured.requestSpecification = WebAdminUtils.buildRequestSpecification(webAdminGuiceProbe.getWebAdminPort())
+            .build();
+        RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
+    }
+
+    @Test
+    void fullReindexingShouldCompleteWhenNoMail() {
+        String taskId = with()
+            .post("/mailboxes?task=reIndex")
+            .jsonPath()
+            .get("taskId");
+
+        given()
+            .basePath(TasksRoutes.BASE)
+        .when()
+            .get(taskId + "/await")
+        .then()
+            .body("status", is("completed"))
+            .body("taskId", is(notNullValue()))
+            .body("type", is("full-reindexing"))
+            .body("additionalInformation.successfullyReprocessedMailCount", is(0))
+            .body("additionalInformation.failedReprocessedMailCount", is(0))
+            .body("additionalInformation.messageFailures", is(anEmptyMap()));
+    }
+
+    @Test
+    void clearMailQueueShouldCompleteWhenNoQueryParameters() {
+        String firstMailQueue = with()
+                .basePath(MailQueueRoutes.BASE_URL)
+            .get()
+            .then()
+                .statusCode(HttpStatus.OK_200)
+                .contentType(ContentType.JSON)
+                .extract()
+                .body()
+                .jsonPath()
+                .getString("[0]");
+
+        String taskId = with()
+                .basePath(MailQueueRoutes.BASE_URL)
+            .delete(firstMailQueue + "/mails")
+                .jsonPath()
+                .getString("taskId");
+
+        given()
+            .basePath(TasksRoutes.BASE)
+        .when()
+            .get(taskId + "/await")
+        .then()
+            .body("status", is("completed"))
+            .body("taskId", is(Matchers.notNullValue()))
+            .body("type", is("clear-mail-queue"))
+            .body("additionalInformation.mailQueueName", is(notNullValue()))
+            .body("additionalInformation.initialCount", is(0))
+            .body("additionalInformation.remainingCount", is(0));
+    }
+
+    @Test
+    void blobStoreVaultGarbageCollectionShouldComplete() {
+        String taskId =
+            with()
+                .basePath(DeletedMessagesVaultRoutes.ROOT_PATH)
+                .queryParam("scope", "expired")
+            .delete()
+                .jsonPath()
+                .get("taskId");
+
+        given()
+            .basePath(TasksRoutes.BASE)
+        .when()
+            .get(taskId + "/await")
+        .then()
+            .body("status", is("completed"))
+            .body("taskId", is(taskId))
+            .body("type", is("deleted-messages-blob-store-based-garbage-collection"))
+            .body("additionalInformation.beginningOfRetentionPeriod", is(notNullValue()))
+            .body("additionalInformation.deletedBuckets", is(empty()));
+    }
+
+    @Test
+    void clearMailRepositoryShouldComplete() {
+        String escapedRepositoryPath = with()
+                .basePath(MailRepositoriesRoutes.MAIL_REPOSITORIES)
+            .get()
+            .then()
+                .statusCode(HttpStatus.OK_200)
+                .contentType(ContentType.JSON)
+                .extract()
+                .body()
+                .jsonPath()
+                .getString("[0].path");
+
+        String taskId = with()
+                .basePath(MailRepositoriesRoutes.MAIL_REPOSITORIES)
+            .delete(escapedRepositoryPath + "/mails")
+                .jsonPath()
+                .get("taskId");
+
+        given()
+            .basePath(TasksRoutes.BASE)
+        .when()
+            .get(taskId + "/await")
+        .then()
+            .body("status", is("completed"))
+            .body("taskId", is(taskId))
+            .body("type", is("clear-mail-repository"))
+            .body("additionalInformation.repositoryPath", is(notNullValue()))
+            .body("additionalInformation.initialCount", is(0))
+            .body("additionalInformation.remainingCount", is(0));
+    }
+
+    @Test
+    void cassandraMigrationShouldComplete() {
+        SchemaVersion toVersion = CassandraSchemaVersionManager.MAX_VERSION;
+        String taskId = with()
+                .body(String.valueOf(toVersion.getValue()))
+            .post("cassandra/version/upgrade")
+                .jsonPath()
+                .get("taskId");
+
+        given()
+            .basePath(TasksRoutes.BASE)
+        .when()
+            .get(taskId + "/await")
+        .then()
+            .body("status", is("completed"))
+            .body("taskId", is(taskId))
+            .body("type", is("cassandra-migration"))
+            .body("additionalInformation.toVersion", is(toVersion.getValue()));
+    }
+
+    @Test
+    void cassandraMappingsSolveInconsistenciesShouldComplete() {
+        String taskId = with()
+                .basePath(CassandraMappingsRoutes.ROOT_PATH)
+                .queryParam("action", "SolveInconsistencies")
+            .post()
+                .jsonPath()
+                .get("taskId");
+
+        given()
+            .basePath(TasksRoutes.BASE)
+        .when()
+            .get(taskId + "/await")
+        .then()
+            .body("status", is("completed"))
+            .body("taskId", is(taskId))
+            .body("type", is("cassandra-mappings-solve-inconsistencies"))
+            .body("additionalInformation.successfulMappingsCount", is(0))
+            .body("additionalInformation.errorMappingsCount", is(0));
+    }
+
+    @Test
+    void recomputeMailboxCountersShouldComplete() {
+        String taskId = with()
+                .basePath("/mailboxes")
+                .queryParam("task", "RecomputeMailboxCounters")
+            .post()
+                .jsonPath()
+                .get("taskId");
+
+        given()
+            .basePath(TasksRoutes.BASE)
+        .when()
+            .get(taskId + "/await")
+        .then()
+            .body("status", is("completed"))
+            .body("taskId", is(taskId))
+            .body("type", is("recompute-mailbox-counters"))
+            .body("additionalInformation.processedMailboxes", is(0));
+    }
+
+    @Test
+    void recomputeCurrentQuotasShouldComplete() {
+        String taskId = with()
+            .basePath("/quota/users")
+            .queryParam("task", "RecomputeCurrentQuotas")
+        .post()
+            .jsonPath()
+            .get("taskId");
+
+        given()
+            .basePath(TasksRoutes.BASE)
+        .when()
+            .get(taskId + "/await")
+        .then()
+            .body("status", is("completed"))
+            .body("taskId", is(taskId))
+            .body("type", is("recompute-current-quotas"))
+            .body("additionalInformation.processedQuotaRoots", is(0))
+            .body("additionalInformation.failedQuotaRoots", empty());
+    }
+
+    @Test
+    void republishNotProcessedMailsOnSpoolShouldComplete() {
+        String taskId = with()
+            .basePath("/mailQueues/spool")
+            .queryParam("action", "RepublishNotProcessedMails")
+            .queryParam("olderThan", "2d")
+        .post()
+            .jsonPath()
+        .get("taskId");
+
+        given()
+            .basePath(TasksRoutes.BASE)
+        .when()
+            .get(taskId + "/await")
+        .then()
+            .body("status", is("completed"))
+            .body("taskId", is(taskId))
+            .body("type", is("republish-not-processed-mails"))
+            .body("additionalInformation.nbRequeuedMails", is(0));
+    }
+}
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerTaskSerializationIntegrationTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerTaskSerializationIntegrationTest.java
index b20b6c0..5fb728e 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerTaskSerializationIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerTaskSerializationIntegrationTest.java
@@ -26,7 +26,6 @@ import static org.apache.james.webadmin.Constants.SEPARATOR;
 import static org.apache.james.webadmin.vault.routes.DeletedMessagesVaultRoutes.MESSAGE_PATH_PARAM;
 import static org.apache.james.webadmin.vault.routes.DeletedMessagesVaultRoutes.USERS;
 import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.Matchers.empty;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.nullValue;
 import static org.hamcrest.collection.IsMapWithSize.anEmptyMap;
@@ -45,8 +44,6 @@ import org.apache.james.GuiceJamesServer;
 import org.apache.james.JamesServerBuilder;
 import org.apache.james.JamesServerExtension;
 import org.apache.james.SearchConfiguration;
-import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionManager;
-import org.apache.james.backends.cassandra.versions.SchemaVersion;
 import org.apache.james.core.Username;
 import org.apache.james.core.builder.MimeMessageBuilder;
 import org.apache.james.events.Event;
@@ -79,7 +76,6 @@ import org.apache.james.utils.WebAdminGuiceProbe;
 import org.apache.james.webadmin.WebAdminUtils;
 import org.apache.james.webadmin.integration.WebadminIntegrationTestModule;
 import org.apache.james.webadmin.routes.CassandraMailboxMergingRoutes;
-import org.apache.james.webadmin.routes.CassandraMappingsRoutes;
 import org.apache.james.webadmin.routes.MailQueueRoutes;
 import org.apache.james.webadmin.routes.MailRepositoriesRoutes;
 import org.apache.james.webadmin.routes.TasksRoutes;
@@ -137,26 +133,6 @@ class RabbitMQWebAdminServerTaskSerializationIntegrationTest {
     }
 
     @Test
-    void fullReindexingShouldCompleteWhenNoMail() {
-        String taskId = with()
-            .post("/mailboxes?task=reIndex")
-            .jsonPath()
-            .get("taskId");
-
-        given()
-            .basePath(TasksRoutes.BASE)
-        .when()
-            .get(taskId + "/await")
-        .then()
-            .body("status", is("completed"))
-            .body("taskId", is(notNullValue()))
-            .body("type", is("full-reindexing"))
-            .body("additionalInformation.successfullyReprocessedMailCount", is(0))
-            .body("additionalInformation.failedReprocessedMailCount", is(0))
-            .body("additionalInformation.messageFailures", is(anEmptyMap()));
-    }
-
-    @Test
     void recomputeFastViewProjectionItemsShouldComplete(GuiceJamesServer server) throws Exception {
         server.getProbe(DataProbeImpl.class).addUser(USERNAME, "secret");
         mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, MailboxConstants.INBOX);
@@ -186,6 +162,30 @@ class RabbitMQWebAdminServerTaskSerializationIntegrationTest {
     }
 
     @Test
+    void singleMailboxReindexingShouldComplete(GuiceJamesServer server) {
+        MailboxId mailboxId = server.getProbe(MailboxProbeImpl.class)
+            .createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, MailboxConstants.INBOX);
+
+        String taskId = when()
+            .post("/mailboxes/" + mailboxId.serialize() + "?task=reIndex")
+            .jsonPath()
+            .get("taskId");
+
+        given()
+            .basePath(TasksRoutes.BASE)
+        .when()
+            .get(taskId + "/await")
+        .then()
+            .body("status", is("completed"))
+            .body("taskId", is(Matchers.notNullValue()))
+            .body("type", is("mailbox-reindexing"))
+            .body("additionalInformation.successfullyReprocessedMailCount", is(0))
+            .body("additionalInformation.failedReprocessedMailCount", is(0))
+            .body("additionalInformation.mailboxId", is(mailboxId.serialize()))
+            .body("additionalInformation.messageFailures", is(anEmptyMap()));
+    }
+
+    @Test
     void populateEmailQueryViewShouldComplete(GuiceJamesServer server) throws Exception {
         server.getProbe(DataProbeImpl.class).addUser(USERNAME, "secret");
         mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, MailboxConstants.INBOX);
@@ -598,92 +598,6 @@ class RabbitMQWebAdminServerTaskSerializationIntegrationTest {
     }
 
     @Test
-    void clearMailQueueShouldCompleteWhenNoQueryParameters() {
-        String firstMailQueue = with()
-                .basePath(MailQueueRoutes.BASE_URL)
-            .get()
-            .then()
-                .statusCode(HttpStatus.OK_200)
-                .contentType(ContentType.JSON)
-                .extract()
-                .body()
-                .jsonPath()
-                .getString("[0]");
-
-        String taskId = with()
-                .basePath(MailQueueRoutes.BASE_URL)
-            .delete(firstMailQueue + "/mails")
-                .jsonPath()
-                .getString("taskId");
-
-        given()
-            .basePath(TasksRoutes.BASE)
-        .when()
-            .get(taskId + "/await")
-        .then()
-            .body("status", is("completed"))
-            .body("taskId", is(Matchers.notNullValue()))
-            .body("type", is("clear-mail-queue"))
-            .body("additionalInformation.mailQueueName", is(notNullValue()))
-            .body("additionalInformation.initialCount", is(0))
-            .body("additionalInformation.remainingCount", is(0));
-    }
-
-    @Test
-    void blobStoreVaultGarbageCollectionShouldComplete() {
-        String taskId =
-            with()
-                .basePath(DeletedMessagesVaultRoutes.ROOT_PATH)
-                .queryParam("scope", "expired")
-            .delete()
-                .jsonPath()
-                .get("taskId");
-
-        given()
-            .basePath(TasksRoutes.BASE)
-        .when()
-            .get(taskId + "/await")
-        .then()
-            .body("status", is("completed"))
-            .body("taskId", is(taskId))
-            .body("type", is("deleted-messages-blob-store-based-garbage-collection"))
-            .body("additionalInformation.beginningOfRetentionPeriod", is(notNullValue()))
-            .body("additionalInformation.deletedBuckets", is(empty()));
-    }
-
-    @Test
-    void clearMailRepositoryShouldComplete() {
-        String escapedRepositoryPath = with()
-                .basePath(MailRepositoriesRoutes.MAIL_REPOSITORIES)
-            .get()
-            .then()
-                .statusCode(HttpStatus.OK_200)
-                .contentType(ContentType.JSON)
-                .extract()
-                .body()
-                .jsonPath()
-                .getString("[0].path");
-
-        String taskId = with()
-                .basePath(MailRepositoriesRoutes.MAIL_REPOSITORIES)
-            .delete(escapedRepositoryPath + "/mails")
-                .jsonPath()
-                .get("taskId");
-
-        given()
-            .basePath(TasksRoutes.BASE)
-        .when()
-            .get(taskId + "/await")
-        .then()
-            .body("status", is("completed"))
-            .body("taskId", is(taskId))
-            .body("type", is("clear-mail-repository"))
-            .body("additionalInformation.repositoryPath", is(notNullValue()))
-            .body("additionalInformation.initialCount", is(0))
-            .body("additionalInformation.remainingCount", is(0));
-    }
-
-    @Test
     void mailboxMergingShouldComplete() {
         MailboxId origin = mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, MailboxConstants.INBOX);
         MailboxId destination = mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, MailboxConstants.INBOX + "2");
@@ -713,29 +627,6 @@ class RabbitMQWebAdminServerTaskSerializationIntegrationTest {
     }
 
     @Test
-    void singleMailboxReindexingShouldComplete() {
-        MailboxId mailboxId = mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, MailboxConstants.INBOX);
-
-        String taskId = when()
-            .post("/mailboxes/" + mailboxId.serialize() + "?task=reIndex")
-                .jsonPath()
-                .get("taskId");
-
-        given()
-            .basePath(TasksRoutes.BASE)
-        .when()
-            .get(taskId + "/await")
-        .then()
-            .body("status", is("completed"))
-            .body("taskId", is(Matchers.notNullValue()))
-            .body("type", is("mailbox-reindexing"))
-            .body("additionalInformation.successfullyReprocessedMailCount", is(0))
-            .body("additionalInformation.failedReprocessedMailCount", is(0))
-            .body("additionalInformation.mailboxId", is(mailboxId.serialize()))
-            .body("additionalInformation.messageFailures", is(anEmptyMap()));
-    }
-
-    @Test
     void deletedMessagesVaultDeleteShouldCompleteEvenNoDeletedMessageExisted() throws Exception {
         dataProbe.addUser(USERNAME, "password");
         mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, MailboxConstants.INBOX);
@@ -766,88 +657,6 @@ class RabbitMQWebAdminServerTaskSerializationIntegrationTest {
             .body("additionalInformation.deleteMessageId", is(composedMessageId.getMessageId().serialize()));
     }
 
-    @Test
-    void cassandraMigrationShouldComplete() {
-        SchemaVersion toVersion = CassandraSchemaVersionManager.MAX_VERSION;
-        String taskId = with()
-                .body(String.valueOf(toVersion.getValue()))
-            .post("cassandra/version/upgrade")
-                .jsonPath()
-                .get("taskId");
-
-        given()
-            .basePath(TasksRoutes.BASE)
-        .when()
-            .get(taskId + "/await")
-        .then()
-            .body("status", is("completed"))
-            .body("taskId", is(taskId))
-            .body("type", is("cassandra-migration"))
-            .body("additionalInformation.toVersion", is(toVersion.getValue()));
-    }
-
-    @Test
-    void cassandraMappingsSolveInconsistenciesShouldComplete() {
-        String taskId = with()
-                .basePath(CassandraMappingsRoutes.ROOT_PATH)
-                .queryParam("action", "SolveInconsistencies")
-            .post()
-                .jsonPath()
-                .get("taskId");
-
-        given()
-            .basePath(TasksRoutes.BASE)
-        .when()
-            .get(taskId + "/await")
-        .then()
-            .body("status", is("completed"))
-            .body("taskId", is(taskId))
-            .body("type", is("cassandra-mappings-solve-inconsistencies"))
-            .body("additionalInformation.successfulMappingsCount", is(0))
-            .body("additionalInformation.errorMappingsCount", is(0));
-    }
-
-    @Test
-    void recomputeMailboxCountersShouldComplete() {
-        String taskId = with()
-                .basePath("/mailboxes")
-                .queryParam("task", "RecomputeMailboxCounters")
-            .post()
-                .jsonPath()
-                .get("taskId");
-
-        given()
-            .basePath(TasksRoutes.BASE)
-        .when()
-            .get(taskId + "/await")
-        .then()
-            .body("status", is("completed"))
-            .body("taskId", is(taskId))
-            .body("type", is("recompute-mailbox-counters"))
-            .body("additionalInformation.processedMailboxes", is(0));
-    }
-
-    @Test
-    void recomputeCurrentQuotasShouldComplete() {
-        String taskId = with()
-            .basePath("/quota/users")
-            .queryParam("task", "RecomputeCurrentQuotas")
-        .post()
-            .jsonPath()
-            .get("taskId");
-
-        given()
-            .basePath(TasksRoutes.BASE)
-        .when()
-            .get(taskId + "/await")
-        .then()
-            .body("status", is("completed"))
-            .body("taskId", is(taskId))
-            .body("type", is("recompute-current-quotas"))
-            .body("additionalInformation.processedQuotaRoots", is(0))
-            .body("additionalInformation.failedQuotaRoots", empty());
-    }
-
     private MailboxAdded createMailboxAdded() {
         String uuid = "6e0dd59d-660e-4d9b-b22f-0354479f47b4";
         return EventFactory.mailboxAdded()
@@ -858,25 +667,4 @@ class RabbitMQWebAdminServerTaskSerializationIntegrationTest {
             .mailboxPath(MailboxPath.forUser(Username.of(USERNAME), "Important-mailbox"))
             .build();
     }
-
-    @Test
-    void republishNotProcessedMailsOnSpoolShouldComplete() {
-        String taskId = with()
-            .basePath("/mailQueues/spool")
-            .queryParam("action", "RepublishNotProcessedMails")
-            .queryParam("olderThan", "2d")
-        .post()
-            .jsonPath()
-        .get("taskId");
-
-        given()
-            .basePath(TasksRoutes.BASE)
-        .when()
-            .get(taskId + "/await")
-        .then()
-            .body("status", is("completed"))
-            .body("taskId", is(taskId))
-            .body("type", is("republish-not-processed-mails"))
-            .body("additionalInformation.nbRequeuedMails", is(0));
-    }
 }
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 770b596..238f366 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
@@ -19,6 +19,8 @@
 
 package org.apache.james.webadmin.integration.memory;
 
+import static org.apache.james.JamesServerExtension.Lifecycle.PER_CLASS;
+
 import org.apache.james.JamesServerBuilder;
 import org.apache.james.JamesServerExtension;
 import org.apache.james.MemoryJamesServerMain;
@@ -32,7 +34,6 @@ import org.junit.jupiter.api.extension.RegisterExtension;
 import com.google.inject.name.Names;
 
 class MemoryJwtFilterIntegrationTest extends JwtFilterIntegrationTest {
-
     @RegisterExtension
     static JamesServerExtension jamesServerExtension = new JamesServerBuilder<>(JamesServerBuilder.defaultConfigurationProvider())
         .server(configuration -> MemoryJamesServerMain.createServer(configuration)
@@ -41,5 +42,6 @@ class MemoryJwtFilterIntegrationTest extends JwtFilterIntegrationTest {
             .overrideWith(binder -> binder.bind(JwtTokenVerifier.Factory.class)
                 .annotatedWith(Names.named("webadmin"))
                 .toInstance(() -> JwtTokenVerifier.create(jwtConfiguration()))))
+        .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/MemoryJwtFilterIntegrationTest.java b/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryWebAdminServerIntegrationImmutableTest.java
similarity index 69%
copy from server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryJwtFilterIntegrationTest.java
copy to server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryWebAdminServerIntegrationImmutableTest.java
index 770b596..6dafd47 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/MemoryWebAdminServerIntegrationImmutableTest.java
@@ -19,27 +19,30 @@
 
 package org.apache.james.webadmin.integration.memory;
 
+import static org.apache.james.JamesServerExtension.Lifecycle.PER_CLASS;
+
 import org.apache.james.JamesServerBuilder;
 import org.apache.james.JamesServerExtension;
 import org.apache.james.MemoryJamesServerMain;
-import org.apache.james.jwt.JwtTokenVerifier;
-import org.apache.james.webadmin.authentication.AuthenticationFilter;
-import org.apache.james.webadmin.authentication.JwtFilter;
-import org.apache.james.webadmin.integration.JwtFilterIntegrationTest;
+import org.apache.james.webadmin.RandomPortSupplier;
+import org.apache.james.webadmin.WebAdminConfiguration;
+import org.apache.james.webadmin.integration.WebAdminServerIntegrationImmutableTest;
 import org.apache.james.webadmin.integration.WebadminIntegrationTestModule;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-import com.google.inject.name.Names;
-
-class MemoryJwtFilterIntegrationTest extends JwtFilterIntegrationTest {
-
+class MemoryWebAdminServerIntegrationImmutableTest extends WebAdminServerIntegrationImmutableTest {
     @RegisterExtension
     static JamesServerExtension jamesServerExtension = new JamesServerBuilder<>(JamesServerBuilder.defaultConfigurationProvider())
         .server(configuration -> MemoryJamesServerMain.createServer(configuration)
             .overrideWith(new WebadminIntegrationTestModule())
-            .overrideWith(binder -> binder.bind(AuthenticationFilter.class).to(JwtFilter.class))
-            .overrideWith(binder -> binder.bind(JwtTokenVerifier.Factory.class)
-                .annotatedWith(Names.named("webadmin"))
-                .toInstance(() -> JwtTokenVerifier.create(jwtConfiguration()))))
+            .overrideWith(binder -> binder.bind(WebAdminConfiguration.class)
+                .toInstance(WebAdminConfiguration.builder()
+                    .enabled()
+                    .corsDisabled()
+                    .host("127.0.0.1")
+                    .port(new RandomPortSupplier())
+                    .additionalRoute("org.apache.james.webadmin.dropwizard.MetricsRoutes")
+                    .build())))
+        .lifeCycle(PER_CLASS)
         .build();
-}
+}
\ No newline at end of file
diff --git a/server/protocols/webadmin-integration-test/webadmin-integration-test-common/src/main/java/org/apache/james/webadmin/integration/JwtFilterIntegrationTest.java b/server/protocols/webadmin-integration-test/webadmin-integration-test-common/src/main/java/org/apache/james/webadmin/integration/JwtFilterIntegrationTest.java
index 860c72b..8406aee 100644
--- a/server/protocols/webadmin-integration-test/webadmin-integration-test-common/src/main/java/org/apache/james/webadmin/integration/JwtFilterIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/webadmin-integration-test-common/src/main/java/org/apache/james/webadmin/integration/JwtFilterIntegrationTest.java
@@ -48,7 +48,9 @@ public abstract class JwtFilterIntegrationTest {
     }
 
     private static final String DOMAIN = "domain";
+    private static final String DOMAIN2 = "other";
     private static final String SPECIFIC_DOMAIN = DomainsRoutes.DOMAINS + SEPARATOR + DOMAIN;
+    private static final String SPECIFIC_DOMAIN2 = DomainsRoutes.DOMAINS + SEPARATOR + DOMAIN2;
     private static final String VALID_TOKEN_ADMIN_TRUE = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbkBvcGVuL" +
         "XBhYXMub3JnIiwiYWRtaW4iOnRydWUsImlhdCI6MTQ4OTAzODQzOH0.rgxCkdWEa-92a4R-72a9Z49k4LRvQDShgci5Y7qWRUP9IGJCK-lMkrHF" +
         "4H0a6L87BYppxVW701zaZ6dNxRMvHnjLBBWnPsC2B0rkkr2hEL2zfz7sb-iNGV-J4ICx97t8-TfQ5rz3VOX0FwdusPL_rJtmlGEGRivPkR6_aBe1" +
@@ -90,12 +92,12 @@ public abstract class JwtFilterIntegrationTest {
         given()
             .header("Authorization", "Bearer " + VALID_TOKEN_ADMIN_FALSE)
         .when()
-            .put(SPECIFIC_DOMAIN)
+            .put(SPECIFIC_DOMAIN2)
         .then()
             .statusCode(HttpStatus.UNAUTHORIZED_401);
 
         assertThat(dataProbe.listDomains())
-            .doesNotContain(DOMAIN);
+            .doesNotContain(DOMAIN2);
     }
 
     @Test
@@ -103,12 +105,11 @@ public abstract class JwtFilterIntegrationTest {
         given()
             .header("Authorization", "Bearer invalid")
         .when()
-            .put(SPECIFIC_DOMAIN)
+            .put(SPECIFIC_DOMAIN2)
         .then()
             .statusCode(HttpStatus.UNAUTHORIZED_401);
 
         assertThat(dataProbe.listDomains())
-            .doesNotContain(DOMAIN);
+            .doesNotContain(DOMAIN2);
     }
-
 }
diff --git a/server/protocols/webadmin-integration-test/webadmin-integration-test-common/src/main/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationImmutableTest.java b/server/protocols/webadmin-integration-test/webadmin-integration-test-common/src/main/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationImmutableTest.java
new file mode 100644
index 0000000..219d5ff
--- /dev/null
+++ b/server/protocols/webadmin-integration-test/webadmin-integration-test-common/src/main/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationImmutableTest.java
@@ -0,0 +1,169 @@
+/****************************************************************
+ * 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;
+
+import static io.restassured.RestAssured.given;
+import static io.restassured.RestAssured.when;
+import static io.restassured.RestAssured.with;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+
+import org.apache.james.GuiceJamesServer;
+import org.apache.james.probe.DataProbe;
+import org.apache.james.utils.DataProbeImpl;
+import org.apache.james.utils.WebAdminGuiceProbe;
+import org.apache.james.webadmin.WebAdminUtils;
+import org.apache.james.webadmin.routes.HealthCheckRoutes;
+import org.apache.james.webadmin.routes.MailQueueRoutes;
+import org.apache.james.webadmin.routes.MailRepositoriesRoutes;
+import org.apache.james.webadmin.routes.TasksRoutes;
+import org.apache.james.webadmin.swagger.routes.SwaggerRoutes;
+import org.eclipse.jetty.http.HttpStatus;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import io.restassured.RestAssured;
+
+public abstract class WebAdminServerIntegrationImmutableTest {
+    private static final String DOMAIN = "domain";
+    protected static final String USERNAME = "username@" + DOMAIN;
+
+    @BeforeAll
+    static void setUp(GuiceJamesServer guiceJamesServer) throws Exception {
+        DataProbe dataProbe = guiceJamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DOMAIN);
+        WebAdminGuiceProbe webAdminGuiceProbe = guiceJamesServer.getProbe(WebAdminGuiceProbe.class);
+
+        RestAssured.requestSpecification = WebAdminUtils.buildRequestSpecification(webAdminGuiceProbe.getWebAdminPort())
+            .build();
+    }
+
+    @Test
+    void mailQueueRoutesShouldBeExposed() {
+        when()
+            .get(MailQueueRoutes.BASE_URL)
+        .then()
+            .statusCode(HttpStatus.OK_200)
+            .body("", containsInAnyOrder("spool", "outgoing"));
+    }
+
+    @Test
+    void metricsRoutesShouldBeExposed() {
+        String body = when()
+                .get("/metrics").prettyPeek()
+            .then()
+                .statusCode(HttpStatus.OK_200)
+                .extract()
+                .body()
+                .asString();
+
+        assertThat(body).contains("outgoingMails_total 0.0");
+    }
+
+    @Test
+    void healthCheckShouldReturn200WhenCalledRepeatedly() {
+        given().get(HealthCheckRoutes.HEALTHCHECK);
+        given().get(HealthCheckRoutes.HEALTHCHECK);
+        given().get(HealthCheckRoutes.HEALTHCHECK);
+        given().get(HealthCheckRoutes.HEALTHCHECK);
+        given().get(HealthCheckRoutes.HEALTHCHECK);
+
+        when()
+            .get(HealthCheckRoutes.HEALTHCHECK)
+        .then()
+            .statusCode(HttpStatus.OK_200);
+    }
+
+    @Test
+    void mailRepositoriesRoutesShouldBeExposed() {
+        when()
+            .get(MailRepositoriesRoutes.MAIL_REPOSITORIES)
+        .then()
+            .statusCode(HttpStatus.OK_200)
+            .body("repository", containsInAnyOrder(
+                "var/mail/error",
+                "var/mail/relay-denied",
+                "var/mail/address-error"));
+    }
+
+    @Test
+    void gettingANonExistingMailRepositoryShouldNotCreateIt() {
+        given()
+            .get(MailRepositoriesRoutes.MAIL_REPOSITORIES + "file%3A%2F%2Fvar%2Fmail%2Fcustom");
+
+        when()
+            .get(MailRepositoriesRoutes.MAIL_REPOSITORIES)
+        .then()
+            .statusCode(HttpStatus.OK_200)
+            .body("repository", containsInAnyOrder(
+                "var/mail/error",
+                "var/mail/relay-denied",
+                "var/mail/address-error"));
+    }
+
+    @Test
+    void getSwaggerShouldReturnJsonDataForSwagger() {
+        when()
+            .get(SwaggerRoutes.SWAGGER_ENDPOINT)
+        .then()
+            .statusCode(HttpStatus.OK_200)
+            .body(containsString("\"swagger\":\"2.0\""))
+            .body(containsString("\"info\":{\"description\":\"All the web administration API for JAMES\",\"version\":\"V1.0\",\"title\":\"JAMES Web Admin API\"}"))
+            .body(containsString("\"tags\":[\"User's Mailbox\"]"))
+            .body(containsString("\"tags\":[\"GlobalQuota\"]"))
+            .body(containsString("\"tags\":[\"DomainQuota\"]"))
+            .body(containsString("\"tags\":[\"UserQuota\"]"))
+            .body(containsString("\"tags\":[\"Domains\"]"))
+            .body(containsString("\"tags\":[\"Users\"]"))
+            .body(containsString("\"tags\":[\"MailRepositories\"]"))
+            .body(containsString("\"tags\":[\"MailQueues\"]"))
+            .body(containsString("\"tags\":[\"Address Forwards\"]"))
+            .body(containsString("\"tags\":[\"Address Aliases\"]"))
+            .body(containsString("\"tags\":[\"Address Groups\"]"))
+            .body(containsString("{\"name\":\"Mailboxes\"}"));
+    }
+
+    @Test
+    void validateHealthChecksShouldReturnOk() {
+        when()
+            .get(HealthCheckRoutes.HEALTHCHECK)
+        .then()
+            .statusCode(HttpStatus.OK_200);
+    }
+
+    @Test
+    void jmapTasksShouldBeExposed() {
+        String taskId = with()
+            .queryParam("task", "recomputeFastViewProjectionItems")
+            .post("/mailboxes")
+            .jsonPath()
+            .get("taskId");
+
+        given()
+            .basePath(TasksRoutes.BASE)
+        .when()
+            .get(taskId + "/await")
+        .then()
+            .body("status", is("completed"))
+            .body("type", is("RecomputeAllFastViewProjectionItemsTask"));
+    }
+}
\ No newline at end of file
diff --git a/server/protocols/webadmin-integration-test/webadmin-integration-test-common/src/main/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java b/server/protocols/webadmin-integration-test/webadmin-integration-test-common/src/main/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java
index 1730a1d..744ca80 100644
--- a/server/protocols/webadmin-integration-test/webadmin-integration-test-common/src/main/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/webadmin-integration-test-common/src/main/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java
@@ -95,6 +95,8 @@ public abstract class WebAdminServerIntegrationTest {
         assertThat(dataProbe.listDomains()).contains(DOMAIN);
     }
 
+
+    // Immutable
     @Test
     void mailQueueRoutesShouldBeExposed() {
         when()
@@ -104,6 +106,8 @@ public abstract class WebAdminServerIntegrationTest {
             .body("", containsInAnyOrder("spool", "outgoing"));
     }
 
+
+    // Immutable
     @Test
     void metricsRoutesShouldBeExposed() {
         String body = when()
@@ -117,6 +121,8 @@ public abstract class WebAdminServerIntegrationTest {
         assertThat(body).contains("outgoingMails_total 0.0");
     }
 
+
+    // Immutable
     @Test
     void healthCheckShouldReturn200WhenCalledRepeatedly() {
         given().get(HealthCheckRoutes.HEALTHCHECK);
@@ -131,6 +137,7 @@ public abstract class WebAdminServerIntegrationTest {
             .statusCode(HttpStatus.OK_200);
     }
 
+    // Immutable
     @Test
     void mailRepositoriesRoutesShouldBeExposed() {
         when()
@@ -143,6 +150,8 @@ public abstract class WebAdminServerIntegrationTest {
                 "var/mail/address-error"));
     }
 
+
+    // Immutable
     @Test
     void gettingANonExistingMailRepositoryShouldNotCreateIt() {
         given()
@@ -301,6 +310,7 @@ public abstract class WebAdminServerIntegrationTest {
         assertThat(members).containsOnly(USERNAME, USERNAME_2);
     }
 
+    // Immutable
     @Test
     void getSwaggerShouldReturnJsonDataForSwagger() {
         when()
@@ -323,6 +333,7 @@ public abstract class WebAdminServerIntegrationTest {
             .body(containsString("{\"name\":\"Mailboxes\"}"));
     }
 
+    // Immutable
     @Test
     void validateHealthChecksShouldReturnOk() {
         when()
@@ -331,6 +342,7 @@ public abstract class WebAdminServerIntegrationTest {
             .statusCode(HttpStatus.OK_200);
     }
 
+    // Immutable
     @Test
     void jmapTasksShouldBeExposed() {
         String taskId = with()


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