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 2019/03/12 03:19:43 UTC

[james-project] 05/15: JAMES-2665 Basic first integration test for memory and the vault

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 e7675be78f43dfaaba9e250ff8306f7422b3a61e
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue Mar 5 11:39:06 2019 +0700

    JAMES-2665 Basic first integration test for memory and the vault
    
    Exercise it on the various type of mail repositories
---
 .../mailbox/PreDeletionHookConfiguration.java      |   5 +
 .../mailbox/PreDeletionHooksConfiguration.java     |   4 +
 .../integration/DeletedMessagesVaultTest.java      | 191 +++++++++++++++++++++
 .../memory/MemoryDeletedMessagesVaultTest.java     |  50 ++++++
 ...moryFileRepositoryDeletedMessagesVaultTest.java |  50 ++++++
 .../src/test/resources/mailrepositorystore.xml     |   7 +
 6 files changed, 307 insertions(+)

diff --git a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/PreDeletionHookConfiguration.java b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/PreDeletionHookConfiguration.java
index 9e36255..e0a22f1 100644
--- a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/PreDeletionHookConfiguration.java
+++ b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/PreDeletionHookConfiguration.java
@@ -22,6 +22,7 @@ import java.util.Objects;
 
 import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.james.mailbox.extension.PreDeletionHook;
 
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
@@ -40,6 +41,10 @@ public class PreDeletionHookConfiguration {
         }
     }
 
+    public static PreDeletionHookConfiguration forClass(Class<? extends PreDeletionHook> clazz) {
+        return forClass(clazz.getName());
+    }
+
     public static PreDeletionHookConfiguration forClass(String clazz) {
         return new PreDeletionHookConfiguration(clazz);
     }
diff --git a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/PreDeletionHooksConfiguration.java b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/PreDeletionHooksConfiguration.java
index 14df7cb..eab2fcc 100644
--- a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/PreDeletionHooksConfiguration.java
+++ b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/PreDeletionHooksConfiguration.java
@@ -40,6 +40,10 @@ public class PreDeletionHooksConfiguration {
                     .collect(Guavate.toImmutableList()));
     }
 
