james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From btell...@apache.org
Subject [5/7] james-project git commit: JAMES-2444 Can't destroy a large set of mails
Date Wed, 04 Jul 2018 02:37:32 GMT
JAMES-2444 Can't destroy a large set of mails


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/6838a981
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/6838a981
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/6838a981

Branch: refs/heads/master
Commit: 6838a981fd65d8e771bba0c4348b84acc2e5f98f
Parents: 8053572
Author: Gautier DI FOLCO <gdifolco@linagora.com>
Authored: Thu Jun 28 16:53:54 2018 +0200
Committer: benwa <btellier@linagora.com>
Committed: Wed Jul 4 09:36:06 2018 +0700

----------------------------------------------------------------------
 .../apache/james/modules/MailboxProbeImpl.java  |   9 +-
 .../cassandra/CassandraBulkOperationTest.java   | 178 +++++++++++++++++++
 2 files changed, 184 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/6838a981/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java
----------------------------------------------------------------------
diff --git a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java
b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java
index b7a85c7..637d449 100644
--- a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java
+++ b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java
@@ -62,11 +62,15 @@ public class MailboxProbeImpl implements GuiceProbe, MailboxProbe {
 
     @Override
     public MailboxId createMailbox(String namespace, String user, String name) {
+        return createMailbox(new MailboxPath(namespace, user, name));
+    }
+
+    public MailboxId createMailbox(MailboxPath mailboxPath) {
         MailboxSession mailboxSession = null;
         try {
-            mailboxSession = mailboxManager.createSystemSession(user);
+            mailboxSession = mailboxManager.createSystemSession(mailboxPath.getUser());
             mailboxManager.startProcessingRequest(mailboxSession);
-            return mailboxManager.createMailbox(new MailboxPath(namespace, user, name), mailboxSession)
+            return mailboxManager.createMailbox(mailboxPath, mailboxSession)
                     .orElseThrow(() -> new MailboxException("mailbox name is probably
empty"));
         } catch (MailboxException e) {
             throw new RuntimeException(e);
@@ -75,7 +79,6 @@ public class MailboxProbeImpl implements GuiceProbe, MailboxProbe {
         }
     }
 
-
     @Override
     public Mailbox getMailbox(String namespace, String user, String name) {
         MailboxSession mailboxSession = null;

http://git-wip-us.apache.org/repos/asf/james-project/blob/6838a981/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraBulkOperationTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraBulkOperationTest.java
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraBulkOperationTest.java
new file mode 100644
index 0000000..8aa327c
--- /dev/null
+++ b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraBulkOperationTest.java
@@ -0,0 +1,178 @@
+/****************************************************************
+ * 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.cassandra;
+
+import static com.jayway.restassured.RestAssured.given;
+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.NAME;
+import static org.apache.james.jmap.TestingConstants.jmapRequestSpecBuilder;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasSize;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.time.ZonedDateTime;
+import java.util.Date;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import org.apache.james.CassandraJmapTestRule;
+import org.apache.james.DockerCassandraRule;
+import org.apache.james.GuiceJamesServer;
+import org.apache.james.backends.cassandra.ContainerLifecycleConfiguration;
+import org.apache.james.backends.cassandra.init.configuration.CassandraConfiguration;
+import org.apache.james.jmap.HttpJmapAuthentication;
+import org.apache.james.jmap.api.access.AccessToken;
+import org.apache.james.mailbox.DefaultMailboxes;
+import org.apache.james.mailbox.MessageManager.AppendCommand;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mime4j.dom.Message;
+import org.apache.james.modules.MailboxProbeImpl;
+import org.apache.james.utils.DataProbeImpl;
+import org.apache.james.utils.JmapGuiceProbe;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+
+import com.jayway.restassured.RestAssured;
+import com.jayway.restassured.parsing.Parser;
+
+public class CassandraBulkOperationTest {
+    private static final Integer NUMBER_OF_MAIL_TO_CREATE = 250;
+
+    @ClassRule
+    public static DockerCassandraRule cassandra =  new DockerCassandraRule();
+
+    public static ContainerLifecycleConfiguration cassandraLifecycleConfiguration = ContainerLifecycleConfiguration.withDefaultIterationsBetweenRestart().container(cassandra.getRawContainer()).build();
+
+    @Rule
+    public CassandraJmapTestRule rule = CassandraJmapTestRule.defaultTestRule();
+
+    @Rule
+    public TestRule cassandraLifecycleTestRule = cassandraLifecycleConfiguration.asTestRule();
+
+    private static final String USERNAME = "username@" + DOMAIN;
+    private static final MailboxPath TRASH_PATH = MailboxPath.forUser(USERNAME, DefaultMailboxes.TRASH);
+    private static final String PASSWORD = "password";
+
+    private GuiceJamesServer jmapServer;
+
+    @Before
+    public void setup() {
+        RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
+        RestAssured.defaultParser = Parser.JSON;
+    }
+
+    @After
+    public void teardown() {
+        if (jmapServer != null) {
+            jmapServer.stop();
+        }
+    }
+
+    @Test
+    public void setMessagesShouldWorkForHugeNumberOfEmailsToTrashWhenChunksConfigurationAreLowEnough()
throws Exception {
+        jmapServer = createServerWithExpungeChunkSize(85);
+        String mailIds = provistionMails(NUMBER_OF_MAIL_TO_CREATE);
+
+        AccessToken accessToken = HttpJmapAuthentication.authenticateJamesUser(baseUri(jmapServer),
USERNAME, PASSWORD);
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"destroy\": [" + mailIds + "]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .log().ifValidationFails()
+            .body(NAME, equalTo("messagesSet"))
+            .body(ARGUMENTS + ".destroyed", hasSize(NUMBER_OF_MAIL_TO_CREATE));
+    }
+
+    @Test
+    public void setMessagesShouldFailForHugeNumberOfEmailsToTrashWhenChunksConfigurationAreTooBig()
throws Exception {
+        jmapServer = createServerWithExpungeChunkSize(NUMBER_OF_MAIL_TO_CREATE);
+        String mailIds = provistionMails(NUMBER_OF_MAIL_TO_CREATE);
+
+        AccessToken accessToken = HttpJmapAuthentication.authenticateJamesUser(baseUri(jmapServer),
USERNAME, PASSWORD);
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"destroy\": [" + mailIds + "]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(400);
+    }
+
+    private String provistionMails(int count) {
+        return IntStream.rangeClosed(1, count)
+            .mapToObj(i -> appendOneMessageToTrash())
+            .map(this::quote)
+            .collect(Collectors.joining(","));
+    }
+
+    private GuiceJamesServer createServerWithExpungeChunkSize(int expungeChunkSize) throws
Exception {
+        GuiceJamesServer jmapServer = rule.jmapServer(cassandra.getModule(),
+            binder -> binder.bind(CassandraConfiguration.class)
+                .toInstance(
+                    CassandraConfiguration.builder()
+                        .expungeChunkSize(expungeChunkSize)
+                        .build()));
+        jmapServer.start();
+        RestAssured.requestSpecification = jmapRequestSpecBuilder
+            .setPort(jmapServer.getProbe(JmapGuiceProbe.class).getJmapPort())
+            .build();
+
+        jmapServer.getProbe(DataProbeImpl.class)
+            .fluent()
+            .addDomain(DOMAIN)
+            .addUser(USERNAME, PASSWORD);
+        jmapServer.getProbe(MailboxProbeImpl.class).createMailbox(TRASH_PATH);
+        return jmapServer;
+    }
+
+    private String appendOneMessageToTrash() {
+        ZonedDateTime dateTime = ZonedDateTime.parse("2014-10-30T14:12:00Z");
+        try {
+            return jmapServer.getProbe(MailboxProbeImpl.class)
+                .appendMessage(USERNAME, TRASH_PATH,
+                    AppendCommand.builder()
+                        .build(Message.Builder
+                            .of()
+                            .setSubject("my test subject")
+                            .setBody("testmail", StandardCharsets.UTF_8)
+                            .setDate(Date.from(dateTime.toInstant()))))
+                .getMessageId()
+                .serialize();
+        } catch (MailboxException | IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private String quote(String id) {
+        return '"' + id + '"';
+    }
+
+}


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


Mime
View raw message