+    public static PreDeletionHooksConfiguration forHooks(PreDeletionHookConfiguration... hooks) {
+        return new PreDeletionHooksConfiguration(ImmutableList.copyOf(hooks));
+    }
+
     public static PreDeletionHooksConfiguration none() {
         return new PreDeletionHooksConfiguration(ImmutableList.of());
     }
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/DeletedMessagesVaultTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/DeletedMessagesVaultTest.java
new file mode 100644
index 0000000..ba529c7
--- /dev/null
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/DeletedMessagesVaultTest.java
@@ -0,0 +1,191 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jmap.methods.integration;
+
+import static io.restassured.RestAssured.given;
+import static io.restassured.RestAssured.with;
+import static org.apache.james.jmap.HttpJmapAuthentication.authenticateJamesUser;
+import static org.apache.james.jmap.JmapCommonRequests.getOutboxId;
+import static org.apache.james.jmap.JmapCommonRequests.listMessageIdsForAccount;
+import static org.apache.james.jmap.JmapURIBuilder.baseUri;
+import static org.apache.james.jmap.TestingConstants.ARGUMENTS;
+import static org.apache.james.jmap.TestingConstants.DOMAIN;
+import static org.apache.james.jmap.TestingConstants.calmlyAwait;
+import static org.apache.james.jmap.TestingConstants.jmapRequestSpecBuilder;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.is;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.james.GuiceJamesServer;
+import org.apache.james.jmap.api.access.AccessToken;
+import org.apache.james.jmap.categories.BasicFeature;
+import org.apache.james.mailbox.DefaultMailboxes;
+import org.apache.james.mailbox.probe.MailboxProbe;
+import org.apache.james.modules.MailboxProbeImpl;
+import org.apache.james.probe.DataProbe;
+import org.apache.james.utils.DataProbeImpl;
+import org.apache.james.utils.JmapGuiceProbe;
+import org.apache.james.utils.WebAdminGuiceProbe;
+import org.apache.james.webadmin.WebAdminUtils;
+import org.apache.james.webadmin.routes.TasksRoutes;
+import org.awaitility.Duration;
+import org.awaitility.core.ConditionFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.google.common.base.Strings;
+
+import io.restassured.RestAssured;
+import io.restassured.parsing.Parser;
+import io.restassured.specification.RequestSpecification;
+
+public abstract class DeletedMessagesVaultTest {
+    private static final String HOMER = "homer@" + DOMAIN;
+    private static final String BART = "bart@" + DOMAIN;
+    private static final String PASSWORD = "password";
+    private static final String BOB_PASSWORD = "bobPassword";
+    private static final ConditionFactory WAIT_TWO_MINUTES = calmlyAwait.atMost(Duration.TWO_MINUTES);
+    private static final String SUBJECT = "This mail will be restored from the vault!!";
+
+    protected abstract GuiceJamesServer createJmapServer() throws IOException;
+
+    private AccessToken homerAccessToken;
+    private AccessToken bartAccessToken;
+    private GuiceJamesServer jmapServer;
+    private RequestSpecification webAdminApi;
+
+    @Before
+    public void setup() throws Throwable {
+        jmapServer = createJmapServer();
+        jmapServer.start();
+        MailboxProbe mailboxProbe = jmapServer.getProbe(MailboxProbeImpl.class);
+        DataProbe dataProbe = jmapServer.getProbe(DataProbeImpl.class);
+
+        RestAssured.requestSpecification = jmapRequestSpecBuilder
+            .setPort(jmapServer.getProbe(JmapGuiceProbe.class).getJmapPort())
+            .build();
+        RestAssured.defaultParser = Parser.JSON;
+
+        dataProbe.addDomain(DOMAIN);
+        dataProbe.addUser(HOMER, PASSWORD);
+        dataProbe.addUser(BART, BOB_PASSWORD);
+        mailboxProbe.createMailbox("#private", HOMER, DefaultMailboxes.INBOX);
+        homerAccessToken = authenticateJamesUser(baseUri(jmapServer), HOMER, PASSWORD);
+        bartAccessToken = authenticateJamesUser(baseUri(jmapServer), BART, BOB_PASSWORD);
+
+        WebAdminGuiceProbe webAdminGuiceProbe = jmapServer.getProbe(WebAdminGuiceProbe.class);
+        webAdminGuiceProbe.await();
+        webAdminApi = given()
+            .spec(WebAdminUtils
+                .buildRequestSpecification(webAdminGuiceProbe.getWebAdminPort())
+                .build());
+    }
+
+    @After
+    public void tearDown() {
+        jmapServer.stop();
+    }
+
+    @Category(BasicFeature.class)
+    @Test
+    public void shouldSendANoticeWhenThresholdExceeded() {
+        bartSendMessageToHomer();
+        WAIT_TWO_MINUTES.until(() -> listMessageIdsForAccount(homerAccessToken).size() == 1);
+
+        homerDeletesMessages(listMessageIdsForAccount(homerAccessToken));
+        WAIT_TWO_MINUTES.until(() -> listMessageIdsForAccount(homerAccessToken).size() == 0);
+
+        restoreAllMessagesOfHomer();
+        WAIT_TWO_MINUTES.until(() -> listMessageIdsForAccount(homerAccessToken).size() == 1);
+
+        String messageId = listMessageIdsForAccount(homerAccessToken).get(0);
+        given()
+            .header("Authorization", homerAccessToken.serialize())
+            .body("[[\"getMessages\", {\"ids\": [\"" + messageId + "\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .log().ifValidationFails()
+            .body(ARGUMENTS + ".list.subject", hasItem(SUBJECT));
+    }
+
+    private void bartSendMessageToHomer() {
+        String messageCreationId = "creationId";
+        String outboxId = getOutboxId(bartAccessToken);
+        String bigEnoughBody = Strings.repeat("123456789\n", 12 * 100);
+        String requestBody = "[" +
+            "  [" +
+            "    \"setMessages\"," +
+            "    {" +
+            "      \"create\": { \"" + messageCreationId  + "\" : {" +
+            "        \"headers\":{\"Disposition-Notification-To\":\"" + BART + "\"}," +
+            "        \"from\": { \"name\": \"Bob\", \"email\": \"" + BART + "\"}," +
+            "        \"to\": [{ \"name\": \"User\", \"email\": \"" + HOMER + "\"}]," +
+            "        \"subject\": \"" + SUBJECT + "\"," +
+            "        \"textBody\": \"" + bigEnoughBody + "\"," +
+            "        \"htmlBody\": \"Test <b>body</b>, HTML version\"," +
+            "        \"mailboxIds\": [\"" + outboxId + "\"] " +
+            "      }}" +
+            "    }," +
+            "    \"#0\"" +
+            "  ]" +
+            "]";
+
+        with()
+            .header("Authorization", bartAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .extract()
+            .body()
+            .path(ARGUMENTS + ".created." + messageCreationId + ".id");
+    }
+
+    private void homerDeletesMessages(List<String> idsToDestroy) {
+        String idString = idsToDestroy.stream()
+            .map(id -> "\"" + id + "\"")
+            .collect(Collectors.joining(","));
+
+        with()
+            .header("Authorization", homerAccessToken.serialize())
+            .body("[[\"setMessages\", {\"destroy\": [" + idString + "]}, \"#0\"]]")
+            .post("/jmap");
+    }
+
+    private void restoreAllMessagesOfHomer() {
+        String taskId = webAdminApi.with()
+            .post("/deletedMessages/user/" + HOMER + "?action=restore")
+            .jsonPath()
+            .get("taskId");
+
+        webAdminApi.given()
+            .basePath(TasksRoutes.BASE)
+        .when()
+            .get(taskId + "/await")
+            .then()
+            .body("status", is("completed"));
+    }
+}
diff --git a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryDeletedMessagesVaultTest.java b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryDeletedMessagesVaultTest.java
new file mode 100644
index 0000000..5f45e97
--- /dev/null
+++ b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryDeletedMessagesVaultTest.java
@@ -0,0 +1,50 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jmap.memory;
+
+import java.io.IOException;
+
+import org.apache.james.GuiceJamesServer;
+import org.apache.james.MemoryJmapTestRule;
+import org.apache.james.jmap.methods.integration.DeletedMessagesVaultTest;
+import org.apache.james.mailrepository.api.MailRepositoryUrl;
+import org.apache.james.modules.mailbox.PreDeletionHookConfiguration;
+import org.apache.james.modules.mailbox.PreDeletionHooksConfiguration;
+import org.apache.james.vault.DeletedMessageVaultHook;
+import org.apache.james.vault.MailRepositoryDeletedMessageVault;
+import org.apache.james.webadmin.WebAdminConfiguration;
+import org.junit.Rule;
+
+public class MemoryDeletedMessagesVaultTest extends DeletedMessagesVaultTest {
+
+    @Rule
+    public MemoryJmapTestRule memoryJmap = new MemoryJmapTestRule();
+
+    @Override
+    protected GuiceJamesServer createJmapServer() throws IOException {
+        return memoryJmap.jmapServer(
+            binder -> binder.bind(PreDeletionHooksConfiguration.class)
+                .toInstance(PreDeletionHooksConfiguration.forHooks(
+                    PreDeletionHookConfiguration.forClass(DeletedMessageVaultHook.class))),
+            binder -> binder.bind(WebAdminConfiguration.class).toInstance(WebAdminConfiguration.TEST_CONFIGURATION),
+            binder -> binder.bind(MailRepositoryDeletedMessageVault.Configuration.class)
+                .toInstance(new MailRepositoryDeletedMessageVault.Configuration(MailRepositoryUrl.from("memory://var/deletedMessages/user"))));
+    }
+}
diff --git a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryFileRepositoryDeletedMessagesVaultTest.java b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryFileRepositoryDeletedMessagesVaultTest.java
new file mode 100644
index 0000000..11f8373
--- /dev/null
+++ b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryFileRepositoryDeletedMessagesVaultTest.java
@@ -0,0 +1,50 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jmap.memory;
+
+import java.io.IOException;
+
+import org.apache.james.GuiceJamesServer;
+import org.apache.james.MemoryJmapTestRule;
+import org.apache.james.jmap.methods.integration.DeletedMessagesVaultTest;
+import org.apache.james.mailrepository.api.MailRepositoryUrl;
+import org.apache.james.modules.mailbox.PreDeletionHookConfiguration;
+import org.apache.james.modules.mailbox.PreDeletionHooksConfiguration;
+import org.apache.james.vault.DeletedMessageVaultHook;
+import org.apache.james.vault.MailRepositoryDeletedMessageVault;
+import org.apache.james.webadmin.WebAdminConfiguration;
+import org.junit.Rule;
+
+public class MemoryFileRepositoryDeletedMessagesVaultTest extends DeletedMessagesVaultTest {
+
+    @Rule
+    public MemoryJmapTestRule memoryJmap = new MemoryJmapTestRule();
+
+    @Override
+    protected GuiceJamesServer createJmapServer() throws IOException {
+        return memoryJmap.jmapServer(
+            binder -> binder.bind(PreDeletionHooksConfiguration.class)
+                .toInstance(PreDeletionHooksConfiguration.forHooks(
+                    PreDeletionHookConfiguration.forClass(DeletedMessageVaultHook.class))),
+            binder -> binder.bind(WebAdminConfiguration.class).toInstance(WebAdminConfiguration.TEST_CONFIGURATION),
+            binder -> binder.bind(MailRepositoryDeletedMessageVault.Configuration.class)
+                .toInstance(new MailRepositoryDeletedMessageVault.Configuration(MailRepositoryUrl.from("file://var/deletedMessages/user"))));
+    }
+}
diff --git a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailrepositorystore.xml b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailrepositorystore.xml
index 3ca4a1d..9dcd6bb 100644
--- a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailrepositorystore.xml
+++ b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailrepositorystore.xml
@@ -28,4 +28,11 @@
             <config FIFO="false" CACHEKEYS="true"/>
         </mailrepository>
     </mailrepositories>
+    <mailrepositories>
+        <mailrepository class="org.apache.james.mailrepository.memory.MemoryMailRepository">
+            <protocols>
+                <protocol>memory</protocol>
+            </protocols>
+        </mailrepository>
+    </mailrepositories>
 </mailrepositorystore>


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