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 ad...@apache.org on 2017/09/13 10:57:27 UTC

[01/24] james-project git commit: MAILBOX-304 Allow to retrieve all attachments from old DAO

Repository: james-project
Updated Branches:
  refs/heads/master ed61657d2 -> 81bf0a3c8


MAILBOX-304 Allow to retrieve all attachments from old DAO


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

Branch: refs/heads/master
Commit: 9031bbd795ece9732df3fa1ab54ad0292a92783f
Parents: ed61657
Author: benwa <bt...@linagora.com>
Authored: Fri Sep 8 16:15:43 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:17:06 2017 +0200

----------------------------------------------------------------------
 .../cassandra/mail/CassandraAttachmentDAO.java  | 25 +++++++++++++-
 ...estCassandraMailboxSessionMapperFactory.java |  2 +-
 .../mail/CassandraAttachmentDAOTest.java        | 35 +++++++++++++++++++-
 .../mail/CassandraAttachmentFallbackTest.java   |  3 +-
 4 files changed, 61 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/9031bbd7/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAO.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAO.java
index df8af76..d1ec829 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAO.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAO.java
@@ -23,6 +23,7 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+import static java.lang.Math.toIntExact;
 import static org.apache.james.mailbox.cassandra.table.CassandraAttachmentTable.FIELDS;
 import static org.apache.james.mailbox.cassandra.table.CassandraAttachmentTable.ID;
 import static org.apache.james.mailbox.cassandra.table.CassandraAttachmentTable.PAYLOAD;
@@ -34,10 +35,13 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
 
 import javax.inject.Inject;
 
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
 
@@ -48,16 +52,21 @@ import com.google.common.base.Preconditions;
 
 public class CassandraAttachmentDAO {
 
+    public static final int SELECT_ALL_TIMEOUT = toIntExact(TimeUnit.DAYS.toMillis(1));
     private final CassandraAsyncExecutor cassandraAsyncExecutor;
+    private final CassandraUtils cassandraUtils;
     private final PreparedStatement insertStatement;
     private final PreparedStatement selectStatement;
+    private final PreparedStatement selectAllStatement;
 
     @Inject
-    public CassandraAttachmentDAO(Session session) {
+    public CassandraAttachmentDAO(Session session, CassandraUtils cassandraUtils) {
         this.cassandraAsyncExecutor = new CassandraAsyncExecutor(session);
 
         this.selectStatement = prepareSelect(session);
+        this.selectAllStatement = prepareSelectAll(session);
         this.insertStatement = prepareInsert(session);
+        this.cassandraUtils = cassandraUtils;
     }
 
     private PreparedStatement prepareInsert(Session session) {
@@ -75,6 +84,11 @@ public class CassandraAttachmentDAO {
             .where(eq(ID, bindMarker(ID))));
     }
 
+    private PreparedStatement prepareSelectAll(Session session) {
+        return session.prepare(select(FIELDS)
+            .from(TABLE_NAME));
+    }
+
     public CompletableFuture<Optional<Attachment>> getAttachment(AttachmentId attachmentId) {
         Preconditions.checkArgument(attachmentId != null);
         return cassandraAsyncExecutor.executeSingleRow(
@@ -83,6 +97,15 @@ public class CassandraAttachmentDAO {
             .thenApply(optional -> optional.map(this::attachment));
     }
 
+    public Stream<Attachment> retrieveAll() {
+        return cassandraUtils.convertToStream(
+            cassandraAsyncExecutor.execute(
+                selectAllStatement.bind()
+                    .setReadTimeoutMillis(SELECT_ALL_TIMEOUT)
+                    .setFetchSize(1))
+                .join())
+            .map(this::attachment);
+    }
 
     public CompletableFuture<Void> storeAttachment(Attachment attachment) throws IOException {
         return cassandraAsyncExecutor.executeVoid(

http://git-wip-us.apache.org/repos/asf/james-project/blob/9031bbd7/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
index 78667ce..c276ce2 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
@@ -58,7 +58,7 @@ public class TestCassandraMailboxSessionMapperFactory {
             new CassandraMailboxPathDAO(session, typesProvider),
             new CassandraFirstUnseenDAO(session),
             new CassandraApplicableFlagDAO(session),
-            new CassandraAttachmentDAO(session),
+            new CassandraAttachmentDAO(session, CassandraUtils.WITH_DEFAULT_CONFIGURATION),
             new CassandraAttachmentDAOV2(session),
             new CassandraDeletedMessageDAO(session),
             cassandraBlobsDAO, CassandraUtils.WITH_DEFAULT_CONFIGURATION,

http://git-wip-us.apache.org/repos/asf/james-project/blob/9031bbd7/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOTest.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOTest.java
index c44bde8..e26af08 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOTest.java
@@ -26,6 +26,7 @@ import java.util.Optional;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.DockerCassandraRule;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
 import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
@@ -34,8 +35,11 @@ import org.junit.Before;
 import org.junit.ClassRule;
 import org.junit.Test;
 
+import com.github.steveash.guavate.Guavate;
+
 public class CassandraAttachmentDAOTest {
     public static final AttachmentId ATTACHMENT_ID = AttachmentId.from("id1");
+    public static final AttachmentId ATTACHMENT_ID_2 = AttachmentId.from("id2");
 
     @ClassRule
     public static DockerCassandraRule cassandraServer = new DockerCassandraRule();
@@ -48,7 +52,7 @@ public class CassandraAttachmentDAOTest {
     public void setUp() throws Exception {
         cassandra = CassandraCluster.create(new CassandraAttachmentModule(),
             cassandraServer.getIp(), cassandraServer.getBindingPort());
-        testee = new CassandraAttachmentDAO(cassandra.getConf());
+        testee = new CassandraAttachmentDAO(cassandra.getConf(), CassandraUtils.WITH_DEFAULT_CONFIGURATION);
     }
 
     @After
@@ -64,6 +68,35 @@ public class CassandraAttachmentDAOTest {
     }
 
     @Test
+    public void retrieveAllShouldReturnEmptyByDefault() {
+        assertThat(
+            testee.retrieveAll()
+                .collect(Guavate.toImmutableList()))
+            .isEmpty();
+    }
+
+    @Test
+    public void retrieveAllShouldReturnStoredAttachments() throws Exception {
+        Attachment attachment1 = Attachment.builder()
+            .attachmentId(ATTACHMENT_ID)
+            .type("application/json")
+            .bytes("{\"property\":`\"value1\"}".getBytes(StandardCharsets.UTF_8))
+            .build();
+        Attachment attachment2 = Attachment.builder()
+            .attachmentId(ATTACHMENT_ID_2)
+            .type("application/json")
+            .bytes("{\"property\":`\"value2\"}".getBytes(StandardCharsets.UTF_8))
+            .build();
+        testee.storeAttachment(attachment1).join();
+        testee.storeAttachment(attachment2).join();
+
+        assertThat(
+            testee.retrieveAll()
+                .collect(Guavate.toImmutableList()))
+            .containsOnly(attachment1, attachment2);
+    }
+
+    @Test
     public void getAttachmentShouldReturnAttachmentWhenStored() throws Exception {
         Attachment attachment = Attachment.builder()
             .attachmentId(ATTACHMENT_ID)

http://git-wip-us.apache.org/repos/asf/james-project/blob/9031bbd7/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java
index 91a6c6c..90ad116 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java
@@ -27,6 +27,7 @@ import java.nio.charset.StandardCharsets;
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.DockerCassandraRule;
 import org.apache.james.backends.cassandra.init.CassandraModuleComposite;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
 import org.apache.james.mailbox.cassandra.ids.BlobId;
 import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraBlobModule;
@@ -65,7 +66,7 @@ public class CassandraAttachmentFallbackTest {
             cassandraServer.getBindingPort());
 
         attachmentDAOV2 = new CassandraAttachmentDAOV2(cassandra.getConf());
-        attachmentDAO = new CassandraAttachmentDAO(cassandra.getConf());
+        attachmentDAO = new CassandraAttachmentDAO(cassandra.getConf(), CassandraUtils.WITH_DEFAULT_CONFIGURATION);
         blobsDAO = new CassandraBlobsDAO(cassandra.getConf());
         attachmentMapper = new CassandraAttachmentMapper(attachmentDAO, attachmentDAOV2, blobsDAO);
     }


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


[23/24] james-project git commit: JAMES-2139 New recipients should not be duplicated when RRT

Posted by ad...@apache.org.
JAMES-2139 New recipients should not be duplicated when RRT


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

Branch: refs/heads/master
Commit: d42ec7f4acc6dd422807bd437a6ec5605f739206
Parents: 3b5180d
Author: quynhn <qn...@linagora.com>
Authored: Tue Sep 12 09:52:31 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:23:34 2017 +0200

----------------------------------------------------------------------
 .../transport/mailets/RecipientRewriteTableProcessor.java   | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/d42ec7f4/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RecipientRewriteTableProcessor.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RecipientRewriteTableProcessor.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RecipientRewriteTableProcessor.java
index b3ba95b..cbcf816 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RecipientRewriteTableProcessor.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RecipientRewriteTableProcessor.java
@@ -46,6 +46,7 @@ import com.github.steveash.guavate.Guavate;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 
 public class RecipientRewriteTableProcessor {
     private static final Logger LOGGER = LoggerFactory.getLogger(RecipientRewriteTableProcessor.class);
@@ -77,9 +78,9 @@ public class RecipientRewriteTableProcessor {
     public void processMail(Mail mail) throws MessagingException{
         ImmutableList<RrtExecutionResult> mappingDatas = toMappingDatas(mail);
 
-        ImmutableList<MailAddress> newRecipients = getRecipientsByCondition(mappingDatas, mappingData -> !mappingData.isError());
+        ImmutableSet<MailAddress> newRecipients = getRecipientsByCondition(mappingDatas, mappingData -> !mappingData.isError());
 
-        ImmutableList<MailAddress> errorMailAddresses = getRecipientsByCondition(mappingDatas, RrtExecutionResult::isError);
+        ImmutableSet<MailAddress> errorMailAddresses = getRecipientsByCondition(mappingDatas, RrtExecutionResult::isError);
 
         if (!errorMailAddresses.isEmpty()) {
             mailetContext.sendMail(mail.getSender(), errorMailAddresses, mail.getMessage(), Mail.ERROR);
@@ -93,11 +94,11 @@ public class RecipientRewriteTableProcessor {
     }
 
 
-    private ImmutableList<MailAddress> getRecipientsByCondition(ImmutableList<RrtExecutionResult> mappingDatas, Predicate<RrtExecutionResult> filterCondition) {
+    private ImmutableSet<MailAddress> getRecipientsByCondition(ImmutableList<RrtExecutionResult> mappingDatas, Predicate<RrtExecutionResult> filterCondition) {
         return mappingDatas.stream()
             .filter(filterCondition)
             .flatMap(mailAddressesFromMappingData)
-            .collect(Guavate.toImmutableList());
+            .collect(Guavate.toImmutableSet());
     }
 
     private ImmutableList<RrtExecutionResult> toMappingDatas(final Mail mail) {


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


[05/24] james-project git commit: JAMES-2143 Setting JMAP blobId Message property

Posted by ad...@apache.org.
JAMES-2143 Setting JMAP blobId Message property


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

Branch: refs/heads/master
Commit: 0024a0c76582bc90a64c7412d7de05f91739940d
Parents: 4e0e860
Author: benwa <bt...@linagora.com>
Authored: Mon Sep 11 17:34:51 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:19:53 2017 +0200

----------------------------------------------------------------------
 .../org/apache/james/mailbox/BlobManager.java   |  3 +++
 .../james/mailbox/store/StoreBlobManager.java   |  5 ++++
 .../mailbox/store/StoreBlobManagerTest.java     |  6 +++++
 .../org/apache/james/jmap/model/BlobId.java     | 11 +++++++++
 .../apache/james/jmap/model/MessageFactory.java |  8 +++++--
 .../jmap/methods/GetMessagesMethodTest.java     | 21 ++++++++++-------
 .../SetMessagesCreationProcessorTest.java       |  8 ++++++-
 .../org/apache/james/jmap/model/BlobIdTest.java |  2 +-
 .../james/jmap/model/MessageFactoryTest.java    | 24 +++++++++++++-------
 .../apache/james/jmap/send/MailFactoryTest.java |  9 ++++++--
 10 files changed, 75 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/0024a0c7/mailbox/api/src/main/java/org/apache/james/mailbox/BlobManager.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/BlobManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/BlobManager.java
index ad453b7..e41b30b 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/BlobManager.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/BlobManager.java
@@ -23,7 +23,10 @@ import org.apache.james.mailbox.exception.BlobNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Blob;
 import org.apache.james.mailbox.model.BlobId;
+import org.apache.james.mailbox.model.MessageId;
 
 public interface BlobManager {
+    BlobId toBlobId(MessageId messageId);
+
     Blob retrieve(BlobId blobId, MailboxSession mailboxSession) throws MailboxException, BlobNotFoundException;
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/0024a0c7/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
index 2869354..c70d479 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
@@ -57,6 +57,11 @@ public class StoreBlobManager implements BlobManager {
     }
 
     @Override
+    public BlobId toBlobId(MessageId messageId) {
+        return BlobId.fromString(messageId.serialize());
+    }
+
+    @Override
     public Blob retrieve(BlobId blobId, MailboxSession mailboxSession) throws MailboxException, BlobNotFoundException {
         return getBlobFromAttachment(blobId, mailboxSession)
             .orElseGet(() -> getBlobFromMessage(blobId, mailboxSession)

http://git-wip-us.apache.org/repos/asf/james-project/blob/0024a0c7/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
index 366bc76..197d8d7 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
@@ -221,4 +221,10 @@ public class StoreBlobManagerTest {
             .isInstanceOf(RuntimeException.class);
     }
 
+    @Test
+    public void toBlobIdShouldReturnBlobIdCorrespondingToAMessageId() {
+        assertThat(blobManager.toBlobId(MESSAGE_ID))
+            .isEqualTo(BlobId.fromString("125"));
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/0024a0c7/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/BlobId.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/BlobId.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/BlobId.java
index 578c09f..9c4b8df 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/BlobId.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/BlobId.java
@@ -31,6 +31,10 @@ public class BlobId {
         return new BlobId(rawValue);
     }
 
+    public static BlobId of(org.apache.james.mailbox.model.BlobId blobId) {
+        return new BlobId(blobId.asString());
+    }
+
     private final String rawValue;
     
     private BlobId(String rawValue) {
@@ -55,4 +59,11 @@ public class BlobId {
     public final int hashCode() {
         return Objects.hashCode(this.rawValue);
     }
+
+    @Override
+    public String toString() {
+        return "BlobId{" +
+            "rawValue='" + rawValue + '\'' +
+            '}';
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/0024a0c7/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageFactory.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageFactory.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageFactory.java
index 1533637..236be87 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageFactory.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageFactory.java
@@ -30,11 +30,13 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Collectors;
+
 import javax.inject.Inject;
 import javax.mail.Flags;
 import javax.mail.internet.SharedInputStream;
 
 import org.apache.james.jmap.utils.HtmlTextExtractor;
+import org.apache.james.mailbox.BlobManager;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Cid;
@@ -69,12 +71,14 @@ public class MessageFactory {
         .setMaxLineLen(-1)
         .build();
 
+    private final BlobManager blobManager;
     private final MessagePreviewGenerator messagePreview;
     private final MessageContentExtractor messageContentExtractor;
     private final HtmlTextExtractor htmlTextExtractor;
 
     @Inject
-    public MessageFactory(MessagePreviewGenerator messagePreview, MessageContentExtractor messageContentExtractor, HtmlTextExtractor htmlTextExtractor) {
+    public MessageFactory(BlobManager blobManager, MessagePreviewGenerator messagePreview, MessageContentExtractor messageContentExtractor, HtmlTextExtractor htmlTextExtractor) {
+        this.blobManager = blobManager;
         this.messagePreview = messagePreview;
         this.messageContentExtractor = messageContentExtractor;
         this.htmlTextExtractor = htmlTextExtractor;
@@ -89,7 +93,7 @@ public class MessageFactory {
         String preview = messagePreview.compute(mainTextContent);
         return Message.builder()
                 .id(message.getMessageId())
-                .blobId(BlobId.of(String.valueOf(message.getUid().asLong())))
+                .blobId(BlobId.of(blobManager.toBlobId(message.getMessageId())))
                 .threadId(message.getMessageId().serialize())
                 .mailboxIds(message.getMailboxIds())
                 .inReplyToMessageId(getHeader(mimeMessage, "in-reply-to"))

http://git-wip-us.apache.org/repos/asf/james-project/blob/0024a0c7/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMessagesMethodTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMessagesMethodTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMessagesMethodTest.java
index fb1353b..36e4348 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMessagesMethodTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMessagesMethodTest.java
@@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
+
 import java.io.ByteArrayInputStream;
 import java.util.Date;
 import java.util.List;
@@ -35,7 +36,6 @@ import java.util.stream.Collectors;
 import javax.mail.Flags;
 import javax.mail.Flags.Flag;
 
-import com.google.common.collect.ImmutableSet;
 import org.apache.commons.lang.NotImplementedException;
 import org.apache.james.jmap.model.ClientId;
 import org.apache.james.jmap.model.GetMessagesRequest;
@@ -46,6 +46,7 @@ import org.apache.james.jmap.model.MessagePreviewGenerator;
 import org.apache.james.jmap.model.MessageProperties.MessageProperty;
 import org.apache.james.jmap.utils.HtmlTextExtractor;
 import org.apache.james.jmap.utils.JsoupHtmlTextExtractor;
+import org.apache.james.mailbox.BlobManager;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
@@ -56,11 +57,18 @@ import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.inmemory.InMemoryMessageIdManager;
 import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
 import org.apache.james.mailbox.mock.MockMailboxSession;
+import org.apache.james.mailbox.model.BlobId;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.metrics.logger.DefaultMetricFactory;
 import org.apache.james.util.mime.MessageContentExtractor;
+import org.assertj.core.api.Condition;
+import org.assertj.core.data.MapEntry;
+import org.assertj.core.groups.Tuple;
+import org.junit.Before;
+import org.junit.Test;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
@@ -69,15 +77,10 @@ import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 import com.jayway.jsonpath.JsonPath;
 
-import org.assertj.core.api.Condition;
-import org.assertj.core.data.MapEntry;
-import org.assertj.core.groups.Tuple;
-import org.junit.Before;
-import org.junit.Test;
-
 public class GetMessagesMethodTest {
     private final static String FORWARDED = "forwarded";
     public static final Flags FLAGS = null;
@@ -130,7 +133,9 @@ public class GetMessagesMethodTest {
         HtmlTextExtractor htmlTextExtractor = new JsoupHtmlTextExtractor();
         MessagePreviewGenerator messagePreview = new MessagePreviewGenerator();
         MessageContentExtractor messageContentExtractor = new MessageContentExtractor();
-        MessageFactory messageFactory = new MessageFactory(messagePreview, messageContentExtractor, htmlTextExtractor);
+        BlobManager blobManager = mock(BlobManager.class);
+        when(blobManager.toBlobId(any(MessageId.class))).thenReturn(BlobId.fromString("fake"));
+        MessageFactory messageFactory = new MessageFactory(blobManager, messagePreview, messageContentExtractor, htmlTextExtractor);
         InMemoryIntegrationResources inMemoryIntegrationResources = new InMemoryIntegrationResources();
         GroupMembershipResolver groupMembershipResolver = inMemoryIntegrationResources.createGroupMembershipResolver();
         mailboxManager = inMemoryIntegrationResources.createMailboxManager(groupMembershipResolver);

http://git-wip-us.apache.org/repos/asf/james-project/blob/0024a0c7/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMessagesCreationProcessorTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMessagesCreationProcessorTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMessagesCreationProcessorTest.java
index 84bf14d..8f15c63 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMessagesCreationProcessorTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMessagesCreationProcessorTest.java
@@ -26,11 +26,13 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+
 import java.io.InputStream;
 import java.sql.Date;
 import java.util.Optional;
 import java.util.function.Supplier;
 import java.util.stream.Stream;
+
 import javax.mail.Flags;
 
 import org.apache.james.jmap.exceptions.AttachmentsNotFoundException;
@@ -53,6 +55,7 @@ import org.apache.james.jmap.send.MailSpool;
 import org.apache.james.jmap.utils.HtmlTextExtractor;
 import org.apache.james.jmap.utils.SystemMailboxesProvider;
 import org.apache.james.mailbox.AttachmentManager;
+import org.apache.james.mailbox.BlobManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
@@ -63,6 +66,7 @@ import org.apache.james.mailbox.mock.MockMailboxSession;
 import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.metrics.api.NoopMetricFactory;
 import org.apache.james.util.OptionalUtils;
@@ -124,7 +128,9 @@ public class SetMessagesCreationProcessorTest {
         MessagePreviewGenerator messagePreview = mock(MessagePreviewGenerator.class);
         MessageContentExtractor messageContentExtractor = new MessageContentExtractor();
         when(messagePreview.compute(any())).thenReturn("text preview");
-        messageFactory = new MessageFactory(messagePreview, messageContentExtractor, htmlTextExtractor);
+        BlobManager blobManager = mock(BlobManager.class);
+        when(blobManager.toBlobId(any(MessageId.class))).thenReturn(org.apache.james.mailbox.model.BlobId.fromString("fake"));
+        messageFactory = new MessageFactory(blobManager, messagePreview, messageContentExtractor, htmlTextExtractor);
         mockedMailSpool = mock(MailSpool.class);
         mockedMailFactory = mock(MailFactory.class);
         mockedAttachmentManager = mock(AttachmentManager.class);

http://git-wip-us.apache.org/repos/asf/james-project/blob/0024a0c7/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/BlobIdTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/BlobIdTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/BlobIdTest.java
index bf04a1e..1fb256e 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/BlobIdTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/BlobIdTest.java
@@ -34,7 +34,7 @@ public class BlobIdTest {
 
     @Test
     public void shouldNotAllowNullInput() {
-        assertThatThrownBy(() -> BlobId.of(null)).isInstanceOf(IllegalArgumentException.class);
+        assertThatThrownBy(() -> BlobId.of((String) null)).isInstanceOf(IllegalArgumentException.class);
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/james-project/blob/0024a0c7/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MessageFactoryTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MessageFactoryTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MessageFactoryTest.java
index 76a5e14..2d86294 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MessageFactoryTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MessageFactoryTest.java
@@ -19,33 +19,39 @@
 package org.apache.james.jmap.model;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import java.io.ByteArrayInputStream;
 import java.time.Instant;
 import java.util.Optional;
+
 import javax.mail.Flags;
 import javax.mail.Flags.Flag;
 
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.james.jmap.model.MessageFactory.MetaDataWithContent;
 import org.apache.james.jmap.utils.HtmlTextExtractor;
 import org.apache.james.jmap.utils.JsoupHtmlTextExtractor;
+import org.apache.james.mailbox.BlobManager;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.Cid;
 import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.util.mime.MessageContentExtractor;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
+import org.junit.Before;
+import org.junit.Test;
 
 import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 
-import org.junit.Before;
-import org.junit.Test;
-
 public class MessageFactoryTest {
     private static final String FORWARDED = "forwarded";
     private static final InMemoryId MAILBOX_ID = InMemoryId.of(18L);
@@ -62,7 +68,9 @@ public class MessageFactoryTest {
         messagePreview = new MessagePreviewGenerator();
         MessageContentExtractor messageContentExtractor = new MessageContentExtractor();
 
-        messageFactory = new MessageFactory(messagePreview, messageContentExtractor, htmlTextExtractor);
+        BlobManager blobManager = mock(BlobManager.class);
+        when(blobManager.toBlobId(any(MessageId.class))).thenReturn(org.apache.james.mailbox.model.BlobId.fromString("blobId"));
+        messageFactory = new MessageFactory(blobManager, messagePreview, messageContentExtractor, htmlTextExtractor);
     }
 
     @Test
@@ -151,7 +159,7 @@ public class MessageFactoryTest {
         Message testee = messageFactory.fromMetaDataWithContent(testMail);
         Message expected = Message.builder()
                 .id(TestMessageId.of(2))
-                .blobId(BlobId.of("2"))
+                .blobId(BlobId.of("blobId"))
                 .threadId("2")
                 .mailboxId(MAILBOX_ID)
                 .inReplyToMessageId("<SN...@phx.gbl>")
@@ -205,7 +213,7 @@ public class MessageFactoryTest {
         Message testee = messageFactory.fromMetaDataWithContent(testMail);
         Message expected = Message.builder()
             .id(TestMessageId.of(2))
-            .blobId(BlobId.of("2"))
+            .blobId(BlobId.of("blobId"))
             .threadId("2")
             .mailboxId(MAILBOX_ID)
             .headers(headersMap)

http://git-wip-us.apache.org/repos/asf/james-project/blob/0024a0c7/server/protocols/jmap/src/test/java/org/apache/james/jmap/send/MailFactoryTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/send/MailFactoryTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/send/MailFactoryTest.java
index bec084b..dd5e0f7 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/send/MailFactoryTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/send/MailFactoryTest.java
@@ -29,19 +29,22 @@ import java.util.Collection;
 import javax.mail.Flags;
 import javax.mail.util.SharedByteArrayInputStream;
 
+import org.apache.james.core.MailAddress;
 import org.apache.james.jmap.model.Message;
 import org.apache.james.jmap.model.MessageFactory;
 import org.apache.james.jmap.model.MessageFactory.MetaDataWithContent;
 import org.apache.james.jmap.model.MessagePreviewGenerator;
 import org.apache.james.jmap.utils.HtmlTextExtractor;
+import org.apache.james.mailbox.BlobManager;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.inmemory.InMemoryId;
+import org.apache.james.mailbox.model.BlobId;
+import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.util.mime.MessageContentExtractor;
 import org.apache.mailet.Mail;
-import org.apache.james.core.MailAddress;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -81,7 +84,9 @@ public class MailFactoryTest {
         when(messagePreview.compute(any())).thenReturn("text preview");
 
         MessageContentExtractor messageContentExtractor = new MessageContentExtractor();
-        MessageFactory messageFactory = new MessageFactory(messagePreview, messageContentExtractor, htmlTextExtractor);
+        BlobManager blobManager = mock(BlobManager.class);
+        when(blobManager.toBlobId(any(MessageId.class))).thenReturn(BlobId.fromString("fake"));
+        MessageFactory messageFactory = new MessageFactory(blobManager, messagePreview, messageContentExtractor, htmlTextExtractor);
         jmapMessage = messageFactory.fromMetaDataWithContent(message);
     }
 


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


[20/24] james-project git commit: JAMES-2139 No testing function on production code

Posted by ad...@apache.org.
JAMES-2139 No testing function on production code


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

Branch: refs/heads/master
Commit: 87067965459c7b8029a72826bb30ee33ae456c48
Parents: 895a004
Author: quynhn <qn...@linagora.com>
Authored: Fri Sep 8 16:36:00 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:23:33 2017 +0200

----------------------------------------------------------------------
 pom.xml                                         |  6 +++
 server/mailet/integration-testing/pom.xml       |  1 +
 .../james/mailets/TemporaryJamesServer.java     |  3 +-
 .../transport/mailets/GroupMappingTest.java     | 14 ++++++
 .../protocols/webadmin-integration-test/pom.xml |  1 +
 .../WebAdminConfigurationModule.java            |  3 +-
 .../webadmin/webadmin-cassandra/pom.xml         |  6 +++
 .../routes/CassandraMigrationRoutesTest.java    |  4 +-
 .../james/webadmin/WebAdminConfiguration.java   |  7 ---
 .../apache/james/webadmin/WebAdminServer.java   | 10 +----
 .../apache/james/webadmin/WebAdminUtils.java    | 45 ++++++++++++++++++++
 server/protocols/webadmin/webadmin-data/pom.xml |  6 +++
 .../webadmin/routes/DomainsRoutesTest.java      |  3 +-
 .../james/webadmin/routes/GroupsRoutesTest.java |  3 +-
 .../james/webadmin/routes/UsersRoutesTest.java  |  3 +-
 .../protocols/webadmin/webadmin-mailbox/pom.xml |  6 +++
 .../webadmin/routes/GlobalQuotaRoutesTest.java  |  3 +-
 .../routes/UserMailboxesRoutesTest.java         |  3 +-
 18 files changed, 103 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index b136d64..08610af 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1348,6 +1348,12 @@
             </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
+                <artifactId>james-server-webadmin-core</artifactId>
+                <version>${project.version}</version>
+                <type>test-jar</type>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
                 <artifactId>james-server-webadmin-data</artifactId>
                 <version>${project.version}</version>
             </dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/server/mailet/integration-testing/pom.xml
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/pom.xml b/server/mailet/integration-testing/pom.xml
index a148d31..147b510 100644
--- a/server/mailet/integration-testing/pom.xml
+++ b/server/mailet/integration-testing/pom.xml
@@ -91,6 +91,7 @@
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>james-server-webadmin-core</artifactId>
+            <type>test-jar</type>
             <scope>test</scope>
         </dependency>
         <dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/TemporaryJamesServer.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/TemporaryJamesServer.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/TemporaryJamesServer.java
index 55f3f05..e6ad1bf 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/TemporaryJamesServer.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/TemporaryJamesServer.java
@@ -37,6 +37,7 @@ import org.apache.james.mailets.configuration.MailetContainer;
 import org.apache.james.modules.TestJMAPServerModule;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.webadmin.WebAdminConfiguration;
+import org.apache.james.webadmin.WebAdminUtils;
 import org.junit.rules.TemporaryFolder;
 
 import com.google.common.collect.ImmutableList;
@@ -61,7 +62,7 @@ public class TemporaryJamesServer {
             .overrideWith(additionalModules)
             .overrideWith(new TestJMAPServerModule(LIMIT_TO_3_MESSAGES))
             .overrideWith(new TemporaryFilesystemModule(temporaryFolder))
-            .overrideWith((binder) -> binder.bind(WebAdminConfiguration.class).toProvider(WebAdminConfiguration::testingConfiguration));
+            .overrideWith((binder) -> binder.bind(WebAdminConfiguration.class).toProvider(WebAdminUtils::webAdminConfigurationForTesting));
 
         jamesServer.start();
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
index 37b16bd..f391fff 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
@@ -20,6 +20,9 @@
 package org.apache.james.transport.mailets;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+
+import java.util.concurrent.TimeUnit;
 
 import javax.mail.internet.MimeMessage;
 
@@ -103,6 +106,17 @@ public class GroupMappingTest {
                     .match("RecipientIsLocal")
                     .clazz("LocalDelivery")
                     .build())
+                .addMailet(MailetConfiguration.builder()
+                    .match("All")
+                    .clazz("RemoteDelivery")
+                    .addProperty("outgoingQueue", "outgoing")
+                    .addProperty("delayTime", "5000, 100000, 500000")
+                    .addProperty("maxRetries", "25")
+                    .addProperty("maxDnsProblemRetries", "0")
+                    .addProperty("deliveryThreads", "10")
+                    .addProperty("sendpartial", "true")
+                    .addProperty("bounceProcessor", "bounces")
+                    .build())
                 .build())
             .build();
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/server/protocols/webadmin-integration-test/pom.xml
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin-integration-test/pom.xml b/server/protocols/webadmin-integration-test/pom.xml
index 319b8b2..6de1b54 100644
--- a/server/protocols/webadmin-integration-test/pom.xml
+++ b/server/protocols/webadmin-integration-test/pom.xml
@@ -77,6 +77,7 @@
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>james-server-webadmin-core</artifactId>
+            <type>test-jar</type>
             <scope>test</scope>
         </dependency>
         <dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminConfigurationModule.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminConfigurationModule.java b/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminConfigurationModule.java
index 6f5ec20..8bcf260 100644
--- a/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminConfigurationModule.java
+++ b/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminConfigurationModule.java
@@ -20,6 +20,7 @@
 package org.apache.james.webadmin.integration;
 
 import org.apache.james.webadmin.WebAdminConfiguration;
+import org.apache.james.webadmin.WebAdminUtils;
 
 import com.google.inject.AbstractModule;
 
@@ -27,7 +28,7 @@ public class WebAdminConfigurationModule extends AbstractModule {
 
     @Override
     protected void configure() {
-        bind(WebAdminConfiguration.class).toProvider(WebAdminConfiguration::testingConfiguration);
+        bind(WebAdminConfiguration.class).toProvider(WebAdminUtils::webAdminConfigurationForTesting);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/server/protocols/webadmin/webadmin-cassandra/pom.xml
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-cassandra/pom.xml b/server/protocols/webadmin/webadmin-cassandra/pom.xml
index 05e89ba..b88f6d0 100644
--- a/server/protocols/webadmin/webadmin-cassandra/pom.xml
+++ b/server/protocols/webadmin/webadmin-cassandra/pom.xml
@@ -43,6 +43,12 @@
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-webadmin-core</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>metrics-logger</artifactId>
             <scope>test</scope>
         </dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/server/protocols/webadmin/webadmin-cassandra/src/test/java/org/apache/james/webadmin/routes/CassandraMigrationRoutesTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-cassandra/src/test/java/org/apache/james/webadmin/routes/CassandraMigrationRoutesTest.java b/server/protocols/webadmin/webadmin-cassandra/src/test/java/org/apache/james/webadmin/routes/CassandraMigrationRoutesTest.java
index d3554d0..e647011 100644
--- a/server/protocols/webadmin/webadmin-cassandra/src/test/java/org/apache/james/webadmin/routes/CassandraMigrationRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-cassandra/src/test/java/org/apache/james/webadmin/routes/CassandraMigrationRoutesTest.java
@@ -40,6 +40,7 @@ import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionDAO;
 import org.apache.james.mailbox.cassandra.mail.migration.Migration;
 import org.apache.james.metrics.logger.DefaultMetricFactory;
 import org.apache.james.webadmin.WebAdminServer;
+import org.apache.james.webadmin.WebAdminUtils;
 import org.apache.james.webadmin.service.CassandraMigrationService;
 import org.apache.james.webadmin.utils.JsonTransformer;
 import org.junit.After;
@@ -72,9 +73,10 @@ public class CassandraMigrationRoutesTest {
             .build();
         schemaVersionDAO = mock(CassandraSchemaVersionDAO.class);
 
-        webAdminServer = new WebAdminServer(
+        webAdminServer = WebAdminUtils.createWebAdminServer(
             new DefaultMetricFactory(),
             new CassandraMigrationRoutes(new CassandraMigrationService(schemaVersionDAO, allMigrationClazz, LATEST_VERSION), new JsonTransformer()));
+
         webAdminServer.configure(NO_CONFIGURATION);
         webAdminServer.await();
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java
index b7608cf..8db2976 100644
--- a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java
@@ -32,13 +32,6 @@ public class WebAdminConfiguration {
     public static final String CORS_ALL_ORIGINS = "*";
     public static final String DEFAULT_HOST = "localhost";
 
-    public static WebAdminConfiguration testingConfiguration() {
-        return WebAdminConfiguration.builder()
-            .enabled()
-            .port(new RandomPort())
-            .build();
-    }
-
     public static final WebAdminConfiguration DISABLED_CONFIGURATION = WebAdminConfiguration.builder()
         .disabled()
         .build();

http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminServer.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminServer.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminServer.java
index ba27d1c..444f5b8 100644
--- a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminServer.java
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminServer.java
@@ -58,7 +58,7 @@ public class WebAdminServer implements Configurable {
 
     // Spark do not allow to retrieve allocated port when using a random port. Thus we generate the port.
     @Inject
-    private WebAdminServer(WebAdminConfiguration configuration, Set<Routes> routesList, AuthenticationFilter authenticationFilter,
+    protected WebAdminServer(WebAdminConfiguration configuration, Set<Routes> routesList, AuthenticationFilter authenticationFilter,
                            MetricFactory metricFactory) {
         this.configuration = configuration;
         this.routesList = routesList;
@@ -67,14 +67,6 @@ public class WebAdminServer implements Configurable {
         this.service = Service.ignite();
     }
 
-    @VisibleForTesting
-    public WebAdminServer(MetricFactory metricFactory, Routes... routes) throws IOException {
-        this(WebAdminConfiguration.testingConfiguration(),
-            ImmutableSet.copyOf(routes),
-            new NoAuthenticationFilter(),
-            metricFactory);
-    }
-
     @Override
     public void configure(HierarchicalConfiguration config) throws ConfigurationException {
         if (configuration.isEnabled()) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/WebAdminUtils.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/WebAdminUtils.java b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/WebAdminUtils.java
new file mode 100644
index 0000000..3ff8c02
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/WebAdminUtils.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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;
+
+import java.io.IOException;
+
+import org.apache.james.metrics.api.MetricFactory;
+import org.apache.james.webadmin.authentication.NoAuthenticationFilter;
+
+import com.google.common.collect.ImmutableSet;
+
+public class WebAdminUtils {
+
+    public static WebAdminConfiguration webAdminConfigurationForTesting() {
+        return WebAdminConfiguration.builder()
+            .enabled()
+            .port(new RandomPort())
+            .build();
+    }
+
+    public static WebAdminServer createWebAdminServer(MetricFactory metricFactory, Routes... routes) throws IOException {
+        return new WebAdminServer(webAdminConfigurationForTesting(),
+            ImmutableSet.copyOf(routes),
+            new NoAuthenticationFilter(),
+            metricFactory);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/server/protocols/webadmin/webadmin-data/pom.xml
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/pom.xml b/server/protocols/webadmin/webadmin-data/pom.xml
index 6f302db..8fbe4f9 100644
--- a/server/protocols/webadmin/webadmin-data/pom.xml
+++ b/server/protocols/webadmin/webadmin-data/pom.xml
@@ -54,6 +54,12 @@
             <groupId>${project.groupId}</groupId>
             <artifactId>james-server-webadmin-core</artifactId>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-webadmin-core</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
 
         <dependency>
             <groupId>${project.groupId}</groupId>

http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DomainsRoutesTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DomainsRoutesTest.java b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DomainsRoutesTest.java
index c3eeaad..5e825e8 100644
--- a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DomainsRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DomainsRoutesTest.java
@@ -42,6 +42,7 @@ import org.apache.james.domainlist.api.DomainListException;
 import org.apache.james.domainlist.memory.MemoryDomainList;
 import org.apache.james.metrics.logger.DefaultMetricFactory;
 import org.apache.james.webadmin.WebAdminServer;
+import org.apache.james.webadmin.WebAdminUtils;
 import org.apache.james.webadmin.utils.JsonTransformer;
 import org.junit.After;
 import org.junit.Before;
@@ -61,7 +62,7 @@ public class DomainsRoutesTest {
     private WebAdminServer webAdminServer;
 
     private void createServer(DomainList domainList) throws Exception {
-        webAdminServer = new WebAdminServer(
+        webAdminServer = WebAdminUtils.createWebAdminServer(
             new DefaultMetricFactory(),
             new DomainsRoutes(domainList, new JsonTransformer()));
         webAdminServer.configure(NO_CONFIGURATION);

http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/GroupsRoutesTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/GroupsRoutesTest.java b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/GroupsRoutesTest.java
index f866f6a..9cda34c 100644
--- a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/GroupsRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/GroupsRoutesTest.java
@@ -46,6 +46,7 @@ import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.user.memory.MemoryUsersRepository;
 import org.apache.james.webadmin.WebAdminServer;
+import org.apache.james.webadmin.WebAdminUtils;
 import org.apache.james.webadmin.utils.JsonTransformer;
 import org.eclipse.jetty.http.HttpStatus;
 import org.junit.After;
@@ -72,7 +73,7 @@ public class GroupsRoutesTest {
     private WebAdminServer webAdminServer;
 
     private void createServer(GroupsRoutes groupsRoutes) throws Exception {
-        webAdminServer = new WebAdminServer(
+        webAdminServer = WebAdminUtils.createWebAdminServer(
             new DefaultMetricFactory(),
             groupsRoutes);
         webAdminServer.configure(NO_CONFIGURATION);

http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/UsersRoutesTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/UsersRoutesTest.java b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/UsersRoutesTest.java
index c1c7527..a073b57 100644
--- a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/UsersRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/UsersRoutesTest.java
@@ -42,6 +42,7 @@ import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.user.api.model.User;
 import org.apache.james.user.memory.MemoryUsersRepository;
 import org.apache.james.webadmin.WebAdminServer;
+import org.apache.james.webadmin.WebAdminUtils;
 import org.apache.james.webadmin.service.UserService;
 import org.apache.james.webadmin.utils.JsonTransformer;
 import org.junit.After;
@@ -64,7 +65,7 @@ public class UsersRoutesTest {
     private WebAdminServer webAdminServer;
 
     private void createServer(UsersRepository usersRepository) throws Exception {
-        webAdminServer = new WebAdminServer(
+        webAdminServer = WebAdminUtils.createWebAdminServer(
             new DefaultMetricFactory(),
             new UserRoutes(new UserService(usersRepository), new JsonTransformer()));
         webAdminServer.configure(NO_CONFIGURATION);

http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/server/protocols/webadmin/webadmin-mailbox/pom.xml
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailbox/pom.xml b/server/protocols/webadmin/webadmin-mailbox/pom.xml
index 13b8b4d..471f8dd 100644
--- a/server/protocols/webadmin/webadmin-mailbox/pom.xml
+++ b/server/protocols/webadmin/webadmin-mailbox/pom.xml
@@ -61,6 +61,12 @@
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-webadmin-core</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>metrics-logger</artifactId>
             <scope>test</scope>
         </dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/GlobalQuotaRoutesTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/GlobalQuotaRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/GlobalQuotaRoutesTest.java
index 4d6f8bd..a1e3971 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/GlobalQuotaRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/GlobalQuotaRoutesTest.java
@@ -29,6 +29,7 @@ import org.apache.james.mailbox.inmemory.quota.InMemoryPerUserMaxQuotaManager;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.metrics.logger.DefaultMetricFactory;
 import org.apache.james.webadmin.WebAdminServer;
+import org.apache.james.webadmin.WebAdminUtils;
 import org.apache.james.webadmin.utils.JsonTransformer;
 import org.junit.After;
 import org.junit.Before;
@@ -48,7 +49,7 @@ public class GlobalQuotaRoutesTest {
     @Before
     public void setUp() throws Exception {
         maxQuotaManager = new InMemoryPerUserMaxQuotaManager();
-        webAdminServer = new WebAdminServer(
+        webAdminServer = WebAdminUtils.createWebAdminServer(
             new DefaultMetricFactory(),
             new GlobalQuotaRoutes(maxQuotaManager, new JsonTransformer()));
         webAdminServer.configure(NO_CONFIGURATION);

http://git-wip-us.apache.org/repos/asf/james-project/blob/87067965/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java
index 7ae6ce4..c62dcd6 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java
@@ -58,6 +58,7 @@ import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
 import org.apache.james.metrics.logger.DefaultMetricFactory;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.webadmin.WebAdminServer;
+import org.apache.james.webadmin.WebAdminUtils;
 import org.apache.james.webadmin.service.UserMailboxesService;
 import org.apache.james.webadmin.utils.JsonTransformer;
 import org.junit.After;
@@ -86,7 +87,7 @@ public class UserMailboxesRoutesTest {
         usersRepository = mock(UsersRepository.class);
         when(usersRepository.contains(USERNAME)).thenReturn(true);
 
-        webAdminServer = new WebAdminServer(
+        webAdminServer = WebAdminUtils.createWebAdminServer(
             new DefaultMetricFactory(),
             new UserMailboxesRoutes(new UserMailboxesService(mailboxManager, usersRepository), new JsonTransformer()));
         webAdminServer.configure(NO_CONFIGURATION);


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


[18/24] james-project git commit: MAILBOX-305 Introduce the new table attachmentId -> messageIds

Posted by ad...@apache.org.
MAILBOX-305 Introduce the new table attachmentId -> messageIds


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

Branch: refs/heads/master
Commit: 1b4d92391c8e566c81297ae98ba4c75ae3e32408
Parents: 035f0f7
Author: Raphael Ouazana <ra...@linagora.com>
Authored: Mon Sep 11 13:01:07 2017 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:21:57 2017 +0200

----------------------------------------------------------------------
 .../apache/james/mailbox/AttachmentManager.java |   5 +-
 .../CassandraMailboxSessionMapperFactory.java   |   7 +-
 .../cassandra/CassandraMessageManager.java      |   5 +-
 .../mail/CassandraAttachmentMapper.java         |  29 +++-
 .../mail/CassandraAttachmentMessageIdDAO.java   | 101 ++++++++++++++
 .../modules/CassandraAttachmentModule.java      |  14 +-
 .../CassandraAttachmentMessageIdTable.java      |  30 +++++
 .../CassandraSubscriptionManagerTest.java       |   3 +
 ...estCassandraMailboxSessionMapperFactory.java |   5 +-
 .../mail/CassandraAttachmentFallbackTest.java   |   5 +-
 .../mail/CassandraAttachmentMapperTest.java     |   7 +
 .../inmemory/InMemoryMessageManager.java        |   5 +-
 .../inmemory/mail/InMemoryAttachmentMapper.java |  14 +-
 .../mail/MemoryAttachmentMapperTest.java        |   7 +
 .../mailbox/store/StoreAttachmentManager.java   |  10 +-
 .../mailbox/store/mail/AttachmentMapper.java    |   5 +-
 .../store/mail/model/AttachmentMapperTest.java  | 134 ++++++++++++++++++-
 17 files changed, 363 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/1b4d9239/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
index e9f2e0f..a03bb53 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
@@ -26,6 +26,7 @@ import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.MessageId;
 
 public interface AttachmentManager {
 
@@ -35,5 +36,7 @@ public interface AttachmentManager {
 
     void storeAttachment(Attachment attachment, MailboxSession mailboxSession) throws MailboxException;
 
-    void storeAttachments(Collection<Attachment> attachments, MailboxSession mailboxSession) throws MailboxException;
+    void storeAttachmentsForMessage(Collection<Attachment> attachments, MessageId ownerMessageId, MailboxSession mailboxSession) throws MailboxException;
+
+    Collection<MessageId> getOwnerMessageIds(AttachmentId attachmentId, MailboxSession mailboxSession) throws MailboxException;
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/1b4d9239/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
index 85e3349..9d4e059 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
@@ -29,6 +29,7 @@ import org.apache.james.mailbox.cassandra.mail.CassandraApplicableFlagDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAOV2;
 import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentMapper;
+import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentMessageIdDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraBlobsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraDeletedMessageDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraFirstUnseenDAO;
@@ -82,6 +83,7 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa
     private final CassandraAttachmentDAOV2 attachmentDAOV2;
     private final CassandraDeletedMessageDAO deletedMessageDAO;
     private final CassandraBlobsDAO blobsDAO;
+    private final CassandraAttachmentMessageIdDAO attachementMessageIdDAO;
     private CassandraUtils cassandraUtils;
     private CassandraConfiguration cassandraConfiguration;
 
@@ -92,7 +94,7 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa
                                                 CassandraMailboxCounterDAO mailboxCounterDAO, CassandraMailboxRecentsDAO mailboxRecentsDAO, CassandraMailboxDAO mailboxDAO,
                                                 CassandraMailboxPathDAO mailboxPathDAO, CassandraFirstUnseenDAO firstUnseenDAO, CassandraApplicableFlagDAO applicableFlagDAO,
                                                 CassandraAttachmentDAO attachmentDAO, CassandraAttachmentDAOV2 attachmentDAOV2, CassandraDeletedMessageDAO deletedMessageDAO,
-                                                CassandraBlobsDAO blobsDAO, CassandraUtils cassandraUtils, CassandraConfiguration cassandraConfiguration) {
+                                                CassandraBlobsDAO blobsDAO, CassandraAttachmentMessageIdDAO attachementMessageIdDAO, CassandraUtils cassandraUtils, CassandraConfiguration cassandraConfiguration) {
         this.uidProvider = uidProvider;
         this.modSeqProvider = modSeqProvider;
         this.session = session;
@@ -109,6 +111,7 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa
         this.deletedMessageDAO = deletedMessageDAO;
         this.applicableFlagDAO = applicableFlagDAO;
         this.blobsDAO = blobsDAO;
+        this.attachementMessageIdDAO = attachementMessageIdDAO;
         this.cassandraUtils = cassandraUtils;
         this.cassandraConfiguration = cassandraConfiguration;
         this.indexTableHandler = new CassandraIndexTableHandler(
@@ -153,7 +156,7 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa
 
     @Override
     public CassandraAttachmentMapper createAttachmentMapper(MailboxSession mailboxSession) {
-        return new CassandraAttachmentMapper(attachmentDAO, attachmentDAOV2, blobsDAO);
+        return new CassandraAttachmentMapper(attachmentDAO, attachmentDAOV2, blobsDAO, attachementMessageIdDAO);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/1b4d9239/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
index 0a8890d..523cad8 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
@@ -74,9 +74,10 @@ public class CassandraMessageManager extends StoreMessageManager {
     @Override
     protected void storeAttachment(final MailboxMessage message, final List<MessageAttachment> messageAttachments, final MailboxSession session) throws MailboxException {
         mapperFactory.getAttachmentMapper(session)
-            .storeAttachments(
+            .storeAttachmentsForMessage(
                 messageAttachments.stream()
                     .map(MessageAttachment::getAttachment)
-                    .collect(Guavate.toImmutableList()));
+                    .collect(Guavate.toImmutableList()),
+                message.getMessageId());
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/1b4d9239/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
index 8388c20..37edb52 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
@@ -33,6 +33,7 @@ import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.util.FluentFutureStream;
 import org.jetbrains.annotations.Nullable;
@@ -49,12 +50,14 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
     private final CassandraAttachmentDAO attachmentDAO;
     private final CassandraAttachmentDAOV2 attachmentDAOV2;
     private final CassandraBlobsDAO blobsDAO;
+    private final CassandraAttachmentMessageIdDAO attachmentMessageIdDAO;
 
     @Inject
-    public CassandraAttachmentMapper(CassandraAttachmentDAO attachmentDAO, CassandraAttachmentDAOV2 attachmentDAOV2, CassandraBlobsDAO blobsDAO) {
+    public CassandraAttachmentMapper(CassandraAttachmentDAO attachmentDAO, CassandraAttachmentDAOV2 attachmentDAOV2, CassandraBlobsDAO blobsDAO, CassandraAttachmentMessageIdDAO attachmentMessageIdDAO) {
         this.attachmentDAO = attachmentDAO;
         this.attachmentDAOV2 = attachmentDAOV2;
         this.blobsDAO = blobsDAO;
+        this.attachmentMessageIdDAO = attachmentMessageIdDAO;
     }
 
     @Override
@@ -118,21 +121,35 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
 
     @Override
     public void storeAttachment(Attachment attachment) throws MailboxException {
-        storeAttachmentAsync(attachment).join();
+        blobsDAO.save(attachment.getBytes())
+            .thenApply(blobId -> CassandraAttachmentDAOV2.from(attachment, blobId))
+            .thenCompose(attachmentDAOV2::storeAttachment)
+            .join();
     }
 
     @Override
-    public void storeAttachments(Collection<Attachment> attachments) throws MailboxException {
+    public void storeAttachmentsForMessage(Collection<Attachment> attachments, MessageId ownerMessageId) throws MailboxException {
         FluentFutureStream.of(
             attachments.stream()
-                .map(this::storeAttachmentAsync))
+                .map(attachment -> storeAttachmentAsync(attachment, ownerMessageId)))
+            .join();
+    }
+
+    @Override
+    public Collection<MessageId> getOwnerMessageIds(AttachmentId attachmentId) throws MailboxException {
+        return attachmentMessageIdDAO.getOwnerMessageIds(attachmentId)
             .join();
     }
 
-    public CompletableFuture<Void> storeAttachmentAsync(Attachment attachment) {
+    public CompletableFuture<Void> storeAttachmentAsync(Attachment attachment, MessageId ownerMessageId) {
         return blobsDAO.save(attachment.getBytes())
             .thenApply(blobId -> CassandraAttachmentDAOV2.from(attachment, blobId))
-            .thenCompose(attachmentDAOV2::storeAttachment);
+            .thenCompose(daoAttachment -> storeAttachmentWithIndex(daoAttachment, ownerMessageId));
+    }
+
+    private CompletableFuture<Void> storeAttachmentWithIndex(DAOAttachment daoAttachment, MessageId ownerMessageId) {
+        return attachmentDAOV2.storeAttachment(daoAttachment)
+                .thenCompose(any -> attachmentMessageIdDAO.storeAttachmentForMessageId(daoAttachment.getAttachmentId(), ownerMessageId));
     }
 
     private Optional<Attachment> logNotFound(AttachmentId attachmentId, Optional<Attachment> optionalAttachment) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/1b4d9239/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMessageIdDAO.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMessageIdDAO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMessageIdDAO.java
new file mode 100644
index 0000000..88b3d4d
--- /dev/null
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMessageIdDAO.java
@@ -0,0 +1,101 @@
+/****************************************************************
+ * 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.mailbox.cassandra.mail;
+
+import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+import static org.apache.james.mailbox.cassandra.table.CassandraAttachmentMessageIdTable.ATTACHMENT_ID;
+import static org.apache.james.mailbox.cassandra.table.CassandraAttachmentMessageIdTable.ATTACHMENT_ID_AS_UUID;
+import static org.apache.james.mailbox.cassandra.table.CassandraAttachmentMessageIdTable.FIELDS;
+import static org.apache.james.mailbox.cassandra.table.CassandraAttachmentMessageIdTable.MESSAGE_ID;
+import static org.apache.james.mailbox.cassandra.table.CassandraAttachmentMessageIdTable.TABLE_NAME;
+
+import java.util.Collection;
+import java.util.concurrent.CompletableFuture;
+
+import javax.inject.Inject;
+
+import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.MessageId;
+
+import com.datastax.driver.core.PreparedStatement;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.github.steveash.guavate.Guavate;
+import com.google.common.base.Preconditions;
+
+public class CassandraAttachmentMessageIdDAO {
+
+    private final CassandraAsyncExecutor cassandraAsyncExecutor;
+    private final PreparedStatement insertStatement;
+    private final PreparedStatement selectStatement;
+    private final MessageId.Factory messageIdFactory;
+    private final CassandraUtils cassandraUtils;
+
+    @Inject
+    public CassandraAttachmentMessageIdDAO(Session session, MessageId.Factory messageIdFactory, CassandraUtils cassandraUtils) {
+        this.messageIdFactory = messageIdFactory;
+        this.cassandraUtils = cassandraUtils;
+        this.cassandraAsyncExecutor = new CassandraAsyncExecutor(session);
+
+        this.selectStatement = prepareSelect(session);
+        this.insertStatement = prepareInsert(session);
+    }
+
+    private PreparedStatement prepareInsert(Session session) {
+        return session.prepare(
+            insertInto(TABLE_NAME)
+                .value(ATTACHMENT_ID_AS_UUID, bindMarker(ATTACHMENT_ID_AS_UUID))
+                .value(ATTACHMENT_ID, bindMarker(ATTACHMENT_ID))
+                .value(MESSAGE_ID, bindMarker(MESSAGE_ID)));
+    }
+
+    private PreparedStatement prepareSelect(Session session) {
+        return session.prepare(select(FIELDS)
+            .from(TABLE_NAME)
+            .where(eq(ATTACHMENT_ID_AS_UUID, bindMarker(ATTACHMENT_ID_AS_UUID))));
+    }
+
+    public CompletableFuture<Collection<MessageId>> getOwnerMessageIds(AttachmentId attachmentId) {
+        Preconditions.checkArgument(attachmentId != null);
+        return cassandraAsyncExecutor.execute(
+            selectStatement.bind()
+                .setUUID(ATTACHMENT_ID_AS_UUID, attachmentId.asUUID()))
+            .thenApply(resultSet -> cassandraUtils.convertToStream(resultSet)
+                .map(this::rowToMessageId)
+                .collect(Guavate.toImmutableSet()));
+    }
+
+    private MessageId rowToMessageId(Row row) {
+        return messageIdFactory.fromString(row.getString(MESSAGE_ID));
+    }
+
+    public CompletableFuture<Void> storeAttachmentForMessageId(AttachmentId attachmentId, MessageId ownerMessageId) {
+        return cassandraAsyncExecutor.executeVoid(
+            insertStatement.bind()
+                .setUUID(ATTACHMENT_ID_AS_UUID, attachmentId.asUUID())
+                .setString(ATTACHMENT_ID, attachmentId.getId())
+                .setString(MESSAGE_ID, ownerMessageId.serialize()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/1b4d9239/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraAttachmentModule.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraAttachmentModule.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraAttachmentModule.java
index 50bee8b..dd2bc46 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraAttachmentModule.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraAttachmentModule.java
@@ -30,6 +30,7 @@ import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.backends.cassandra.components.CassandraTable;
 import org.apache.james.backends.cassandra.components.CassandraType;
 import org.apache.james.backends.cassandra.utils.CassandraConstants;
+import org.apache.james.mailbox.cassandra.table.CassandraAttachmentMessageIdTable;
 import org.apache.james.mailbox.cassandra.table.CassandraAttachmentTable;
 import org.apache.james.mailbox.cassandra.table.CassandraAttachmentV2Table;
 
@@ -65,7 +66,18 @@ public class CassandraAttachmentModule implements CassandraModule {
                     .caching(SchemaBuilder.KeyCaching.ALL,
                         SchemaBuilder.rows(CassandraConstants.DEFAULT_CACHED_ROW_PER_PARTITION))
                     .comment("Holds attachment for fast attachment retrieval. Content of messages is stored" +
-                        "in `blobs` and `blobparts` tables.")));
+                        "in `blobs` and `blobparts` tables.")),
+            new CassandraTable(CassandraAttachmentMessageIdTable.TABLE_NAME,
+                SchemaBuilder.createTable(CassandraAttachmentMessageIdTable.TABLE_NAME)
+                    .ifNotExists()
+                    .addPartitionKey(CassandraAttachmentMessageIdTable.ATTACHMENT_ID_AS_UUID, uuid())
+                    .addColumn(CassandraAttachmentMessageIdTable.ATTACHMENT_ID, text())
+                    .addClusteringColumn(CassandraAttachmentMessageIdTable.MESSAGE_ID, text())
+                    .withOptions()
+                    .compactionOptions(SchemaBuilder.leveledStrategy())
+                    .caching(SchemaBuilder.KeyCaching.ALL,
+                        SchemaBuilder.rows(CassandraConstants.DEFAULT_CACHED_ROW_PER_PARTITION))
+                    .comment("Holds ids of messages owning the attachment")));
         types = ImmutableList.of();
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/1b4d9239/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraAttachmentMessageIdTable.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraAttachmentMessageIdTable.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraAttachmentMessageIdTable.java
new file mode 100644
index 0000000..42655fb
--- /dev/null
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraAttachmentMessageIdTable.java
@@ -0,0 +1,30 @@
+/****************************************************************
+ * 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.mailbox.cassandra.table;
+
+public interface CassandraAttachmentMessageIdTable {
+
+    String TABLE_NAME = "attachmentMessageId";
+    String ATTACHMENT_ID_AS_UUID = "attachmentIdAsUUID";
+    String ATTACHMENT_ID = "attachmentId";
+    String MESSAGE_ID = "messageId";
+    String[] FIELDS = { ATTACHMENT_ID_AS_UUID, ATTACHMENT_ID, MESSAGE_ID };
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/1b4d9239/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManagerTest.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManagerTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManagerTest.java
index 7e94b3c..53345db 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManagerTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManagerTest.java
@@ -29,6 +29,7 @@ import org.apache.james.mailbox.SubscriptionManager;
 import org.apache.james.mailbox.cassandra.mail.CassandraApplicableFlagDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAOV2;
+import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentMessageIdDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraBlobsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraDeletedMessageDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraFirstUnseenDAO;
@@ -91,6 +92,7 @@ public class CassandraSubscriptionManagerTest extends AbstractSubscriptionManage
         CassandraDeletedMessageDAO deletedMessageDAO = null;
         CassandraAttachmentDAOV2 attachmentDAOV2 = null;
         CassandraBlobsDAO cassandraBlobsDAO = null;
+        CassandraAttachmentMessageIdDAO attachmentMessageIdDAO = null;
         return new CassandraSubscriptionManager(
             new CassandraMailboxSessionMapperFactory(
                 new CassandraUidProvider(cassandra.getConf()),
@@ -109,6 +111,7 @@ public class CassandraSubscriptionManagerTest extends AbstractSubscriptionManage
                 attachmentDAOV2,
                 deletedMessageDAO,
                 cassandraBlobsDAO,
+                attachmentMessageIdDAO,
                 CassandraUtils.WITH_DEFAULT_CONFIGURATION,
                 CassandraConfiguration.DEFAULT_CONFIGURATION));
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/1b4d9239/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
index 312accd..fcd3467 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
@@ -26,6 +26,7 @@ import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.cassandra.mail.CassandraApplicableFlagDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAOV2;
+import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentMessageIdDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraBlobsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraDeletedMessageDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraFirstUnseenDAO;
@@ -61,7 +62,9 @@ public class TestCassandraMailboxSessionMapperFactory {
             new CassandraAttachmentDAO(session, CassandraUtils.WITH_DEFAULT_CONFIGURATION, CassandraConfiguration.DEFAULT_CONFIGURATION),
             new CassandraAttachmentDAOV2(session),
             new CassandraDeletedMessageDAO(session),
-            cassandraBlobsDAO, CassandraUtils.WITH_DEFAULT_CONFIGURATION,
+            cassandraBlobsDAO,
+            new CassandraAttachmentMessageIdDAO(session, factory, CassandraUtils.WITH_DEFAULT_CONFIGURATION),
+            CassandraUtils.WITH_DEFAULT_CONFIGURATION,
             CassandraConfiguration.DEFAULT_CONFIGURATION);
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/1b4d9239/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java
index 7408840..d9ac703 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java
@@ -30,6 +30,7 @@ import org.apache.james.backends.cassandra.init.CassandraConfiguration;
 import org.apache.james.backends.cassandra.init.CassandraModuleComposite;
 import org.apache.james.backends.cassandra.utils.CassandraUtils;
 import org.apache.james.mailbox.cassandra.ids.BlobId;
+import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraBlobModule;
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
@@ -54,6 +55,7 @@ public class CassandraAttachmentFallbackTest {
     private CassandraAttachmentDAO attachmentDAO;
     private CassandraAttachmentMapper attachmentMapper;
     private CassandraBlobsDAO blobsDAO;
+    private CassandraAttachmentMessageIdDAO attachmentMessageIdDAO;
 
     @Before
     public void setUp() throws Exception {
@@ -71,7 +73,8 @@ public class CassandraAttachmentFallbackTest {
             CassandraUtils.WITH_DEFAULT_CONFIGURATION,
             CassandraConfiguration.DEFAULT_CONFIGURATION);
         blobsDAO = new CassandraBlobsDAO(cassandra.getConf());
-        attachmentMapper = new CassandraAttachmentMapper(attachmentDAO, attachmentDAOV2, blobsDAO);
+        attachmentMessageIdDAO = new CassandraAttachmentMessageIdDAO(cassandra.getConf(), new CassandraMessageId.Factory(), CassandraUtils.WITH_DEFAULT_CONFIGURATION);
+        attachmentMapper = new CassandraAttachmentMapper(attachmentDAO, attachmentDAOV2, blobsDAO, attachmentMessageIdDAO);
     }
 
     @After

http://git-wip-us.apache.org/repos/asf/james-project/blob/1b4d9239/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapperTest.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapperTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapperTest.java
index ed3948d..85acca5 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapperTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapperTest.java
@@ -22,6 +22,7 @@ package org.apache.james.mailbox.cassandra.mail;
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.DockerCassandraRule;
 import org.apache.james.backends.cassandra.init.CassandraModuleComposite;
+import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraAnnotationModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraApplicableFlagsModule;
@@ -36,6 +37,7 @@ import org.apache.james.mailbox.cassandra.modules.CassandraMessageModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraModSeqModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraUidModule;
 import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.mail.model.AttachmentMapperTest;
 import org.apache.james.mailbox.store.mail.model.MapperProvider;
 import org.junit.After;
@@ -77,4 +79,9 @@ public class CassandraAttachmentMapperTest extends AttachmentMapperTest {
     protected MapperProvider createMapperProvider() {
         return new CassandraMapperProvider(cassandra);
     }
+
+    @Override
+    protected MessageId generateMessageId() {
+        return new CassandraMessageId.Factory().generate();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/1b4d9239/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
----------------------------------------------------------------------
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
index 7620ddc..6732816 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
@@ -46,9 +46,10 @@ public class InMemoryMessageManager extends StoreMessageManager {
     @Override
     protected void storeAttachment(final MailboxMessage message, final List<MessageAttachment> messageAttachments, final MailboxSession session) throws MailboxException {
         mapperFactory.getAttachmentMapper(session)
-            .storeAttachments(
+            .storeAttachmentsForMessage(
                 messageAttachments.stream()
                     .map(MessageAttachment::getAttachment)
-                    .collect(Guavate.toImmutableList()));
+                    .collect(Guavate.toImmutableList()),
+                message.getMessageId());
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/1b4d9239/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
----------------------------------------------------------------------
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
index 3b4f92d..314226b 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
@@ -27,19 +27,25 @@ import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
 
 import com.google.common.base.Preconditions;
+import com.google.common.collect.HashMultimap;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableList.Builder;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
 
 public class InMemoryAttachmentMapper implements AttachmentMapper {
     
     private static final int INITIAL_SIZE = 128;
     private final Map<AttachmentId, Attachment> attachmentsById;
+    private final Multimap<AttachmentId, MessageId> messageIdsByAttachmentId;
 
     public InMemoryAttachmentMapper() {
         attachmentsById = new ConcurrentHashMap<>(INITIAL_SIZE);
+        messageIdsByAttachmentId = Multimaps.synchronizedSetMultimap(HashMultimap.create());
     }
 
     @Override
@@ -79,9 +85,15 @@ public class InMemoryAttachmentMapper implements AttachmentMapper {
     }
 
     @Override
-    public void storeAttachments(Collection<Attachment> attachments) throws MailboxException {
+    public void storeAttachmentsForMessage(Collection<Attachment> attachments, MessageId ownerMessageId) throws MailboxException {
         for (Attachment attachment: attachments) {
             storeAttachment(attachment);
+            messageIdsByAttachmentId.put(attachment.getAttachmentId(), ownerMessageId);
         }
     }
+
+    @Override
+    public Collection<MessageId> getOwnerMessageIds(AttachmentId attachmentId) throws MailboxException {
+        return messageIdsByAttachmentId.get(attachmentId);
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/1b4d9239/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/MemoryAttachmentMapperTest.java
----------------------------------------------------------------------
diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/MemoryAttachmentMapperTest.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/MemoryAttachmentMapperTest.java
index 7b60d83..00e6ae1 100644
--- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/MemoryAttachmentMapperTest.java
+++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/MemoryAttachmentMapperTest.java
@@ -20,6 +20,8 @@
 package org.apache.james.mailbox.inmemory.mail;
 
 import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.inmemory.InMemoryMessageId;
+import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.mail.model.AttachmentMapperTest;
 import org.apache.james.mailbox.store.mail.model.MapperProvider;
 import org.junit.Before;
@@ -35,4 +37,9 @@ public class MemoryAttachmentMapperTest extends AttachmentMapperTest {
     protected MapperProvider createMapperProvider() {
         return new InMemoryMapperProvider();
     }
+
+    @Override
+    protected MessageId generateMessageId() {
+        return new InMemoryMessageId.Factory().generate();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/1b4d9239/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
index 88799d9..0d2b8a6 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
@@ -30,6 +30,7 @@ import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.mailbox.store.mail.AttachmentMapperFactory;
 
@@ -66,7 +67,12 @@ public class StoreAttachmentManager implements AttachmentManager {
     }
 
     @Override
-    public void storeAttachments(Collection<Attachment> attachments, MailboxSession mailboxSession) throws MailboxException {
-        getAttachmentMapper(mailboxSession).storeAttachments(attachments);
+    public void storeAttachmentsForMessage(Collection<Attachment> attachments, MessageId ownerMessageId, MailboxSession mailboxSession) throws MailboxException {
+        getAttachmentMapper(mailboxSession).storeAttachmentsForMessage(attachments, ownerMessageId);
+    }
+
+    @Override
+    public Collection<MessageId> getOwnerMessageIds(AttachmentId attachmentId, MailboxSession mailboxSession) throws MailboxException {
+        return getAttachmentMapper(mailboxSession).getOwnerMessageIds(attachmentId);
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/1b4d9239/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
index 06e84a7..c9c12bb 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
@@ -25,6 +25,7 @@ import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.transaction.Mapper;
 
 public interface AttachmentMapper extends Mapper {
@@ -35,5 +36,7 @@ public interface AttachmentMapper extends Mapper {
 
     void storeAttachment(Attachment attachment) throws MailboxException;
 
-    void storeAttachments(Collection<Attachment> attachments) throws MailboxException;
+    void storeAttachmentsForMessage(Collection<Attachment> attachments, MessageId ownerMessageId) throws MailboxException;
+
+    Collection<MessageId> getOwnerMessageIds(AttachmentId attachmentId) throws MailboxException;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/1b4d9239/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
index a915d36..e56ba13 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
@@ -21,12 +21,14 @@ package org.apache.james.mailbox.store.mail.model;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
+import java.util.Collection;
 import java.util.List;
 
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.junit.Assume;
 import org.junit.Rule;
@@ -37,6 +39,7 @@ import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableList;
 
 public abstract class AttachmentMapperTest {
+    private static final AttachmentId UNKNOWN_ATTACHMENT_ID = AttachmentId.forPayload("unknown".getBytes(Charsets.UTF_8));
 
     private AttachmentMapper attachmentMapper;
     private MapperProvider mapperProvider;
@@ -46,6 +49,8 @@ public abstract class AttachmentMapperTest {
 
     protected abstract MapperProvider createMapperProvider();
 
+    protected abstract MessageId generateMessageId();
+
     public void setUp() throws MailboxException {
         mapperProvider = createMapperProvider();
         Assume.assumeTrue(mapperProvider.getSupportedCapabilities().contains(MapperProvider.Capabilities.ATTACHMENT));
@@ -61,7 +66,7 @@ public abstract class AttachmentMapperTest {
     @Test
     public void getAttachmentShouldThrowWhenNonReferencedAttachmentId() throws Exception {
         expected.expect(AttachmentNotFoundException.class);
-        attachmentMapper.getAttachment(AttachmentId.forPayload("unknown".getBytes(Charsets.UTF_8)));
+        attachmentMapper.getAttachment(UNKNOWN_ATTACHMENT_ID);
     }
 
     @Test
@@ -93,7 +98,7 @@ public abstract class AttachmentMapperTest {
         AttachmentId attachmentId1 = expected1.getAttachmentId();
         AttachmentId attachmentId2 = expected2.getAttachmentId();
         //When
-        attachmentMapper.storeAttachments(ImmutableList.of(expected1, expected2));
+        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(expected1, expected2), generateMessageId());
         //Then
         Attachment attachment1 = attachmentMapper.getAttachment(attachmentId1);
         Attachment attachment2 = attachmentMapper.getAttachment(attachmentId2);
@@ -109,7 +114,7 @@ public abstract class AttachmentMapperTest {
 
     @Test
     public void getAttachmentsShouldReturnEmptyListWhenNonReferencedAttachmentId() throws Exception {
-        List<Attachment> attachments = attachmentMapper.getAttachments(ImmutableList.of(AttachmentId.forPayload("unknown".getBytes(Charsets.UTF_8))));
+        List<Attachment> attachments = attachmentMapper.getAttachments(ImmutableList.of(UNKNOWN_ATTACHMENT_ID));
 
         assertThat(attachments).isEmpty();
     }
@@ -136,4 +141,127 @@ public abstract class AttachmentMapperTest {
         //Then
         assertThat(attachments).contains(expected, expected2);
     }
+
+    @Test
+    public void getOwnerMessageIdsShouldReturnEmptyWhenNone() throws Exception {
+        Collection<MessageId> messageIds = attachmentMapper.getOwnerMessageIds(UNKNOWN_ATTACHMENT_ID);
+
+        assertThat(messageIds).isEmpty();
+    }
+
+    @Test
+    public void getOwnerMessageIdsShouldReturnEmptyWhenStoredWithoutMessageId() throws Exception {
+        //Given
+        Attachment attachment = Attachment.builder()
+                .bytes("payload".getBytes(Charsets.UTF_8))
+                .type("content")
+                .build();
+        AttachmentId attachmentId = attachment.getAttachmentId();
+        attachmentMapper.storeAttachment(attachment);
+        
+        //When
+        Collection<MessageId> messageIds = attachmentMapper.getOwnerMessageIds(attachmentId);
+        //Then
+        assertThat(messageIds).isEmpty();
+    }
+
+    @Test
+    public void getOwnerMessageIdsShouldReturnMessageIdWhenStoredWithMessageId() throws Exception {
+        //Given
+        Attachment attachment = Attachment.builder()
+                .bytes("payload".getBytes(Charsets.UTF_8))
+                .type("content")
+                .build();
+        AttachmentId attachmentId = attachment.getAttachmentId();
+        MessageId messageId = generateMessageId();
+        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment), messageId);
+        
+        //When
+        Collection<MessageId> messageIds = attachmentMapper.getOwnerMessageIds(attachmentId);
+        //Then
+        assertThat(messageIds).containsOnly(messageId);
+    }
+
+    @Test
+    public void getOwnerMessageIdsShouldReturnTwoMessageIdsWhenStoredTwice() throws Exception {
+        //Given
+        Attachment attachment = Attachment.builder()
+                .bytes("payload".getBytes(Charsets.UTF_8))
+                .type("content")
+                .build();
+        AttachmentId attachmentId = attachment.getAttachmentId();
+        MessageId messageId1 = generateMessageId();
+        MessageId messageId2 = generateMessageId();
+        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment), messageId1);
+        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment), messageId2);
+        
+        //When
+        Collection<MessageId> messageIds = attachmentMapper.getOwnerMessageIds(attachmentId);
+        //Then
+        assertThat(messageIds).containsOnly(messageId1, messageId2);
+    }
+
+    @Test
+    public void getOwnerMessageIdsShouldReturnOnlyMatchingMessageId() throws Exception {
+        //Given
+        Attachment attachment = Attachment.builder()
+                .bytes("payload".getBytes(Charsets.UTF_8))
+                .type("content")
+                .build();
+        Attachment otherAttachment = Attachment.builder()
+                .bytes("something different".getBytes(Charsets.UTF_8))
+                .type("content")
+                .build();
+        AttachmentId attachmentId = attachment.getAttachmentId();
+        MessageId messageId1 = generateMessageId();
+        MessageId messageId2 = generateMessageId();
+        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment), messageId1);
+        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(otherAttachment), messageId2);
+        
+        //When
+        Collection<MessageId> messageIds = attachmentMapper.getOwnerMessageIds(attachmentId);
+        //Then
+        assertThat(messageIds).containsOnly(messageId1);
+    }
+
+    @Test
+    public void getOwnerMessageIdsShouldReturnOnlyOneMessageIdWhenStoredTwice() throws Exception {
+        //Given
+        Attachment attachment = Attachment.builder()
+                .bytes("payload".getBytes(Charsets.UTF_8))
+                .type("content")
+                .build();
+        AttachmentId attachmentId = attachment.getAttachmentId();
+        MessageId messageId = generateMessageId();
+        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment), messageId);
+        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment), messageId);
+        
+        //When
+        Collection<MessageId> messageIds = attachmentMapper.getOwnerMessageIds(attachmentId);
+        //Then
+        assertThat(messageIds).containsOnly(messageId);
+    }
+
+    @Test
+    public void getOwnerMessageIdsShouldReturnMessageIdForTwoAttachmentsWhenBothStoredAtTheSameTime() throws Exception {
+        //Given
+        Attachment attachment = Attachment.builder()
+                .bytes("payload".getBytes(Charsets.UTF_8))
+                .type("content")
+                .build();
+        Attachment attachment2 = Attachment.builder()
+                .bytes("other payload".getBytes(Charsets.UTF_8))
+                .type("content")
+                .build();
+        AttachmentId attachmentId = attachment.getAttachmentId();
+        AttachmentId attachmentId2 = attachment2.getAttachmentId();
+        MessageId messageId = generateMessageId();
+        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment, attachment2), messageId);
+        
+        //When
+        Collection<MessageId> messageIds = attachmentMapper.getOwnerMessageIds(attachmentId);
+        Collection<MessageId> messageIds2 = attachmentMapper.getOwnerMessageIds(attachmentId2);
+        //Then
+        assertThat(messageIds).isEqualTo(messageIds2);
+    }
 }


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


[07/24] james-project git commit: JAMES-2143 Introduce Blob API

Posted by ad...@apache.org.
JAMES-2143 Introduce Blob API


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

Branch: refs/heads/master
Commit: 6487016d05923440b9309945d0e32594c7fe9e03
Parents: b3c308e
Author: benwa <bt...@linagora.com>
Authored: Mon Sep 11 15:38:16 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:19:53 2017 +0200

----------------------------------------------------------------------
 .../org/apache/james/mailbox/BlobManager.java   |  29 +++++
 .../exception/BlobNotFoundException.java        |  36 ++++++
 .../apache/james/mailbox/model/Attachment.java  |   8 ++
 .../org/apache/james/mailbox/model/Blob.java    | 112 +++++++++++++++++++
 .../org/apache/james/mailbox/model/BlobId.java  |  66 +++++++++++
 .../james/mailbox/model/AttachmentTest.java     |  22 +++-
 .../apache/james/mailbox/model/BlobIdTest.java  |  55 +++++++++
 .../apache/james/mailbox/model/BlobTest.java    |  84 ++++++++++++++
 8 files changed, 409 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/6487016d/mailbox/api/src/main/java/org/apache/james/mailbox/BlobManager.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/BlobManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/BlobManager.java
new file mode 100644
index 0000000..ad453b7
--- /dev/null
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/BlobManager.java
@@ -0,0 +1,29 @@
+/****************************************************************
+ * 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.mailbox;
+
+import org.apache.james.mailbox.exception.BlobNotFoundException;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.Blob;
+import org.apache.james.mailbox.model.BlobId;
+
+public interface BlobManager {
+    Blob retrieve(BlobId blobId, MailboxSession mailboxSession) throws MailboxException, BlobNotFoundException;
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6487016d/mailbox/api/src/main/java/org/apache/james/mailbox/exception/BlobNotFoundException.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/exception/BlobNotFoundException.java b/mailbox/api/src/main/java/org/apache/james/mailbox/exception/BlobNotFoundException.java
new file mode 100644
index 0000000..f46a4d6
--- /dev/null
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/exception/BlobNotFoundException.java
@@ -0,0 +1,36 @@
+/****************************************************************
+ * 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.mailbox.exception;
+
+import org.apache.james.mailbox.model.BlobId;
+
+public class BlobNotFoundException extends RuntimeException {
+
+    private final BlobId blobId;
+
+    public BlobNotFoundException(BlobId blobId) {
+        super("Could not retrieve " + blobId.asString());
+        this.blobId = blobId;
+    }
+
+    public BlobId getBlobId() {
+        return blobId;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6487016d/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
index e0f6ac2..a1321d9 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
@@ -116,6 +116,14 @@ public class Attachment {
         return bytes;
     }
 
+    public Blob toBlob() {
+        return Blob.builder()
+            .id(BlobId.fromString(attachmentId.getId()))
+            .payload(bytes)
+            .contentType(type)
+            .build();
+    }
+
     @Override
     public boolean equals(Object obj) {
         if (obj instanceof Attachment) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/6487016d/mailbox/api/src/main/java/org/apache/james/mailbox/model/Blob.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Blob.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Blob.java
new file mode 100644
index 0000000..16a372e
--- /dev/null
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Blob.java
@@ -0,0 +1,112 @@
+/****************************************************************
+ * 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.mailbox.model;
+
+import java.util.Objects;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+
+public class Blob {
+
+    public static class Builder {
+        private BlobId blobId;
+        private byte[] payload;
+        private String contentType;
+
+        private Builder() {
+        }
+
+        public Builder id(BlobId id) {
+            this.blobId = id;
+            return this;
+        }
+
+        public Builder payload(byte[] payload) {
+            this.payload = payload;
+            return this;
+        }
+
+        public Builder contentType(String contentType) {
+            this.contentType = contentType;
+            return this;
+        }
+
+        public Blob build() {
+            Preconditions.checkState(blobId != null, "id can not be empty");
+            Preconditions.checkState(payload != null, "payload can not be empty");
+            Preconditions.checkState(contentType != null, "contentType can not be empty");
+
+            return new Blob(blobId, payload, contentType);
+        }
+    }
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    private final BlobId blobId;
+    private final byte[] payload;
+    private final String contentType;
+
+    @VisibleForTesting
+    Blob(BlobId blobId, byte[] payload, String contentType) {
+        this.blobId = blobId;
+        this.payload = payload;
+        this.contentType = contentType;
+    }
+
+    public BlobId getBlobId() {
+        return blobId;
+    }
+
+    public byte[] getPayload() {
+        return payload;
+    }
+
+    public String getContentType() {
+        return contentType;
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof Blob) {
+            Blob blob = (Blob) o;
+
+            return Objects.equals(this.blobId, blob.blobId)
+                && Objects.equals(this.contentType, blob.contentType);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(blobId, contentType);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+            .add("blobId", blobId)
+            .add("contentType", contentType)
+            .toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6487016d/mailbox/api/src/main/java/org/apache/james/mailbox/model/BlobId.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/BlobId.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/BlobId.java
new file mode 100644
index 0000000..476eca2
--- /dev/null
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/BlobId.java
@@ -0,0 +1,66 @@
+/****************************************************************
+ * 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.mailbox.model;
+
+import java.util.Objects;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+
+public class BlobId {
+    public static BlobId fromString(String raw) {
+        Preconditions.checkArgument(!Strings.isNullOrEmpty(raw));
+        return new BlobId(raw);
+    }
+
+    private final String id;
+
+    private BlobId(String id) {
+        this.id = id;
+    }
+
+    public String asString() {
+        return id;
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof BlobId) {
+            BlobId blobId = (BlobId) o;
+
+            return Objects.equals(this.id, blobId.id);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(id);
+    }
+
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+            .add("id", id)
+            .toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6487016d/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java
index 8edbdae..3235a7c 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java
@@ -25,12 +25,11 @@ import static org.assertj.core.api.Assertions.assertThat;
 import java.io.InputStream;
 import java.nio.charset.Charset;
 
-import com.google.common.base.Charsets;
 import org.apache.commons.io.IOUtils;
-import org.apache.james.mailbox.model.Attachment;
-
 import org.junit.Test;
 
+import com.google.common.base.Charsets;
+
 public class AttachmentTest {
 
     private static Charset CHARSET = Charsets.UTF_8;
@@ -140,4 +139,21 @@ public class AttachmentTest {
 
         assertThat(attachment.getSize()).isEqualTo(input.getBytes(CHARSET).length);
     }
+
+    @Test
+    public void toBlobShouldGenerateTheAttachmentBlob() throws Exception {
+        byte[] bytes = "mystream".getBytes(CHARSET);
+        String content = "content";
+        Attachment attachment = Attachment.builder()
+            .bytes(bytes)
+            .type(content)
+            .build();
+        Blob expected = Blob.builder()
+            .id(BlobId.fromString(attachment.getAttachmentId().getId()))
+            .contentType(content)
+            .payload(bytes)
+            .build();
+
+        assertThat(attachment.toBlob()).isEqualTo(expected);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/6487016d/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobIdTest.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobIdTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobIdTest.java
new file mode 100644
index 0000000..fefeed0
--- /dev/null
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobIdTest.java
@@ -0,0 +1,55 @@
+/****************************************************************
+ * 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.mailbox.model;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import org.junit.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class BlobIdTest {
+
+    @Test
+    public void shouldMatchBeanContact() {
+        EqualsVerifier.forClass(BlobId.class)
+            .allFieldsShouldBeUsed()
+            .verify();
+    }
+
+    @Test
+    public void fromStringShouldThrowOnNull() {
+        assertThatThrownBy(() -> BlobId.fromString(null))
+            .isInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    public void fromStringShouldThrowOnEmpty() {
+        assertThatThrownBy(() -> BlobId.fromString(""))
+            .isInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    public void asStringShouldReturnUnderlyingId() {
+        assertThat(BlobId.fromString("abc").asString())
+            .isEqualTo("abc");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6487016d/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobTest.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobTest.java
new file mode 100644
index 0000000..ed35795
--- /dev/null
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobTest.java
@@ -0,0 +1,84 @@
+/****************************************************************
+ * 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.mailbox.model;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.nio.charset.StandardCharsets;
+
+import org.junit.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class BlobTest {
+
+    public static final BlobId ID = BlobId.fromString("123");
+    public static final String CONTENT_TYPE = "text/plain";
+    public static final byte[] PAYLOAD = "abc".getBytes(StandardCharsets.UTF_8);
+
+    @Test
+    public void shouldMatchBeanContract() {
+        EqualsVerifier.forClass(Blob.class)
+            .verify();
+    }
+
+    @Test
+    public void buildShouldConstructValidBlob() {
+        assertThat(
+            Blob.builder()
+                .id(ID)
+                .contentType(CONTENT_TYPE)
+                .payload(PAYLOAD)
+                .build())
+            .isEqualTo(
+                new Blob(ID, PAYLOAD, CONTENT_TYPE));
+    }
+
+    @Test
+    public void buildShouldThrowOnMissingBlobId() {
+        assertThatThrownBy(() ->
+            Blob.builder()
+                .contentType(CONTENT_TYPE)
+                .payload(PAYLOAD)
+                .build())
+            .isInstanceOf(IllegalStateException.class);
+    }
+
+    @Test
+    public void buildShouldThrowOnMissingContentType() {
+        assertThatThrownBy(() ->
+            Blob.builder()
+                .id(ID)
+                .payload(PAYLOAD)
+                .build())
+            .isInstanceOf(IllegalStateException.class);
+    }
+
+    @Test
+    public void buildShouldThrowOnMissingPayload() {
+        assertThatThrownBy(() ->
+            Blob.builder()
+                .id(ID)
+                .contentType(CONTENT_TYPE)
+                .build())
+            .isInstanceOf(IllegalStateException.class);
+    }
+}


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


[21/24] james-project git commit: JAMES-2139 IT test from mailet

Posted by ad...@apache.org.
JAMES-2139 IT test from mailet


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

Branch: refs/heads/master
Commit: 895a00425f3dc2da42d4ca3def1caa7db8782384
Parents: bdedd0b
Author: quynhn <qn...@linagora.com>
Authored: Wed Sep 6 18:00:36 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:23:33 2017 +0200

----------------------------------------------------------------------
 server/mailet/integration-testing/pom.xml       |  10 +
 .../james/mailets/TemporaryJamesServer.java     |  11 +-
 .../configuration/ProcessorConfiguration.java   |   4 +
 .../transport/mailets/GroupMappingTest.java     | 377 +++++++++++++++++++
 .../apache/james/utils/IMAPMessageReader.java   |  11 +
 .../apache/james/utils/SMTPMessageSender.java   |  10 +-
 6 files changed, 416 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/895a0042/server/mailet/integration-testing/pom.xml
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/pom.xml b/server/mailet/integration-testing/pom.xml
index 82b5000..a148d31 100644
--- a/server/mailet/integration-testing/pom.xml
+++ b/server/mailet/integration-testing/pom.xml
@@ -89,6 +89,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-webadmin-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
             <scope>test</scope>
@@ -103,6 +108,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>com.jayway.restassured</groupId>
+            <artifactId>rest-assured</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>com.rabbitmq</groupId>
             <artifactId>amqp-client</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/895a0042/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/TemporaryJamesServer.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/TemporaryJamesServer.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/TemporaryJamesServer.java
index 387e419..55f3f05 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/TemporaryJamesServer.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/TemporaryJamesServer.java
@@ -36,9 +36,11 @@ import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.mailets.configuration.MailetContainer;
 import org.apache.james.modules.TestJMAPServerModule;
 import org.apache.james.utils.GuiceProbe;
+import org.apache.james.webadmin.WebAdminConfiguration;
 import org.junit.rules.TemporaryFolder;
 
 import com.google.common.collect.ImmutableList;
+import com.google.inject.AbstractModule;
 import com.google.inject.Module;
 
 public class TemporaryJamesServer {
@@ -56,11 +58,10 @@ public class TemporaryJamesServer {
         jamesServer = new GuiceJamesServer()
             .combineWith(MemoryJamesServerMain.inMemoryServerModule)
             .overrideWith((binder) -> binder.bind(PersistenceAdapter.class).to(MemoryPersistenceAdapter.class))
-            .overrideWith(ImmutableList.<Module>builder().addAll(Arrays.asList(additionalModules))
-                .add(new TestJMAPServerModule(LIMIT_TO_3_MESSAGES))
-                .add(new TemporaryFilesystemModule(temporaryFolder))
-                .build()
-                .toArray(new Module[additionalModules.length + 2]));
+            .overrideWith(additionalModules)
+            .overrideWith(new TestJMAPServerModule(LIMIT_TO_3_MESSAGES))
+            .overrideWith(new TemporaryFilesystemModule(temporaryFolder))
+            .overrideWith((binder) -> binder.bind(WebAdminConfiguration.class).toProvider(WebAdminConfiguration::testingConfiguration));
 
         jamesServer.start();
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/895a0042/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/ProcessorConfiguration.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/ProcessorConfiguration.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/ProcessorConfiguration.java
index 00128f1..cf95d69 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/ProcessorConfiguration.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/ProcessorConfiguration.java
@@ -30,6 +30,10 @@ public class ProcessorConfiguration implements SerializableAsXml {
         return new Builder();
     }
 
+    public static Builder transport() {
+        return builder().state("transport");
+    }
+
     public static class Builder {
 
         private String state;

http://git-wip-us.apache.org/repos/asf/james-project/blob/895a0042/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
new file mode 100644
index 0000000..37b16bd
--- /dev/null
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
@@ -0,0 +1,377 @@
+/****************************************************************
+ * 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.transport.mailets;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import javax.mail.internet.MimeMessage;
+
+import org.apache.james.core.MailAddress;
+import org.apache.james.mailbox.model.MailboxConstants;
+import org.apache.james.mailets.TemporaryJamesServer;
+import org.apache.james.mailets.configuration.CommonProcessors;
+import org.apache.james.mailets.configuration.MailetConfiguration;
+import org.apache.james.mailets.configuration.MailetContainer;
+import org.apache.james.mailets.configuration.ProcessorConfiguration;
+import org.apache.james.modules.MailboxProbeImpl;
+import org.apache.james.probe.DataProbe;
+import org.apache.james.utils.DataProbeImpl;
+import org.apache.james.utils.IMAPMessageReader;
+import org.apache.james.utils.SMTPMessageSender;
+import org.apache.james.utils.WebAdminGuiceProbe;
+import org.apache.james.webadmin.routes.GroupsRoutes;
+import org.apache.mailet.Mail;
+import org.apache.mailet.base.test.FakeMail;
+import org.apache.mailet.base.test.MimeMessageBuilder;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import com.jayway.awaitility.Awaitility;
+import com.jayway.awaitility.Duration;
+import com.jayway.awaitility.core.ConditionFactory;
+import com.jayway.restassured.RestAssured;
+import com.jayway.restassured.specification.RequestSpecification;
+
+public class GroupMappingTest {
+    private static final String LOCALHOST_IP = "127.0.0.1";
+    private static final int IMAP_PORT = 1143;
+    private static final int SMTP_PORT = 1025;
+    private static final String PASSWORD = "secret";
+
+    private static final String DOMAIN1 = "domain1.com";
+    private static final String DOMAIN2 = "domain2.com";
+
+    private static final String SENDER = "fromUser@" + DOMAIN1;
+    private static final String GROUP_ON_DOMAIN1 = "group@" + DOMAIN1;
+    private static final String GROUP_ON_DOMAIN2 = "group@" + DOMAIN2;
+
+    private static final String USER_DOMAIN1 = "user@" + DOMAIN1;
+    private static final String USER_DOMAIN2 = "user@" + DOMAIN2;
+    private static final String MESSAGE_CONTENT = "any text";
+
+    private TemporaryJamesServer jamesServer;
+    private ConditionFactory calmlyAwait;
+    private MimeMessage message;
+    private DataProbe dataProbe;
+    private RequestSpecification restApiRequest;
+
+    @Rule
+    public TemporaryFolder temporaryFolder = new TemporaryFolder();
+    @Before
+    public void setup() throws Exception {
+        MailetContainer mailetContainer = MailetContainer.builder()
+            .postmaster("postmaster@" + DOMAIN1)
+            .threads(5)
+            .addProcessor(CommonProcessors.root())
+            .addProcessor(CommonProcessors.error())
+            .addProcessor(ProcessorConfiguration.transport()
+                .enableJmx(true)
+                .addMailet(MailetConfiguration.builder()
+                    .match("All")
+                    .clazz("RemoveMimeHeader")
+                    .addProperty("name", "bcc")
+                    .build())
+                .addMailet(MailetConfiguration.builder()
+                    .match("All")
+                    .clazz("RecipientRewriteTable")
+                    .build())
+                .addMailet(MailetConfiguration.builder()
+                    .match("RecipientIsLocal")
+                    .clazz("org.apache.james.jmap.mailet.VacationMailet")
+                    .build())
+                .addMailet(MailetConfiguration.builder()
+                    .match("RecipientIsLocal")
+                    .clazz("LocalDelivery")
+                    .build())
+                .build())
+            .build();
+
+        jamesServer = new TemporaryJamesServer(temporaryFolder, mailetContainer);
+        Duration slowPacedPollInterval = Duration.FIVE_HUNDRED_MILLISECONDS;
+        calmlyAwait = Awaitility.with().pollInterval(slowPacedPollInterval).and().with().pollDelay(slowPacedPollInterval).await();
+
+        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DOMAIN1);
+        dataProbe.addDomain(DOMAIN2);
+
+        dataProbe.addUser(SENDER, PASSWORD);
+
+        dataProbe.addUser(USER_DOMAIN1, PASSWORD);
+        dataProbe.addUser(USER_DOMAIN2, PASSWORD);
+
+        jamesServer.getProbe(MailboxProbeImpl.class).createMailbox(MailboxConstants.USER_NAMESPACE, USER_DOMAIN1, "INBOX");
+        jamesServer.getProbe(MailboxProbeImpl.class).createMailbox(MailboxConstants.USER_NAMESPACE, USER_DOMAIN2, "INBOX");
+
+        restApiRequest = RestAssured.given()
+            .port(jamesServer.getProbe(WebAdminGuiceProbe.class).getWebAdminPort());
+
+        message = MimeMessageBuilder.mimeMessageBuilder()
+            .setSubject("test")
+            .setText(MESSAGE_CONTENT)
+            .build();
+    }
+
+    @After
+    public void tearDown() {
+        jamesServer.shutdown();
+    }
+
+    @Test
+    public void messageShouldRedirectToUserWhenBelongingToGroup() throws Exception {
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN1);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userReceivedMessage(USER_DOMAIN1, PASSWORD));
+
+            String processedMessage = imapMessageReader.readFirstMessageInInbox(USER_DOMAIN1, PASSWORD);
+
+            assertThat(processedMessage).contains(MESSAGE_CONTENT);
+        }
+
+    }
+
+    @Test
+    public void messageShouldRedirectToUserDoesNotHaveSameDomainWhenBelongingToGroup() throws Exception {
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN2);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userReceivedMessage(USER_DOMAIN2, PASSWORD));
+
+            String processedMessage = imapMessageReader.readFirstMessageInInbox(USER_DOMAIN2, PASSWORD);
+
+            assertThat(processedMessage).contains(MESSAGE_CONTENT);
+        }
+    }
+
+    @Test
+    public void messageShouldRedirectToAllUsersBelongingToGroup() throws Exception {
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN1);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN2);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.countReceivedMessage(USER_DOMAIN1, PASSWORD, 1));
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.countReceivedMessage(USER_DOMAIN2, PASSWORD, 1));
+        }
+    }
+
+    @Test
+    public void messageShouldRedirectWhenGroupBelongingToAnotherGroup() throws Exception {
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN2 + "/" + USER_DOMAIN2);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + GROUP_ON_DOMAIN2);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userReceivedMessage(USER_DOMAIN2, PASSWORD));
+
+            String processedMessage = imapMessageReader.readFirstMessageInInbox(USER_DOMAIN2, PASSWORD);
+
+            assertThat(processedMessage).contains(MESSAGE_CONTENT);
+        }
+    }
+
+    @Test
+    public void messageShouldNotBeDuplicatedWhenUserBelongingToTwoGroups() throws Exception {
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN1);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN2 + "/" + USER_DOMAIN1);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + GROUP_ON_DOMAIN2);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.countReceivedMessage(USER_DOMAIN1, PASSWORD, 1));
+        }
+    }
+
+    @Test
+    public void messageShouldNotBeDuplicatedWhenRecipientIsAlsoPartOfGroup() throws Exception {
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN1);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipients(new MailAddress(GROUP_ON_DOMAIN1), new MailAddress(USER_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.countReceivedMessage(USER_DOMAIN1, PASSWORD, 1));
+        }
+    }
+
+    @Test
+    public void groupMappingShouldSupportTreeStructure() throws Exception {
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN1);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN2 + "/" + USER_DOMAIN2);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + GROUP_ON_DOMAIN2);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN2))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userReceivedMessage(USER_DOMAIN2, PASSWORD));
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userReceivedMessage(USER_DOMAIN1, PASSWORD));
+        }
+    }
+
+    @Test
+    public void messageShouldNotBeSentWhenGroupLoopMapping() throws Exception {
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN1);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN2 + "/" + USER_DOMAIN2);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + GROUP_ON_DOMAIN2);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN2 + "/" + GROUP_ON_DOMAIN1);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+            IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHaveNotBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userDoesNotReceiveMessage(USER_DOMAIN1, PASSWORD));
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userDoesNotReceiveMessage(USER_DOMAIN2, PASSWORD));
+        }
+    }
+
+    @Test
+    public void messageShouldRedirectToUserWhenDomainMapping() throws Exception {
+        dataProbe.addDomainAliasMapping(DOMAIN1, DOMAIN2);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN1);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userReceivedMessage(USER_DOMAIN2, PASSWORD));
+        }
+    }
+
+    @Test
+    public void messageShouldNotSendToUserBelongingToGroupWhenDomainMapping() throws Exception {
+        dataProbe.addDomainAliasMapping(DOMAIN1, DOMAIN2);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN1);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userDoesNotReceiveMessage(USER_DOMAIN1, PASSWORD));
+        }
+    }
+
+    @Test
+    public void messageShouldRedirectToGroupWhenDomainMapping() throws Exception {
+        dataProbe.addDomainAliasMapping(DOMAIN1, DOMAIN2);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN2 + "/" + USER_DOMAIN2);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userReceivedMessage(USER_DOMAIN2, PASSWORD));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/895a0042/server/testing/src/main/java/org/apache/james/utils/IMAPMessageReader.java
----------------------------------------------------------------------
diff --git a/server/testing/src/main/java/org/apache/james/utils/IMAPMessageReader.java b/server/testing/src/main/java/org/apache/james/utils/IMAPMessageReader.java
index fc05bde..8fb5d68 100644
--- a/server/testing/src/main/java/org/apache/james/utils/IMAPMessageReader.java
+++ b/server/testing/src/main/java/org/apache/james/utils/IMAPMessageReader.java
@@ -43,6 +43,17 @@ public class IMAPMessageReader implements Closeable {
         imapClient.select(mailbox);
     }
 
+    public boolean countReceivedMessage(String user, String password, int numberOfMessages) throws IOException {
+        return countReceivedMessageInMailbox(user, password, INBOX, numberOfMessages);
+    }
+
+    public boolean countReceivedMessageInMailbox(String user, String password, String mailbox, int numberOfMessages) throws IOException {
+        connectAndSelect(user, password, mailbox);
+
+        return imapClient.getReplyString()
+            .contains(numberOfMessages + " EXISTS");
+    }
+
     public boolean userReceivedMessage(String user, String password) throws IOException {
         return userReceivedMessageInMailbox(user, password, INBOX);
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/895a0042/server/testing/src/main/java/org/apache/james/utils/SMTPMessageSender.java
----------------------------------------------------------------------
diff --git a/server/testing/src/main/java/org/apache/james/utils/SMTPMessageSender.java b/server/testing/src/main/java/org/apache/james/utils/SMTPMessageSender.java
index 2a0e5fc..b08c5d2 100644
--- a/server/testing/src/main/java/org/apache/james/utils/SMTPMessageSender.java
+++ b/server/testing/src/main/java/org/apache/james/utils/SMTPMessageSender.java
@@ -31,10 +31,10 @@ import javax.mail.MessagingException;
 
 import org.apache.commons.net.smtp.AuthenticatingSMTPClient;
 import org.apache.commons.net.smtp.SMTPClient;
+import org.apache.james.core.MailAddress;
 import org.apache.mailet.Mail;
 
 import com.google.common.base.Charsets;
-import com.google.common.base.Joiner;
 import com.google.common.base.Throwables;
 
 public class SMTPMessageSender implements Closeable {
@@ -92,7 +92,9 @@ public class SMTPMessageSender implements Closeable {
             String from = mail.getSender().asString();
             smtpClient.helo(senderDomain);
             smtpClient.setSender(from);
-            smtpClient.rcpt("<" + Joiner.on(", ").join(mail.getRecipients()) + ">");
+            for (MailAddress mailAddress : mail.getRecipients()) {
+                smtpClient.addRecipient(mailAddress.asString());
+            }
             smtpClient.sendShortMessageData(asString(mail.getMessage()));
         } catch (IOException e) {
             throw Throwables.propagate(e);
@@ -110,6 +112,10 @@ public class SMTPMessageSender implements Closeable {
             .contains("250 2.6.0 Message received");
     }
 
+    public boolean messageHaveNotBeenSent() throws IOException {
+        return !messageHasBeenSent();
+    }
+
     @Override
     public void close() throws IOException {
         smtpClient.disconnect();


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


[06/24] james-project git commit: JAMES-2143 JMAP downloads should rely on BlobManager

Posted by ad...@apache.org.
JAMES-2143 JMAP downloads should rely on BlobManager


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

Branch: refs/heads/master
Commit: 4e0e860490daff7616fc49ed9040b57dd1b60a8a
Parents: 55dcb3d
Author: benwa <bt...@linagora.com>
Authored: Mon Sep 11 16:21:18 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:19:53 2017 +0200

----------------------------------------------------------------------
 .../org/apache/james/mailbox/model/Blob.java    | 13 ++++++++
 .../integration/cucumber/DownloadStepdefs.java  | 33 +++++++++++++++-----
 .../test/resources/cucumber/DownloadGet.feature | 16 +++++++---
 .../org/apache/james/jmap/DownloadServlet.java  | 26 +++++++--------
 .../apache/james/jmap/DownloadServletTest.java  |  8 ++---
 5 files changed, 67 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/4e0e8604/mailbox/api/src/main/java/org/apache/james/mailbox/model/Blob.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Blob.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Blob.java
index 16a372e..694faf9 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Blob.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Blob.java
@@ -19,6 +19,9 @@
 
 package org.apache.james.mailbox.model;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.Objects;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -66,12 +69,14 @@ public class Blob {
     private final BlobId blobId;
     private final byte[] payload;
     private final String contentType;
+    private final long size;
 
     @VisibleForTesting
     Blob(BlobId blobId, byte[] payload, String contentType) {
         this.blobId = blobId;
         this.payload = payload;
         this.contentType = contentType;
+        this.size = payload.length;
     }
 
     public BlobId getBlobId() {
@@ -82,6 +87,14 @@ public class Blob {
         return payload;
     }
 
+    public InputStream getStream() throws IOException {
+        return new ByteArrayInputStream(payload);
+    }
+
+    public long getSize() {
+        return size;
+    }
+
     public String getContentType() {
         return contentType;
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4e0e8604/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
index a60506a..e34c45c 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
@@ -27,6 +27,7 @@ import java.net.URISyntaxException;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Optional;
 
 import javax.inject.Inject;
 import javax.mail.Flags;
@@ -39,8 +40,10 @@ import org.apache.http.client.fluent.Response;
 import org.apache.http.client.utils.URIBuilder;
 import org.apache.james.jmap.api.access.AccessToken;
 import org.apache.james.jmap.model.AttachmentAccessToken;
+import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mime4j.codec.DecoderUtil;
 import org.apache.james.modules.MailboxProbeImpl;
 
@@ -73,6 +76,7 @@ public class DownloadStepdefs {
     private HttpResponse response;
     private Multimap<String, String> attachmentsByMessageId;
     private Map<String, String> blobIdByAttachmentId;
+    private Map<String, MessageId> inputToMessageId;
     private Map<AttachmentAccessTokenKey, AttachmentAccessToken> attachmentAccessTokens;
 
     @Inject
@@ -82,8 +86,19 @@ public class DownloadStepdefs {
         this.attachmentsByMessageId = ArrayListMultimap.create();
         this.blobIdByAttachmentId = new HashMap<>();
         this.attachmentAccessTokens = new HashMap<>();
+        this.inputToMessageId = new HashMap<>();
     }
-    
+
+    @Given("^\"([^\"]*)\" mailbox \"([^\"]*)\" contains a message \"([^\"]*)\"$")
+    public void appendMessageToMailbox(String user, String mailbox, String messageId) throws Throwable {
+        MailboxPath mailboxPath = new MailboxPath(MailboxConstants.USER_NAMESPACE, user, mailbox);
+
+        ComposedMessageId composedMessageId = mainStepdefs.jmapServer.getProbe(MailboxProbeImpl.class).appendMessage(user, mailboxPath,
+            ClassLoader.getSystemResourceAsStream("eml/oneAttachment.eml"), new Date(), false, new Flags());
+
+        inputToMessageId.put(messageId, composedMessageId.getMessageId());
+    }
+
     @Given("^\"([^\"]*)\" mailbox \"([^\"]*)\" contains a message \"([^\"]*)\" with an attachment \"([^\"]*)\"$")
     public void appendMessageWithAttachmentToMailbox(String user, String mailbox, String messageId, String attachmentId) throws Throwable {
         MailboxPath mailboxPath = new MailboxPath(MailboxConstants.USER_NAMESPACE, user, mailbox);
@@ -129,10 +144,14 @@ public class DownloadStepdefs {
     }
 
     @When("^\"([^\"]*)\" downloads \"([^\"]*)\"$")
-    public void downloads(String username, String attachmentId) throws Throwable {
-        String blobId = blobIdByAttachmentId.get(attachmentId);
-        URIBuilder uriBuilder = mainStepdefs.baseUri().setPath("/download/" + blobId);
-        response = authenticatedDownloadRequest(uriBuilder, blobId, username).execute().returnResponse();
+    public void downloads(String username, String blobId) throws Throwable {
+        String attachmentIdOrMessageId = Optional.ofNullable(blobIdByAttachmentId.get(blobId))
+            .orElse(Optional.ofNullable(inputToMessageId.get(blobId))
+                .map(MessageId::serialize)
+                .orElse(null));
+
+        URIBuilder uriBuilder = mainStepdefs.baseUri().setPath("/download/" + attachmentIdOrMessageId);
+        response = authenticatedDownloadRequest(uriBuilder, attachmentIdOrMessageId, username).execute().returnResponse();
     }
 
     private Request authenticatedDownloadRequest(URIBuilder uriBuilder, String blobId, String username) throws URISyntaxException {
@@ -324,7 +343,7 @@ public class DownloadStepdefs {
         assertThat(response.getStatusLine().getStatusCode()).isEqualTo(400);
     }
 
-    @Then("^the user should receive that attachment$")
+    @Then("^the user should receive that blob")
     public void httpOkStatusAndExpectedContent() throws IOException {
         assertThat(response.getStatusLine().getStatusCode()).isEqualTo(200);
         assertThat(IOUtils.toString(response.getEntity().getContent(), Charsets.UTF_8)).isNotEmpty();
@@ -351,7 +370,7 @@ public class DownloadStepdefs {
         }
     }
 
-    @Then("^the attachment size is (\\d+)$")
+    @Then("^the blob size is (\\d+)$")
     public void assertContentLength(int size) throws IOException {
         assertThat(response.getFirstHeader("Content-Length").getValue()).isEqualTo(String.valueOf(size));
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4e0e8604/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
index fba6926..3021f03 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
@@ -10,8 +10,8 @@ Feature: Download GET
   Scenario: Getting an attachment previously stored
     Given "username@domain.tld" mailbox "INBOX" contains a message "1" with an attachment "2"
     When "username@domain.tld" downloads "2"
-    Then the user should receive that attachment
-    And the attachment size is 3071
+    Then the user should receive that blob
+    And the blob size is 3071
 
   Scenario: Getting an attachment with an unknown blobId
     Given "username@domain.tld" mailbox "INBOX" contains a message "1" with an attachment "2"
@@ -21,11 +21,17 @@ Feature: Download GET
   Scenario: Getting an attachment previously stored with a desired name
     Given "username@domain.tld" mailbox "INBOX" contains a message "1" with an attachment "2"
     When "username@domain.tld" downloads "2" with "myFileName.txt" name
-    Then the user should receive that attachment
+    Then the user should receive that blob
     And the attachment is named "myFileName.txt"
 
   Scenario: Getting an attachment previously stored with a non ASCII name
     Given "username@domain.tld" mailbox "INBOX" contains a message "1" with an attachment "2"
     When "username@domain.tld" downloads "2" with "ديناصور.odt" name
-    Then the user should receive that attachment
-    And the attachment is named "ديناصور.odt"
\ No newline at end of file
+    Then the user should receive that blob
+    And the attachment is named "ديناصور.odt"
+
+  Scenario: Getting a message blob previously stored
+    Given "username@domain.tld" mailbox "INBOX" contains a message "1"
+    When "username@domain.tld" downloads "1"
+    Then the user should receive that blob
+    And the blob size is 4963
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/4e0e8604/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java
index a64020b..8f58405 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java
@@ -35,12 +35,12 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.commons.io.IOUtils;
 import org.apache.james.jmap.api.SimpleTokenFactory;
 import org.apache.james.jmap.utils.DownloadPath;
-import org.apache.james.mailbox.AttachmentManager;
+import org.apache.james.mailbox.BlobManager;
 import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.exception.AttachmentNotFoundException;
+import org.apache.james.mailbox.exception.BlobNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.model.Attachment;
-import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.Blob;
+import org.apache.james.mailbox.model.BlobId;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.metrics.api.TimeMetric;
 import org.apache.james.mime4j.codec.EncoderUtil;
@@ -56,13 +56,13 @@ public class DownloadServlet extends HttpServlet {
     private static final Logger LOGGER = LoggerFactory.getLogger(DownloadServlet.class);
     private static final String TEXT_PLAIN_CONTENT_TYPE = "text/plain";
 
-    private final AttachmentManager attachmentManager;
+    private final BlobManager blobManager;
     private final SimpleTokenFactory simpleTokenFactory;
     private final MetricFactory metricFactory;
 
     @Inject
-    @VisibleForTesting DownloadServlet(AttachmentManager attachmentManager, SimpleTokenFactory simpleTokenFactory, MetricFactory metricFactory) {
-        this.attachmentManager = attachmentManager;
+    @VisibleForTesting DownloadServlet(BlobManager blobManager, SimpleTokenFactory simpleTokenFactory, MetricFactory metricFactory) {
+        this.blobManager = blobManager;
         this.simpleTokenFactory = simpleTokenFactory;
         this.metricFactory = metricFactory;
     }
@@ -102,9 +102,9 @@ public class DownloadServlet extends HttpServlet {
 
     private boolean attachmentExists(MailboxSession mailboxSession, String blobId) throws MailboxException {
         try {
-            attachmentManager.getAttachment(AttachmentId.from(blobId), mailboxSession);
+            blobManager.retrieve(BlobId.fromString(blobId), mailboxSession);
             return true;
-        } catch (AttachmentNotFoundException e) {
+        } catch (BlobNotFoundException e) {
             return false;
         }
     }
@@ -125,12 +125,12 @@ public class DownloadServlet extends HttpServlet {
         try {
             addContentDispositionHeader(downloadPath.getName(), resp);
 
-            Attachment attachment = attachmentManager.getAttachment(AttachmentId.from(blobId), mailboxSession);
-            IOUtils.copy(attachment.getStream(), resp.getOutputStream());
+            Blob blob = blobManager.retrieve(BlobId.fromString(blobId), mailboxSession);
+            IOUtils.copy(blob.getStream(), resp.getOutputStream());
 
-            resp.setHeader("Content-Length", String.valueOf(attachment.getSize()));
+            resp.setHeader("Content-Length", String.valueOf(blob.getSize()));
             resp.setStatus(SC_OK);
-        } catch (AttachmentNotFoundException e) {
+        } catch (BlobNotFoundException e) {
             LOGGER.info(String.format("Attachment '%s' not found", blobId), e);
             resp.setStatus(SC_NOT_FOUND);
         } catch (MailboxException | IOException e) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/4e0e8604/server/protocols/jmap/src/test/java/org/apache/james/jmap/DownloadServletTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/DownloadServletTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/DownloadServletTest.java
index ea8a93f..a336da7 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/DownloadServletTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/DownloadServletTest.java
@@ -29,7 +29,7 @@ import javax.servlet.http.HttpServletResponse;
 
 import org.apache.james.jmap.api.SimpleTokenFactory;
 import org.apache.james.jmap.utils.DownloadPath;
-import org.apache.james.mailbox.AttachmentManager;
+import org.apache.james.mailbox.BlobManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.metrics.api.NoopMetricFactory;
@@ -40,12 +40,12 @@ public class DownloadServletTest {
     @Test
     public void downloadMayFailWhenUnknownErrorOnAttachmentManager() throws Exception {
         MailboxSession mailboxSession = mock(MailboxSession.class);
-        AttachmentManager mockedAttachmentManager = mock(AttachmentManager.class);
-        when(mockedAttachmentManager.getAttachment(any(), eq(mailboxSession)))
+        BlobManager mockedBlobManager = mock(BlobManager.class);
+        when(mockedBlobManager.retrieve(any(), eq(mailboxSession)))
             .thenThrow(new MailboxException());
         SimpleTokenFactory nullSimpleTokenFactory = null;
 
-        DownloadServlet testee = new DownloadServlet(mockedAttachmentManager, nullSimpleTokenFactory, new NoopMetricFactory());
+        DownloadServlet testee = new DownloadServlet(mockedBlobManager, nullSimpleTokenFactory, new NoopMetricFactory());
 
         HttpServletResponse resp = mock(HttpServletResponse.class);
         testee.download(mailboxSession, DownloadPath.from("/blobId"), resp);


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


[09/24] james-project git commit: JAMES-2143 Introduce StoreBlobManager

Posted by ad...@apache.org.
JAMES-2143 Introduce StoreBlobManager


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

Branch: refs/heads/master
Commit: a688e343ae9ec54d3fc442ec9a991dd06f7a7238
Parents: 6487016
Author: benwa <bt...@linagora.com>
Authored: Mon Sep 11 16:12:46 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:19:53 2017 +0200

----------------------------------------------------------------------
 .../james/mailbox/store/StoreBlobManager.java   | 109 +++++++++
 .../mailbox/store/StoreBlobManagerTest.java     | 224 +++++++++++++++++++
 2 files changed, 333 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/a688e343/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
new file mode 100644
index 0000000..e1474e3
--- /dev/null
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
@@ -0,0 +1,109 @@
+/****************************************************************
+ * 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.mailbox.store;
+
+import java.io.IOException;
+import java.util.Optional;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.james.mailbox.AttachmentManager;
+import org.apache.james.mailbox.BlobManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageIdManager;
+import org.apache.james.mailbox.exception.AttachmentNotFoundException;
+import org.apache.james.mailbox.exception.BlobNotFoundException;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.Attachment;
+import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.Blob;
+import org.apache.james.mailbox.model.BlobId;
+import org.apache.james.mailbox.model.FetchGroupImpl;
+import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.MessageResult;
+
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+
+public class StoreBlobManager implements BlobManager {
+    public static final String MESSAGE_RFC822_CONTENT_TYPE = "message/rfc822";
+    private final AttachmentManager attachmentManager;
+    private final MessageIdManager messageIdManager;
+    private final MessageId.Factory messageIdFactory;
+
+    public StoreBlobManager(AttachmentManager attachmentManager, MessageIdManager messageIdManager, MessageId.Factory messageIdFactory) {
+        this.attachmentManager = attachmentManager;
+        this.messageIdManager = messageIdManager;
+        this.messageIdFactory = messageIdFactory;
+    }
+
+    @Override
+    public Blob retrieve(BlobId blobId, MailboxSession mailboxSession) throws MailboxException, BlobNotFoundException {
+        return getBlobFromAttachment(blobId, mailboxSession)
+            .orElseGet(() -> getBlobFromMessage(blobId, mailboxSession)
+                .orElseThrow(() -> new BlobNotFoundException(blobId)));
+    }
+
+    private Optional<Blob> getBlobFromAttachment(BlobId blobId, MailboxSession mailboxSession) throws MailboxException {
+        try {
+            Attachment attachment = attachmentManager.getAttachment(
+                AttachmentId.from(blobId.asString()),
+                mailboxSession);
+            return Optional.of(attachment.toBlob());
+        } catch (AttachmentNotFoundException e) {
+            return Optional.empty();
+        }
+    }
+
+    private Optional<Blob> getBlobFromMessage(BlobId blobId, MailboxSession mailboxSession) {
+        return retrieveMessageId(blobId)
+            .flatMap(messageId -> fromMessageId(blobId, mailboxSession, messageId));
+    }
+
+    private Optional<MessageId> retrieveMessageId(BlobId blobId) {
+        try {
+            return Optional.of(messageIdFactory.fromString(blobId.asString()));
+        } catch (Exception e) {
+            return Optional.empty();
+        }
+    }
+
+    private Optional<Blob> fromMessageId(BlobId blobId, MailboxSession mailboxSession, MessageId messageId)  {
+        try {
+            return messageIdManager.getMessages(ImmutableList.of(messageId), FetchGroupImpl.FULL_CONTENT, mailboxSession)
+                .stream()
+                .findFirst()
+                .map(messageResult -> toBlob(blobId, messageResult));
+        } catch (MailboxException e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    private Blob toBlob(BlobId blobId, MessageResult messageResult) {
+        try {
+            return Blob.builder()
+                .id(blobId)
+                .contentType(MESSAGE_RFC822_CONTENT_TYPE)
+                .payload(IOUtils.toByteArray(messageResult.getFullContent().getInputStream()))
+                .build();
+        } catch (IOException | MailboxException e) {
+            throw Throwables.propagate(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/a688e343/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
new file mode 100644
index 0000000..366bc76
--- /dev/null
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
@@ -0,0 +1,224 @@
+/****************************************************************
+ * 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.mailbox.store;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.james.mailbox.AttachmentManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageIdManager;
+import org.apache.james.mailbox.exception.AttachmentNotFoundException;
+import org.apache.james.mailbox.exception.BlobNotFoundException;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.Attachment;
+import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.Blob;
+import org.apache.james.mailbox.model.BlobId;
+import org.apache.james.mailbox.model.Content;
+import org.apache.james.mailbox.model.FetchGroupImpl;
+import org.apache.james.mailbox.model.MessageResult;
+import org.apache.james.mailbox.model.TestMessageId;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class StoreBlobManagerTest {
+    public static final String ID = "abc";
+    public static final AttachmentId ATTACHMENT_ID = AttachmentId.from(ID);
+    public static final String CONTENT_TYPE = "text/plain";
+    public static final byte[] BYTES = "abc".getBytes(StandardCharsets.UTF_8);
+    public static final TestMessageId MESSAGE_ID = TestMessageId.of(125);
+    public static final BlobId BLOB_ID_ATTACHMENT = BlobId.fromString(ID);
+    public static final BlobId BLOB_ID_MESSAGE = BlobId.fromString(MESSAGE_ID.serialize());
+    private StoreBlobManager blobManager;
+
+    private AttachmentManager attachmentManager;
+    private MessageIdManager messageIdManager;
+    private MailboxSession session;
+
+    @Before
+    public void setUp() {
+        attachmentManager = mock(AttachmentManager.class);
+        messageIdManager = mock(MessageIdManager.class);
+        session = mock(MailboxSession.class);
+
+        blobManager = new StoreBlobManager(attachmentManager, messageIdManager, new TestMessageId.Factory());
+    }
+
+    @Test
+    public void retrieveShouldReturnBlobWhenAttachment() throws Exception {
+        when(attachmentManager.getAttachment(ATTACHMENT_ID, session))
+            .thenReturn(Attachment.builder()
+                .attachmentId(ATTACHMENT_ID)
+                .bytes(BYTES)
+                .type(CONTENT_TYPE)
+                .build());
+
+        assertThat(blobManager.retrieve(BLOB_ID_ATTACHMENT, session))
+            .isEqualTo(Blob.builder()
+                .id(BLOB_ID_ATTACHMENT)
+                .contentType(CONTENT_TYPE)
+                .payload(BYTES)
+                .build());
+    }
+
+    @Test
+    public void retrieveShouldThrowWhenNotFound() throws Exception {
+        when(attachmentManager.getAttachment(ATTACHMENT_ID, session))
+            .thenThrow(new AttachmentNotFoundException(ID));
+        when(messageIdManager.getMessages(ImmutableList.of(MESSAGE_ID), FetchGroupImpl.FULL_CONTENT, session))
+            .thenReturn(ImmutableList.of());
+
+        assertThatThrownBy(() -> blobManager.retrieve(BLOB_ID_ATTACHMENT, session))
+            .isInstanceOf(BlobNotFoundException.class);
+    }
+
+    @Test
+    public void retrieveShouldReturnBlobWhenMessage() throws Exception {
+        when(attachmentManager.getAttachment(any(), any()))
+            .thenThrow(new AttachmentNotFoundException(ID));
+
+        MessageResult messageResult = mock(MessageResult.class);
+        Content content = mock(Content.class);
+        when(content.getInputStream()).thenReturn(new ByteArrayInputStream(BYTES));
+        when(messageResult.getFullContent()).thenReturn(content);
+        when(messageIdManager.getMessages(ImmutableList.of(MESSAGE_ID), FetchGroupImpl.FULL_CONTENT, session))
+            .thenReturn(ImmutableList.of(messageResult));
+
+        assertThat(blobManager.retrieve(BLOB_ID_MESSAGE, session))
+            .isEqualTo(Blob.builder()
+                .id(BLOB_ID_MESSAGE)
+                .contentType(StoreBlobManager.MESSAGE_RFC822_CONTENT_TYPE)
+                .payload(BYTES)
+                .build());
+    }
+
+    @Test
+    public void retrieveShouldThrowOnMailboxExceptionWhenRetrievingAttachment() throws Exception {
+        when(attachmentManager.getAttachment(any(), any()))
+            .thenThrow(new MailboxException());
+
+        assertThatThrownBy(() -> blobManager.retrieve(BLOB_ID_MESSAGE, session))
+            .isInstanceOf(MailboxException.class);
+    }
+
+    @Test
+    public void retrieveShouldThrowOnRuntimeExceptionWhenRetrievingAttachment() throws Exception {
+        when(attachmentManager.getAttachment(any(), any()))
+            .thenThrow(new RuntimeException());
+
+        assertThatThrownBy(() -> blobManager.retrieve(BLOB_ID_MESSAGE, session))
+            .isInstanceOf(RuntimeException.class);
+    }
+
+    @Test
+    public void retrieveShouldThrowOnRuntimeExceptionWhenRetrievingMessage() throws Exception {
+        when(attachmentManager.getAttachment(any(), any()))
+            .thenThrow(new AttachmentNotFoundException(ID));
+
+        when(messageIdManager.getMessages(ImmutableList.of(MESSAGE_ID), FetchGroupImpl.FULL_CONTENT, session))
+            .thenThrow(new RuntimeException());
+
+        assertThatThrownBy(() -> blobManager.retrieve(BLOB_ID_MESSAGE, session))
+            .isInstanceOf(RuntimeException.class);
+    }
+
+    @Test
+    public void retrieveShouldThrowOnMailboxExceptionWhenRetrievingMessage() throws Exception {
+        when(attachmentManager.getAttachment(any(), any()))
+            .thenThrow(new AttachmentNotFoundException(ID));
+
+        when(messageIdManager.getMessages(ImmutableList.of(MESSAGE_ID), FetchGroupImpl.FULL_CONTENT, session))
+            .thenThrow(new MailboxException());
+
+        assertThatThrownBy(() -> blobManager.retrieve(BLOB_ID_MESSAGE, session))
+            .isInstanceOf(RuntimeException.class);
+    }
+
+    @Test
+    public void retrieveShouldThrowOnMailboxExceptionWhenRetrievingMessageContent() throws Exception {
+        when(attachmentManager.getAttachment(any(), any()))
+            .thenThrow(new AttachmentNotFoundException(ID));
+
+        MessageResult messageResult = mock(MessageResult.class);
+        when(messageResult.getFullContent()).thenThrow(new MailboxException());
+        when(messageIdManager.getMessages(ImmutableList.of(MESSAGE_ID), FetchGroupImpl.FULL_CONTENT, session))
+            .thenReturn(ImmutableList.of(messageResult));
+
+        assertThatThrownBy(() -> blobManager.retrieve(BLOB_ID_MESSAGE, session))
+            .isInstanceOf(RuntimeException.class);
+    }
+
+    @Test
+    public void retrieveShouldThrowOnRuntimeExceptionWhenRetrievingMessageContent() throws Exception {
+        when(attachmentManager.getAttachment(any(), any()))
+            .thenThrow(new AttachmentNotFoundException(ID));
+
+        MessageResult messageResult = mock(MessageResult.class);
+        when(messageResult.getFullContent()).thenThrow(new RuntimeException());
+        when(messageIdManager.getMessages(ImmutableList.of(MESSAGE_ID), FetchGroupImpl.FULL_CONTENT, session))
+            .thenReturn(ImmutableList.of(messageResult));
+
+        assertThatThrownBy(() -> blobManager.retrieve(BLOB_ID_MESSAGE, session))
+            .isInstanceOf(RuntimeException.class);
+    }
+
+    @Test
+    public void retrieveShouldThrowOnIOExceptionWhenRetrievingMessageContentInputStream() throws Exception {
+        when(attachmentManager.getAttachment(any(), any()))
+            .thenThrow(new AttachmentNotFoundException(ID));
+
+        MessageResult messageResult = mock(MessageResult.class);
+        Content content = mock(Content.class);
+        when(content.getInputStream()).thenThrow(new IOException());
+        when(messageResult.getFullContent()).thenReturn(content);
+        when(messageIdManager.getMessages(ImmutableList.of(MESSAGE_ID), FetchGroupImpl.FULL_CONTENT, session))
+            .thenReturn(ImmutableList.of(messageResult));
+
+        assertThatThrownBy(() -> blobManager.retrieve(BLOB_ID_MESSAGE, session))
+            .isInstanceOf(RuntimeException.class);
+    }
+
+    @Test
+    public void retrieveShouldThrowOnRuntimeExceptionWhenRetrievingMessageContentInputStream() throws Exception {
+        when(attachmentManager.getAttachment(any(), any()))
+            .thenThrow(new AttachmentNotFoundException(ID));
+
+        MessageResult messageResult = mock(MessageResult.class);
+        Content content = mock(Content.class);
+        when(content.getInputStream()).thenThrow(new RuntimeException());
+        when(messageResult.getFullContent()).thenReturn(content);
+        when(messageIdManager.getMessages(ImmutableList.of(MESSAGE_ID), FetchGroupImpl.FULL_CONTENT, session))
+            .thenReturn(ImmutableList.of(messageResult));
+
+        assertThatThrownBy(() -> blobManager.retrieve(BLOB_ID_MESSAGE, session))
+            .isInstanceOf(RuntimeException.class);
+    }
+
+}


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


[03/24] james-project git commit: MAILBOX-304 Create and implement migration task

Posted by ad...@apache.org.
MAILBOX-304 Create and implement migration task


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

Branch: refs/heads/master
Commit: 2001443b951ee46828b68331e75f9a0708452fde
Parents: 8f1c35b
Author: benwa <bt...@linagora.com>
Authored: Fri Sep 8 18:28:30 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:17:09 2017 +0200

----------------------------------------------------------------------
 .../versions/CassandraSchemaVersionManager.java |   2 +-
 .../mail/migration/AttachmentV2Migration.java   |  71 ++++++
 .../migration/AttachmentV2MigrationTest.java    | 219 +++++++++++++++++++
 .../modules/mailbox/CassandraMailboxModule.java |   4 +
 .../modules/server/CassandraRoutesModule.java   |   3 +
 5 files changed, 298 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/2001443b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/versions/CassandraSchemaVersionManager.java
----------------------------------------------------------------------
diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/versions/CassandraSchemaVersionManager.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/versions/CassandraSchemaVersionManager.java
index 79072b7..663db63 100644
--- a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/versions/CassandraSchemaVersionManager.java
+++ b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/versions/CassandraSchemaVersionManager.java
@@ -34,7 +34,7 @@ import com.google.common.base.Preconditions;
 
 public class CassandraSchemaVersionManager {
     public static final int MIN_VERSION = 2;
-    public static final int MAX_VERSION = 3;
+    public static final int MAX_VERSION = 4;
     public static final int DEFAULT_VERSION = 2;
 
     private static final Logger LOGGER = LoggerFactory.getLogger(CassandraSchemaVersionManager.class);

http://git-wip-us.apache.org/repos/asf/james-project/blob/2001443b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2Migration.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2Migration.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2Migration.java
new file mode 100644
index 0000000..8290deb
--- /dev/null
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2Migration.java
@@ -0,0 +1,71 @@
+/****************************************************************
+ * 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.mailbox.cassandra.mail.migration;
+
+import javax.inject.Inject;
+
+import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAOV2;
+import org.apache.james.mailbox.cassandra.mail.CassandraBlobsDAO;
+import org.apache.james.mailbox.model.Attachment;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AttachmentV2Migration implements Migration {
+    private static final Logger LOGGER = LoggerFactory.getLogger(AttachmentV2Migration.class);
+    private final CassandraAttachmentDAO attachmentDAOV1;
+    private final CassandraAttachmentDAOV2 attachmentDAOV2;
+    private final CassandraBlobsDAO blobsDAO;
+
+    @Inject
+    public AttachmentV2Migration(CassandraAttachmentDAO attachmentDAOV1,
+                                 CassandraAttachmentDAOV2 attachmentDAOV2,
+                                 CassandraBlobsDAO blobsDAO) {
+        this.attachmentDAOV1 = attachmentDAOV1;
+        this.attachmentDAOV2 = attachmentDAOV2;
+        this.blobsDAO = blobsDAO;
+    }
+
+    @Override
+    public MigrationResult run() {
+        try {
+            return attachmentDAOV1.retrieveAll()
+                .map(this::migrateAttachment)
+                .reduce(MigrationResult.COMPLETED, Migration::combine);
+        } catch (Exception e) {
+            LOGGER.error("Error while performing attachmentDAO V2 migration", e);
+            return MigrationResult.PARTIAL;
+        }
+    }
+
+    private MigrationResult migrateAttachment(Attachment attachment) {
+        try {
+            blobsDAO.save(attachment.getBytes())
+                .thenApply(blobId -> CassandraAttachmentDAOV2.from(attachment, blobId))
+                .thenCompose(attachmentDAOV2::storeAttachment)
+                .thenCompose(any -> attachmentDAOV1.deleteAttachment(attachment.getAttachmentId()))
+                .join();
+            return MigrationResult.COMPLETED;
+        } catch (Exception e) {
+            LOGGER.error("Error while performing attachmentDAO V2 migration", e);
+            return MigrationResult.PARTIAL;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/2001443b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2MigrationTest.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2MigrationTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2MigrationTest.java
new file mode 100644
index 0000000..7bbbb39
--- /dev/null
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2MigrationTest.java
@@ -0,0 +1,219 @@
+/****************************************************************
+ * 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.mailbox.cassandra.mail.migration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Stream;
+
+import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.backends.cassandra.DockerCassandraRule;
+import org.apache.james.backends.cassandra.init.CassandraModuleComposite;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.mailbox.cassandra.ids.BlobId;
+import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAOV2;
+import org.apache.james.mailbox.cassandra.mail.CassandraBlobsDAO;
+import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
+import org.apache.james.mailbox.cassandra.modules.CassandraBlobModule;
+import org.apache.james.mailbox.model.Attachment;
+import org.apache.james.mailbox.model.AttachmentId;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+public class AttachmentV2MigrationTest {
+    public static final AttachmentId ATTACHMENT_ID = AttachmentId.from("id1");
+    public static final AttachmentId ATTACHMENT_ID_2 = AttachmentId.from("id2");
+
+    @ClassRule
+    public static DockerCassandraRule cassandraServer = new DockerCassandraRule();
+
+    private CassandraAttachmentDAO attachmentDAO;
+    private CassandraAttachmentDAOV2 attachmentDAOV2;
+    private CassandraBlobsDAO blobsDAO;
+    private AttachmentV2Migration migration;
+    private Attachment attachment1;
+    private Attachment attachment2;
+
+    @Before
+    public void setUp() {
+        CassandraCluster cassandra = CassandraCluster.create(
+            new CassandraModuleComposite(
+                new CassandraAttachmentModule(),
+                new CassandraBlobModule()),
+            cassandraServer.getIp(),
+            cassandraServer.getBindingPort());
+
+        attachmentDAO = new CassandraAttachmentDAO(cassandra.getConf(), CassandraUtils.WITH_DEFAULT_CONFIGURATION);
+        attachmentDAOV2 = new CassandraAttachmentDAOV2(cassandra.getConf());
+        blobsDAO = new CassandraBlobsDAO(cassandra.getConf());
+
+        migration = new AttachmentV2Migration(attachmentDAO, attachmentDAOV2, blobsDAO);
+
+        attachment1 = Attachment.builder()
+            .attachmentId(ATTACHMENT_ID)
+            .type("application/json")
+            .bytes("{\"property\":`\"value1\"}".getBytes(StandardCharsets.UTF_8))
+            .build();
+        attachment2 = Attachment.builder()
+            .attachmentId(ATTACHMENT_ID_2)
+            .type("application/json")
+            .bytes("{\"property\":`\"value2\"}".getBytes(StandardCharsets.UTF_8))
+            .build();
+    }
+
+    @Test
+    public void emptyMigrationShouldSucceed() {
+        assertThat(migration.run())
+            .isEqualTo(Migration.MigrationResult.COMPLETED);
+    }
+
+    @Test
+    public void migrationShouldSucceed() throws Exception {
+        attachmentDAO.storeAttachment(attachment1).join();
+        attachmentDAO.storeAttachment(attachment2).join();
+
+        assertThat(migration.run())
+            .isEqualTo(Migration.MigrationResult.COMPLETED);
+    }
+
+    @Test
+    public void migrationShouldMoveAttachmentsToV2() throws Exception {
+        attachmentDAO.storeAttachment(attachment1).join();
+        attachmentDAO.storeAttachment(attachment2).join();
+
+        migration.run();
+
+        assertThat(attachmentDAOV2.getAttachment(ATTACHMENT_ID).join())
+            .contains(CassandraAttachmentDAOV2.from(attachment1, BlobId.forPayload(attachment1.getBytes())));
+        assertThat(attachmentDAOV2.getAttachment(ATTACHMENT_ID_2).join())
+            .contains(CassandraAttachmentDAOV2.from(attachment2, BlobId.forPayload(attachment2.getBytes())));
+        assertThat(blobsDAO.read(BlobId.forPayload(attachment1.getBytes())).join())
+            .isEqualTo(attachment1.getBytes());
+        assertThat(blobsDAO.read(BlobId.forPayload(attachment2.getBytes())).join())
+            .isEqualTo(attachment2.getBytes());
+    }
+
+    @Test
+    public void migrationShouldRemoveAttachmentsFromV1() throws Exception {
+        attachmentDAO.storeAttachment(attachment1).join();
+        attachmentDAO.storeAttachment(attachment2).join();
+
+        migration.run();
+
+        assertThat(attachmentDAO.getAttachment(ATTACHMENT_ID).join())
+            .isEmpty();
+        assertThat(attachmentDAO.getAttachment(ATTACHMENT_ID_2).join())
+            .isEmpty();
+    }
+
+    @Test
+    public void runShouldReturnPartialWhenInitialReadFail() throws Exception {
+        CassandraAttachmentDAO attachmentDAO = mock(CassandraAttachmentDAO.class);
+        CassandraAttachmentDAOV2 attachmentDAOV2 = mock(CassandraAttachmentDAOV2.class);
+        CassandraBlobsDAO blobsDAO = mock(CassandraBlobsDAO.class);
+        migration = new AttachmentV2Migration(attachmentDAO, attachmentDAOV2, blobsDAO);
+
+        when(attachmentDAO.retrieveAll()).thenThrow(new RuntimeException());
+
+        assertThat(migration.run()).isEqualTo(Migration.MigrationResult.PARTIAL);
+    }
+
+    @Test
+    public void runShouldReturnPartialWhenSavingBlobsFails() throws Exception {
+        CassandraAttachmentDAO attachmentDAO = mock(CassandraAttachmentDAO.class);
+        CassandraAttachmentDAOV2 attachmentDAOV2 = mock(CassandraAttachmentDAOV2.class);
+        CassandraBlobsDAO blobsDAO = mock(CassandraBlobsDAO.class);
+        migration = new AttachmentV2Migration(attachmentDAO, attachmentDAOV2, blobsDAO);
+
+        when(attachmentDAO.retrieveAll()).thenReturn(Stream.of(
+            attachment1,
+            attachment2));
+        when(blobsDAO.save(any())).thenThrow(new RuntimeException());
+
+        assertThat(migration.run()).isEqualTo(Migration.MigrationResult.PARTIAL);
+    }
+
+    @Test
+    public void runShouldReturnPartialWhenSavingAttachmentV2Fail() throws Exception {
+        CassandraAttachmentDAO attachmentDAO = mock(CassandraAttachmentDAO.class);
+        CassandraAttachmentDAOV2 attachmentDAOV2 = mock(CassandraAttachmentDAOV2.class);
+        CassandraBlobsDAO blobsDAO = mock(CassandraBlobsDAO.class);
+        migration = new AttachmentV2Migration(attachmentDAO, attachmentDAOV2, blobsDAO);
+
+        when(attachmentDAO.retrieveAll()).thenReturn(Stream.of(
+            attachment1,
+            attachment2));
+        when(blobsDAO.save(attachment1.getBytes()))
+            .thenReturn(CompletableFuture.completedFuture(BlobId.forPayload(attachment1.getBytes())));
+        when(blobsDAO.save(attachment2.getBytes()))
+            .thenReturn(CompletableFuture.completedFuture(BlobId.forPayload(attachment2.getBytes())));
+        when(attachmentDAOV2.storeAttachment(any())).thenThrow(new RuntimeException());
+
+        assertThat(migration.run()).isEqualTo(Migration.MigrationResult.PARTIAL);
+    }
+
+    @Test
+    public void runShouldReturnPartialWhenDeleteV1AttachmentFail() throws Exception {
+        CassandraAttachmentDAO attachmentDAO = mock(CassandraAttachmentDAO.class);
+        CassandraAttachmentDAOV2 attachmentDAOV2 = mock(CassandraAttachmentDAOV2.class);
+        CassandraBlobsDAO blobsDAO = mock(CassandraBlobsDAO.class);
+        migration = new AttachmentV2Migration(attachmentDAO, attachmentDAOV2, blobsDAO);
+
+        when(attachmentDAO.retrieveAll()).thenReturn(Stream.of(
+            attachment1,
+            attachment2));
+        when(blobsDAO.save(attachment1.getBytes()))
+            .thenReturn(CompletableFuture.completedFuture(BlobId.forPayload(attachment1.getBytes())));
+        when(blobsDAO.save(attachment2.getBytes()))
+            .thenReturn(CompletableFuture.completedFuture(BlobId.forPayload(attachment2.getBytes())));
+        when(attachmentDAOV2.storeAttachment(any())).thenReturn(CompletableFuture.completedFuture(null));
+        when(attachmentDAO.deleteAttachment(any())).thenThrow(new RuntimeException());
+
+        assertThat(migration.run()).isEqualTo(Migration.MigrationResult.PARTIAL);
+    }
+
+    @Test
+    public void runShouldReturnPartialWhenAtLeastOneAttachmentMigrationFails() throws Exception {
+        CassandraAttachmentDAO attachmentDAO = mock(CassandraAttachmentDAO.class);
+        CassandraAttachmentDAOV2 attachmentDAOV2 = mock(CassandraAttachmentDAOV2.class);
+        CassandraBlobsDAO blobsDAO = mock(CassandraBlobsDAO.class);
+        migration = new AttachmentV2Migration(attachmentDAO, attachmentDAOV2, blobsDAO);
+
+        when(attachmentDAO.retrieveAll()).thenReturn(Stream.of(
+            attachment1,
+            attachment2));
+        when(blobsDAO.save(attachment1.getBytes()))
+            .thenReturn(CompletableFuture.completedFuture(BlobId.forPayload(attachment1.getBytes())));
+        when(blobsDAO.save(attachment2.getBytes()))
+            .thenThrow(new RuntimeException());
+        when(attachmentDAOV2.storeAttachment(any())).thenReturn(CompletableFuture.completedFuture(null));
+        when(attachmentDAO.deleteAttachment(any())).thenReturn(CompletableFuture.completedFuture(null));
+
+        assertThat(migration.run()).isEqualTo(Migration.MigrationResult.PARTIAL);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/2001443b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
index ae0b844..732b3ff 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
@@ -33,6 +33,8 @@ import org.apache.james.mailbox.cassandra.CassandraMailboxSessionMapperFactory;
 import org.apache.james.mailbox.cassandra.CassandraSubscriptionManager;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
+import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAOV2;
 import org.apache.james.mailbox.cassandra.mail.CassandraBlobsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxMapper;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
@@ -94,6 +96,8 @@ public class CassandraMailboxModule extends AbstractModule {
         bind(CassandraMailboxMapper.class).in(Scopes.SINGLETON);
         bind(CassandraMessageDAO.class).in(Scopes.SINGLETON);
         bind(CassandraBlobsDAO.class).in(Scopes.SINGLETON);
+        bind(CassandraAttachmentDAO.class).in(Scopes.SINGLETON);
+        bind(CassandraAttachmentDAOV2.class).in(Scopes.SINGLETON);
 
         bind(MessageMapperFactory.class).to(CassandraMailboxSessionMapperFactory.class);
         bind(MailboxMapperFactory.class).to(CassandraMailboxSessionMapperFactory.class);

http://git-wip-us.apache.org/repos/asf/james-project/blob/2001443b/server/container/guice/protocols/webadmin-cassandra/src/main/java/org/apache/james/modules/server/CassandraRoutesModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/webadmin-cassandra/src/main/java/org/apache/james/modules/server/CassandraRoutesModule.java b/server/container/guice/protocols/webadmin-cassandra/src/main/java/org/apache/james/modules/server/CassandraRoutesModule.java
index 55b8c23..96f807c 100644
--- a/server/container/guice/protocols/webadmin-cassandra/src/main/java/org/apache/james/modules/server/CassandraRoutesModule.java
+++ b/server/container/guice/protocols/webadmin-cassandra/src/main/java/org/apache/james/modules/server/CassandraRoutesModule.java
@@ -20,6 +20,7 @@
 package org.apache.james.modules.server;
 
 import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionManager;
+import org.apache.james.mailbox.cassandra.mail.migration.AttachmentV2Migration;
 import org.apache.james.mailbox.cassandra.mail.migration.Migration;
 import org.apache.james.webadmin.Routes;
 import org.apache.james.webadmin.routes.CassandraMigrationRoutes;
@@ -33,6 +34,7 @@ import com.google.inject.name.Names;
 
 public class CassandraRoutesModule extends AbstractModule {
     private static final int FROM_V2_TO_V3 = 2;
+    private static final int FROM_V3_TO_V4 = 3;
 
     @Override
     protected void configure() {
@@ -44,6 +46,7 @@ public class CassandraRoutesModule extends AbstractModule {
 
         MapBinder<Integer, Migration> allMigrationClazzBinder = MapBinder.newMapBinder(binder(), Integer.class, Migration.class);
         allMigrationClazzBinder.addBinding(FROM_V2_TO_V3).toInstance(() -> Migration.MigrationResult.COMPLETED);
+        allMigrationClazzBinder.addBinding(FROM_V3_TO_V4).to(AttachmentV2Migration.class);
 
         bindConstant()
             .annotatedWith(Names.named(CassandraMigrationService.LATEST_VERSION))


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


[14/24] james-project git commit: JAMES-2142 Fix Eclipse warnings

Posted by ad...@apache.org.
JAMES-2142 Fix Eclipse warnings


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

Branch: refs/heads/master
Commit: a9a40c70621e25ae8b3fd00410c34eae7293c0bb
Parents: 38db514
Author: Antoine Duprat <ad...@linagora.com>
Authored: Fri Sep 8 10:54:04 2017 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:21:06 2017 +0200

----------------------------------------------------------------------
 .../integration/GetMessageListMethodTest.java   | 31 ++++++++++----------
 1 file changed, 16 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/a9a40c70/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
index df53f63..a58eadc 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
@@ -29,12 +29,15 @@ import static org.hamcrest.Matchers.empty;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.not;
+
 import java.io.ByteArrayInputStream;
 import java.time.LocalDate;
 import java.time.ZoneId;
 import java.util.Date;
+
 import javax.mail.Flags;
 
+import org.apache.http.client.utils.URIBuilder;
 import org.apache.james.GuiceJamesServer;
 import org.apache.james.jmap.HttpJmapAuthentication;
 import org.apache.james.jmap.api.access.AccessToken;
@@ -50,17 +53,15 @@ import org.apache.james.probe.DataProbe;
 import org.apache.james.util.date.ImapDateTimeFormatter;
 import org.apache.james.utils.DataProbeImpl;
 import org.apache.james.utils.JmapGuiceProbe;
-import org.apache.http.client.utils.URIBuilder;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
 
 import com.google.common.base.Charsets;
 import com.jayway.restassured.RestAssured;
 import com.jayway.restassured.builder.RequestSpecBuilder;
 import com.jayway.restassured.http.ContentType;
 
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
 public abstract class GetMessageListMethodTest {
     private final static String FORWARDED = "$Forwarded";
     private static final String NAME = "[0][0]";
@@ -1462,8 +1463,8 @@ public abstract class GetMessageListMethodTest {
         .then()
             .statusCode(200)
             .body(NAME, equalTo("messageList"))
-            .body(ARGUMENTS + ".messageIds", allOf(
-                containsInAnyOrder(messageNotFlagged.getMessageId().serialize(), messageFlagged.getMessageId().serialize())));
+            .body(ARGUMENTS + ".messageIds",
+                containsInAnyOrder(messageNotFlagged.getMessageId().serialize(), messageFlagged.getMessageId().serialize()));
     }
 
     @Test
@@ -1509,8 +1510,8 @@ public abstract class GetMessageListMethodTest {
         .then()
             .statusCode(200)
             .body(NAME, equalTo("messageList"))
-            .body(ARGUMENTS + ".messageIds", allOf(
-                containsInAnyOrder(messageFlagged.getMessageId().serialize(), messageNotFlagged.getMessageId().serialize())));
+            .body(ARGUMENTS + ".messageIds",
+                containsInAnyOrder(messageFlagged.getMessageId().serialize(), messageNotFlagged.getMessageId().serialize()));
     }
 
     @Test
@@ -1532,8 +1533,8 @@ public abstract class GetMessageListMethodTest {
         .then()
             .statusCode(200)
             .body(NAME, equalTo("messageList"))
-            .body(ARGUMENTS + ".messageIds", allOf(
-                containsInAnyOrder(messageFlagged.getMessageId().serialize(), messageNotFlagged.getMessageId().serialize())));
+            .body(ARGUMENTS + ".messageIds",
+                containsInAnyOrder(messageFlagged.getMessageId().serialize(), messageNotFlagged.getMessageId().serialize()));
     }
 
     @Test
@@ -1555,8 +1556,8 @@ public abstract class GetMessageListMethodTest {
         .then()
             .statusCode(200)
             .body(NAME, equalTo("messageList"))
-            .body(ARGUMENTS + ".messageIds", allOf(
-                containsInAnyOrder(messageFlagged.getMessageId().serialize(), messageNotFlagged.getMessageId().serialize())));
+            .body(ARGUMENTS + ".messageIds",
+                containsInAnyOrder(messageFlagged.getMessageId().serialize(), messageNotFlagged.getMessageId().serialize()));
     }
 
     @Test
@@ -1578,8 +1579,8 @@ public abstract class GetMessageListMethodTest {
         .then()
             .statusCode(200)
             .body(NAME, equalTo("messageList"))
-            .body(ARGUMENTS + ".messageIds", allOf(
-                containsInAnyOrder(messageFlagged.getMessageId().serialize(), messageNotFlagged.getMessageId().serialize())));
+            .body(ARGUMENTS + ".messageIds",
+                containsInAnyOrder(messageFlagged.getMessageId().serialize(), messageNotFlagged.getMessageId().serialize()));
     }
 
     @Test


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


[02/24] james-project git commit: MAILBOX-304 Allow deleting attachments from old DAO

Posted by ad...@apache.org.
MAILBOX-304 Allow deleting attachments from old DAO


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

Branch: refs/heads/master
Commit: 8f1c35b9b4a0d723ef4bf1f0faf31d08a03d3398
Parents: 9031bbd
Author: benwa <bt...@linagora.com>
Authored: Fri Sep 8 18:27:58 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:17:08 2017 +0200

----------------------------------------------------------------------
 .../cassandra/mail/CassandraAttachmentDAO.java     | 17 +++++++++++++++++
 .../cassandra/mail/CassandraAttachmentDAOTest.java | 15 +++++++++++++++
 2 files changed, 32 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/8f1c35b9/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAO.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAO.java
index d1ec829..532dea3 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAO.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAO.java
@@ -20,6 +20,7 @@
 package org.apache.james.mailbox.cassandra.mail;
 
 import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.delete;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
@@ -56,6 +57,7 @@ public class CassandraAttachmentDAO {
     private final CassandraAsyncExecutor cassandraAsyncExecutor;
     private final CassandraUtils cassandraUtils;
     private final PreparedStatement insertStatement;
+    private final PreparedStatement deleteStatement;
     private final PreparedStatement selectStatement;
     private final PreparedStatement selectAllStatement;
 
@@ -65,10 +67,18 @@ public class CassandraAttachmentDAO {
 
         this.selectStatement = prepareSelect(session);
         this.selectAllStatement = prepareSelectAll(session);
+        this.deleteStatement = prepareDelete(session);
         this.insertStatement = prepareInsert(session);
         this.cassandraUtils = cassandraUtils;
     }
 
+    private PreparedStatement prepareDelete(Session session) {
+        return session.prepare(
+            delete()
+                .from(TABLE_NAME)
+                .where(eq(ID, bindMarker(ID))));
+    }
+
     private PreparedStatement prepareInsert(Session session) {
         return session.prepare(
             insertInto(TABLE_NAME)
@@ -116,6 +126,13 @@ public class CassandraAttachmentDAO {
                 .setBytes(PAYLOAD, ByteBuffer.wrap(attachment.getBytes())));
     }
 
+    public CompletableFuture<Void> deleteAttachment(AttachmentId attachmentId) {
+        return cassandraAsyncExecutor.executeVoid(
+            deleteStatement
+                .bind()
+                .setString(ID, attachmentId.getId()));
+    }
+
     private Attachment attachment(Row row) {
         return Attachment.builder()
             .attachmentId(AttachmentId.from(row.getString(ID)))

http://git-wip-us.apache.org/repos/asf/james-project/blob/8f1c35b9/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOTest.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOTest.java
index e26af08..3b00a1a 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOTest.java
@@ -109,4 +109,19 @@ public class CassandraAttachmentDAOTest {
 
         assertThat(actual).contains(attachment);
     }
+
+    @Test
+    public void deleteAttachmentShouldRemoveAttachment() throws Exception {
+        Attachment attachment = Attachment.builder()
+            .attachmentId(ATTACHMENT_ID)
+            .type("application/json")
+            .bytes("{\"property\":`\"value\"}".getBytes(StandardCharsets.UTF_8))
+            .build();
+        testee.storeAttachment(attachment).join();
+
+        testee.deleteAttachment(attachment.getAttachmentId()).join();
+
+        assertThat(testee.getAttachment(attachment.getAttachmentId()).join())
+            .isEmpty();
+    }
 }


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


[19/24] james-project git commit: JAMES-2139 DataProbe support domain mapping

Posted by ad...@apache.org.
JAMES-2139 DataProbe support domain mapping


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

Branch: refs/heads/master
Commit: bdedd0bfe45a81d93a69cb60ea62d1ea0de328eb
Parents: 1b4d923
Author: quynhn <qn...@linagora.com>
Authored: Thu Sep 7 11:21:44 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:23:33 2017 +0200

----------------------------------------------------------------------
 .../james/cli/probe/impl/JmxDataProbe.java      | 47 ++++++++++++--------
 .../org/apache/james/utils/DataProbeImpl.java   |  4 ++
 .../java/org/apache/james/probe/DataProbe.java  |  2 +
 3 files changed, 35 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/bdedd0bf/server/container/cli/src/main/java/org/apache/james/cli/probe/impl/JmxDataProbe.java
----------------------------------------------------------------------
diff --git a/server/container/cli/src/main/java/org/apache/james/cli/probe/impl/JmxDataProbe.java b/server/container/cli/src/main/java/org/apache/james/cli/probe/impl/JmxDataProbe.java
index 3c70b24..debcef9 100644
--- a/server/container/cli/src/main/java/org/apache/james/cli/probe/impl/JmxDataProbe.java
+++ b/server/container/cli/src/main/java/org/apache/james/cli/probe/impl/JmxDataProbe.java
@@ -35,9 +35,10 @@ import org.apache.james.util.MDCBuilder;
 
 public class JmxDataProbe implements DataProbe, JmxProbe {
 
-    private final static String DOMAINLIST_OBJECT_NAME = "org.apache.james:type=component,name=domainlist";
-    private final static String VIRTUALUSERTABLE_OBJECT_NAME = "org.apache.james:type=component,name=recipientrewritetable";
-    private final static String USERSREPOSITORY_OBJECT_NAME = "org.apache.james:type=component,name=usersrepository";
+    private static final String DOMAINLIST_OBJECT_NAME = "org.apache.james:type=component,name=domainlist";
+    private static final String VIRTUALUSERTABLE_OBJECT_NAME = "org.apache.james:type=component,name=recipientrewritetable";
+    private static final String USERSREPOSITORY_OBJECT_NAME = "org.apache.james:type=component,name=usersrepository";
+    private static final String JMX = "JMX";
 
     private DomainListManagementMBean domainListProxy;
     private RecipientRewriteTableManagementMBean virtualUserTableProxy;
@@ -58,7 +59,7 @@ public class JmxDataProbe implements DataProbe, JmxProbe {
     public void addUser(String userName, String password) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addContext(MDCBuilder.PROTOCOL, JMX)
                      .addContext(MDCBuilder.ACTION, "addUser")
                      .addContext("parameter", userName)
                      .build()) {
@@ -70,7 +71,7 @@ public class JmxDataProbe implements DataProbe, JmxProbe {
     public void removeUser(String username) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addContext(MDCBuilder.PROTOCOL, JMX)
                      .addContext(MDCBuilder.ACTION, "removeUser")
                      .addContext("parameter", username)
                      .build()) {
@@ -82,7 +83,7 @@ public class JmxDataProbe implements DataProbe, JmxProbe {
     public String[] listUsers() throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addContext(MDCBuilder.PROTOCOL, JMX)
                      .addContext(MDCBuilder.ACTION, "listUsers")
                      .build()) {
             return usersRepositoryProxy.listAllUsers();
@@ -93,7 +94,7 @@ public class JmxDataProbe implements DataProbe, JmxProbe {
     public void setPassword(String userName, String password) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addContext(MDCBuilder.PROTOCOL, JMX)
                      .addContext(MDCBuilder.ACTION, "setPassword")
                      .addContext("parameter", userName)
                      .build()) {
@@ -105,7 +106,7 @@ public class JmxDataProbe implements DataProbe, JmxProbe {
     public boolean containsDomain(String domain) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addContext(MDCBuilder.PROTOCOL, JMX)
                      .addContext(MDCBuilder.ACTION, "containsDomain")
                      .addContext("parameter", domain)
                      .build()) {
@@ -117,7 +118,7 @@ public class JmxDataProbe implements DataProbe, JmxProbe {
     public String getDefaultDomain() throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addContext(MDCBuilder.PROTOCOL, JMX)
                      .addContext(MDCBuilder.ACTION, "getDefaultDomain")
                      .build()) {
             return domainListProxy.getDefaultDomain();
@@ -128,7 +129,7 @@ public class JmxDataProbe implements DataProbe, JmxProbe {
     public void addDomain(String domain) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addContext(MDCBuilder.PROTOCOL, JMX)
                      .addContext(MDCBuilder.ACTION, "addDomain")
                      .addContext("parameter", domain)
                      .build()) {
@@ -140,7 +141,7 @@ public class JmxDataProbe implements DataProbe, JmxProbe {
     public void removeDomain(String domain) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addContext(MDCBuilder.PROTOCOL, JMX)
                      .addContext(MDCBuilder.ACTION, "removeDomain")
                      .addContext("parameter", domain)
                      .build()) {
@@ -152,7 +153,7 @@ public class JmxDataProbe implements DataProbe, JmxProbe {
     public List<String> listDomains() throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addContext(MDCBuilder.PROTOCOL, JMX)
                      .addContext(MDCBuilder.ACTION, "listDomains")
                      .build()) {
             return domainListProxy.getDomains();
@@ -163,7 +164,7 @@ public class JmxDataProbe implements DataProbe, JmxProbe {
     public Map<String, Mappings> listMappings() throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addContext(MDCBuilder.PROTOCOL, JMX)
                      .addContext(MDCBuilder.ACTION, "listMappings")
                      .build()) {
             return virtualUserTableProxy.getAllMappings();
@@ -174,7 +175,7 @@ public class JmxDataProbe implements DataProbe, JmxProbe {
     public void addAddressMapping(String user, String domain, String toAddress) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addContext(MDCBuilder.PROTOCOL, JMX)
                      .addContext(MDCBuilder.ACTION, "addAddressMapping")
                      .build()) {
             virtualUserTableProxy.addAddressMapping(user, domain, toAddress);
@@ -185,7 +186,7 @@ public class JmxDataProbe implements DataProbe, JmxProbe {
     public void removeAddressMapping(String user, String domain, String fromAddress) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addContext(MDCBuilder.PROTOCOL, JMX)
                      .addContext(MDCBuilder.ACTION, "removeAddressMapping")
                      .build()) {
             virtualUserTableProxy.removeAddressMapping(user, domain, fromAddress);
@@ -196,7 +197,7 @@ public class JmxDataProbe implements DataProbe, JmxProbe {
     public Mappings listUserDomainMappings(String user, String domain) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addContext(MDCBuilder.PROTOCOL, JMX)
                      .addContext(MDCBuilder.ACTION, "listUserDomainMappings")
                      .build()) {
             return virtualUserTableProxy.getUserDomainMappings(user, domain);
@@ -207,7 +208,7 @@ public class JmxDataProbe implements DataProbe, JmxProbe {
     public void addRegexMapping(String user, String domain, String regex) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addContext(MDCBuilder.PROTOCOL, JMX)
                      .addContext(MDCBuilder.ACTION, "addRegexMapping")
                      .build()) {
             virtualUserTableProxy.addRegexMapping(user, domain, regex);
@@ -218,11 +219,21 @@ public class JmxDataProbe implements DataProbe, JmxProbe {
     public void removeRegexMapping(String user, String domain, String regex) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addContext(MDCBuilder.PROTOCOL, JMX)
                      .addContext(MDCBuilder.ACTION, "removeRegexMapping")
                      .build()) {
             virtualUserTableProxy.removeRegexMapping(user, domain, regex);
         }
     }
 
+    @Override
+    public void addDomainAliasMapping(String aliasDomain, String deliveryDomain) throws Exception {
+        try (Closeable closeable =
+                 MDCBuilder.create()
+                     .addContext(MDCBuilder.PROTOCOL, JMX)
+                     .addContext(MDCBuilder.ACTION, "addDomainAliasMapping")
+                     .build()) {
+            virtualUserTableProxy.addDomainMapping(aliasDomain, deliveryDomain);
+        }
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/bdedd0bf/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java
index 8fdfccf..ed4d522 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java
@@ -127,4 +127,8 @@ public class DataProbeImpl implements GuiceProbe, DataProbe {
         recipientRewriteTable.removeRegexMapping(user, domain, regex);
     }
 
+    @Override
+    public void addDomainAliasMapping(String aliasDomain, String deliveryDomain) throws Exception {
+        recipientRewriteTable.addAliasDomainMapping(aliasDomain, deliveryDomain);
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/bdedd0bf/server/data/data-api/src/main/java/org/apache/james/probe/DataProbe.java
----------------------------------------------------------------------
diff --git a/server/data/data-api/src/main/java/org/apache/james/probe/DataProbe.java b/server/data/data-api/src/main/java/org/apache/james/probe/DataProbe.java
index 6f45e61..31488d7 100644
--- a/server/data/data-api/src/main/java/org/apache/james/probe/DataProbe.java
+++ b/server/data/data-api/src/main/java/org/apache/james/probe/DataProbe.java
@@ -56,4 +56,6 @@ public interface DataProbe {
 
     void removeRegexMapping(String user, String domain, String regex) throws Exception;
 
+    void addDomainAliasMapping(String aliasDomain, String deliveryDomain) throws Exception;
+
 }
\ 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


[16/24] james-project git commit: Silent warnings

Posted by ad...@apache.org.
Silent warnings


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

Branch: refs/heads/master
Commit: e6f7567be4e2c5cd9be335ad5367eee7076dfd83
Parents: 14a8a4f
Author: Raphael Ouazana <ra...@linagora.com>
Authored: Wed Sep 6 11:37:47 2017 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:21:48 2017 +0200

----------------------------------------------------------------------
 .../apache/james/backends/cassandra/DockerCassandraRule.java   | 1 +
 .../james/mailbox/store/mail/model/ListMessageAssert.java      | 6 ++++--
 .../java/org/apache/james/transport/mailets/SMIMEDecrypt.java  | 3 ++-
 .../james/mpt/smtp/host/CassandraJamesSmtpHostSystem.java      | 1 -
 pom.xml                                                        | 1 -
 .../imap/decode/parser/SetAnnotationCommandParserTest.java     | 2 --
 .../java/org/apache/james/managesieve/core/CoreProcessor.java  | 4 ++--
 .../java/org/apache/james/transport/mailets/DSNBounceTest.java | 1 -
 .../java/org/apache/james/transport/mailets/ResendTest.java    | 1 -
 .../src/main/java/org/apache/james/jmap/model/Attachment.java  | 2 --
 10 files changed, 9 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/e6f7567b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java
----------------------------------------------------------------------
diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java
index 2579a14..303eb54 100644
--- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java
+++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java
@@ -54,6 +54,7 @@ public class DockerCassandraRule implements TestRule {
     private final CreateVolumeCmd createTmpsFsCmd;
     private final RemoveVolumeCmd deleteTmpsFsCmd;
 
+    @SuppressWarnings("resource")
     public DockerCassandraRule() {
         String tmpFsName = "cassandraData" + RandomStringUtils.randomAlphabetic(10);
         client = DockerClientFactory.instance().client();

http://git-wip-us.apache.org/repos/asf/james-project/blob/e6f7567b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/ListMessageAssert.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/ListMessageAssert.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/ListMessageAssert.java
index 1933858..1d1409d 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/ListMessageAssert.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/ListMessageAssert.java
@@ -20,14 +20,16 @@
 package org.apache.james.mailbox.store.mail.model;
 
 import static org.assertj.core.api.Assertions.assertThat;
+
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.Date;
 import java.util.List;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.commons.io.IOUtils;
 
 import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Objects;
@@ -46,7 +48,7 @@ public class ListMessageAssert {
     private InnerMessage getInnerMessage(MailboxMessage message) {
         try {
             return new InnerMessage(message.getMessageId(), message.getUid(), message.getMailboxId(), message.getInternalDate(), message.getBodyOctets(),
-                    message.getFullContentOctets(), message.getMediaType(), message.getSubType(), IOUtils.toString(message.getFullContent()));
+                    message.getFullContentOctets(), message.getMediaType(), message.getSubType(), IOUtils.toString(message.getFullContent(), StandardCharsets.UTF_8));
         } catch (IOException e) {
             Throwables.propagate(e);
             return null;

http://git-wip-us.apache.org/repos/asf/james-project/blob/e6f7567b/mailet/crypto/src/main/java/org/apache/james/transport/mailets/SMIMEDecrypt.java
----------------------------------------------------------------------
diff --git a/mailet/crypto/src/main/java/org/apache/james/transport/mailets/SMIMEDecrypt.java b/mailet/crypto/src/main/java/org/apache/james/transport/mailets/SMIMEDecrypt.java
index cfa1062..d7e519c 100644
--- a/mailet/crypto/src/main/java/org/apache/james/transport/mailets/SMIMEDecrypt.java
+++ b/mailet/crypto/src/main/java/org/apache/james/transport/mailets/SMIMEDecrypt.java
@@ -22,6 +22,7 @@
 package org.apache.james.transport.mailets;
 
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.security.GeneralSecurityException;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509Certificate;
@@ -178,6 +179,6 @@ public class SMIMEDecrypt extends GenericMailet {
     }
 
     private String text(Part mimePart) throws IOException, MessagingException {
-        return IOUtils.toString(mimePart.getDataHandler().getInputStream());
+        return IOUtils.toString(mimePart.getDataHandler().getInputStream(), StandardCharsets.UTF_8);
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/e6f7567b/mpt/impl/smtp/cassandra/src/test/java/org/apache/james/mpt/smtp/host/CassandraJamesSmtpHostSystem.java
----------------------------------------------------------------------
diff --git a/mpt/impl/smtp/cassandra/src/test/java/org/apache/james/mpt/smtp/host/CassandraJamesSmtpHostSystem.java b/mpt/impl/smtp/cassandra/src/test/java/org/apache/james/mpt/smtp/host/CassandraJamesSmtpHostSystem.java
index 4909779..97a5f55 100644
--- a/mpt/impl/smtp/cassandra/src/test/java/org/apache/james/mpt/smtp/host/CassandraJamesSmtpHostSystem.java
+++ b/mpt/impl/smtp/cassandra/src/test/java/org/apache/james/mpt/smtp/host/CassandraJamesSmtpHostSystem.java
@@ -29,7 +29,6 @@ import org.apache.james.dnsservice.api.InMemoryDNSService;
 import org.apache.james.mailbox.elasticsearch.MailboxElasticsearchConstants;
 import org.apache.james.modules.CassandraJmapServerModule;
 import org.apache.james.modules.protocols.ProtocolHandlerModule;
-import org.apache.james.modules.protocols.SMTPServerModule;
 import org.apache.james.mpt.monitor.SystemLoggingMonitor;
 import org.apache.james.mpt.session.ExternalSessionFactory;
 import org.apache.james.mpt.smtp.SmtpHostSystem;

http://git-wip-us.apache.org/repos/asf/james-project/blob/e6f7567b/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index cc7b4da..b136d64 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2700,7 +2700,6 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-enforcer-plugin</artifactId>
-                <version>1.4.1</version>
                 <executions>
                     <execution>
                         <id>enforce-maven</id>

http://git-wip-us.apache.org/repos/asf/james-project/blob/e6f7567b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SetAnnotationCommandParserTest.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SetAnnotationCommandParserTest.java b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SetAnnotationCommandParserTest.java
index 3b46532..67d91e9 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SetAnnotationCommandParserTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SetAnnotationCommandParserTest.java
@@ -20,8 +20,6 @@
 package org.apache.james.imap.decode.parser;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.guava.api.Assertions.assertThat;
-
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;

http://git-wip-us.apache.org/repos/asf/james-project/blob/e6f7567b/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/CoreProcessor.java
----------------------------------------------------------------------
diff --git a/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/CoreProcessor.java b/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/CoreProcessor.java
index 9c06e4d..302efe8 100644
--- a/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/CoreProcessor.java
+++ b/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/CoreProcessor.java
@@ -21,6 +21,7 @@
 package org.apache.james.managesieve.core;
 
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
@@ -133,11 +134,10 @@ public class CoreProcessor implements CoreCommands {
     }
 
     @Override
-
     public String getScript(final Session session, final String name) {
         return handleCommandExecution(() -> {
             authenticationCheck(session);
-            String scriptContent = IOUtils.toString(sieveRepository.getScript(session.getUser(), name));
+            String scriptContent = IOUtils.toString(sieveRepository.getScript(session.getUser(), name), StandardCharsets.UTF_8);
             return "{" + scriptContent.length() + "}" + "\r\n" + scriptContent + "\r\nOK";
         }, session);
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/e6f7567b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/DSNBounceTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/DSNBounceTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/DSNBounceTest.java
index 280b3e6..b46f490 100644
--- a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/DSNBounceTest.java
+++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/DSNBounceTest.java
@@ -21,7 +21,6 @@
 package org.apache.james.transport.mailets;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.guava.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/e6f7567b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ResendTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ResendTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ResendTest.java
index aae7a06..103e546 100644
--- a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ResendTest.java
+++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ResendTest.java
@@ -20,7 +20,6 @@
 package org.apache.james.transport.mailets;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.guava.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/e6f7567b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/Attachment.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/Attachment.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/Attachment.java
index 304acbe..49081a4 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/Attachment.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/Attachment.java
@@ -21,8 +21,6 @@ package org.apache.james.jmap.model;
 
 import java.util.Optional;
 
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
 import com.google.common.annotations.VisibleForTesting;


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


[04/24] james-project git commit: MAILBOX-304 Configure read timeout for attachment v2 migration

Posted by ad...@apache.org.
MAILBOX-304 Configure read timeout for attachment v2 migration


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

Branch: refs/heads/master
Commit: b3c308e9c0a0a18a69c37889701230b10c379834
Parents: 2001443
Author: benwa <bt...@linagora.com>
Authored: Sat Sep 9 15:50:56 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:17:37 2017 +0200

----------------------------------------------------------------------
 .../cassandra/init/CassandraConfiguration.java  | 36 ++++++++++++++++----
 .../init/CassandraConfigurationTest.java        | 24 +++++++++++--
 .../cassandra/mail/CassandraAttachmentDAO.java  | 10 +++---
 ...estCassandraMailboxSessionMapperFactory.java |  2 +-
 .../mail/CassandraAttachmentDAOTest.java        |  5 ++-
 .../mail/CassandraAttachmentFallbackTest.java   |  5 ++-
 .../migration/AttachmentV2MigrationTest.java    |  5 ++-
 .../modules/mailbox/CassandraSessionModule.java |  3 ++
 .../mailbox/CassandraSessionModuleTest.java     |  1 +
 .../modules/mailbox/cassandra.properties        |  1 +
 src/site/xdoc/server/config-cassandra.xml       | 15 ++++++++
 11 files changed, 90 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/b3c308e9/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraConfiguration.java
----------------------------------------------------------------------
diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraConfiguration.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraConfiguration.java
index 17945e8..2121cff 100644
--- a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraConfiguration.java
+++ b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraConfiguration.java
@@ -19,16 +19,17 @@
 
 package org.apache.james.backends.cassandra.init;
 
+import static java.lang.Math.toIntExact;
+
 import java.util.Objects;
 import java.util.Optional;
+import java.util.concurrent.TimeUnit;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
 
 public class CassandraConfiguration {
-    public static final CassandraConfiguration DEFAULT_CONFIGURATION = builder().build();
-
     public static final int DEFAULT_MESSAGE_CHUNK_SIZE_ON_READ = 100;
     public static final int DEFAULT_EXPUNGE_BATCH_SIZE = 100;
     public static final int DEFAULT_UPDATE_FLAGS_BATCH_SIZE = 20;
@@ -39,6 +40,8 @@ public class CassandraConfiguration {
     public static final int DEFAULT_ACL_MAX_RETRY = 1000;
     public static final int DEFAULT_FETCH_NEXT_PAGE_ADVANCE_IN_ROW = 100;
     public static final int DEFAULT_BLOB_PART_SIZE = 100 * 1024;
+    public static final int DEFAULT_ATTACHMENT_V2_MIGRATION_READ_TIMEOUT = toIntExact(TimeUnit.DAYS.toMillis(1));
+    public static final CassandraConfiguration DEFAULT_CONFIGURATION = builder().build();
 
     public static class Builder {
         private Optional<Integer> messageReadChunkSize = Optional.empty();
@@ -51,6 +54,7 @@ public class CassandraConfiguration {
         private Optional<Integer> aclMaxRetry = Optional.empty();
         private Optional<Integer> fetchNextPageInAdvanceRow = Optional.empty();
         private Optional<Integer> blobPartSize = Optional.empty();
+        private Optional<Integer> attachmentV2MigrationReadTimeout = Optional.empty();
 
         public Builder messageReadChunkSize(int value) {
             Preconditions.checkArgument(value > 0, "messageReadChunkSize needs to be strictly positive");
@@ -112,6 +116,12 @@ public class CassandraConfiguration {
             return this;
         }
 
+        public Builder attachmentV2MigrationReadTimeout(int value) {
+            Preconditions.checkArgument(value > 0, "attachmentV2MigrationReadTimeout needs to be strictly positive");
+            this.attachmentV2MigrationReadTimeout = Optional.of(value);
+            return this;
+        }
+
         public Builder messageReadChunkSize(Optional<Integer> value) {
             value.ifPresent(this::messageReadChunkSize);
             return this;
@@ -162,6 +172,11 @@ public class CassandraConfiguration {
             return this;
         }
 
+        public Builder attachmentV2MigrationReadTimeout(Optional<Integer> value) {
+            value.ifPresent(this::attachmentV2MigrationReadTimeout);
+            return this;
+        }
+
         public CassandraConfiguration build() {
             return new CassandraConfiguration(aclMaxRetry.orElse(DEFAULT_ACL_MAX_RETRY),
                 messageReadChunkSize.orElse(DEFAULT_MESSAGE_CHUNK_SIZE_ON_READ),
@@ -172,7 +187,8 @@ public class CassandraConfiguration {
                 modSeqMaxRetry.orElse(DEFAULT_MODSEQ_MAX_RETRY),
                 uidMaxRetry.orElse(DEFAULT_UID_MAX_RETRY),
                 fetchNextPageInAdvanceRow.orElse(DEFAULT_FETCH_NEXT_PAGE_ADVANCE_IN_ROW),
-                blobPartSize.orElse(DEFAULT_BLOB_PART_SIZE));
+                blobPartSize.orElse(DEFAULT_BLOB_PART_SIZE),
+                attachmentV2MigrationReadTimeout.orElse(DEFAULT_ATTACHMENT_V2_MIGRATION_READ_TIMEOUT));
         }
     }
 
@@ -190,12 +206,13 @@ public class CassandraConfiguration {
     private final int aclMaxRetry;
     private final int fetchNextPageInAdvanceRow;
     private final int blobPartSize;
+    private final int attachmentV2MigrationReadTimeout;
 
     @VisibleForTesting
     CassandraConfiguration(int aclMaxRetry, int messageReadChunkSize, int expungeChunkSize,
                            int flagsUpdateChunkSize, int flagsUpdateMessageIdMaxRetry, int flagsUpdateMessageMaxRetry,
                            int modSeqMaxRetry, int uidMaxRetry, int fetchNextPageInAdvanceRow,
-                           int blobPartSize) {
+                           int blobPartSize, final int attachmentV2MigrationReadTimeout) {
         this.aclMaxRetry = aclMaxRetry;
         this.messageReadChunkSize = messageReadChunkSize;
         this.expungeChunkSize = expungeChunkSize;
@@ -206,6 +223,7 @@ public class CassandraConfiguration {
         this.fetchNextPageInAdvanceRow = fetchNextPageInAdvanceRow;
         this.flagsUpdateChunkSize = flagsUpdateChunkSize;
         this.blobPartSize = blobPartSize;
+        this.attachmentV2MigrationReadTimeout = attachmentV2MigrationReadTimeout;
     }
 
     public int getBlobPartSize() {
@@ -248,6 +266,10 @@ public class CassandraConfiguration {
         return fetchNextPageInAdvanceRow;
     }
 
+    public int getAttachmentV2MigrationReadTimeout() {
+        return attachmentV2MigrationReadTimeout;
+    }
+
     @Override
     public final boolean equals(Object o) {
         if (o instanceof CassandraConfiguration) {
@@ -262,7 +284,8 @@ public class CassandraConfiguration {
                 && Objects.equals(this.uidMaxRetry, that.uidMaxRetry)
                 && Objects.equals(this.flagsUpdateChunkSize, that.flagsUpdateChunkSize)
                 && Objects.equals(this.fetchNextPageInAdvanceRow, that.fetchNextPageInAdvanceRow)
-                && Objects.equals(this.blobPartSize, that.blobPartSize);
+                && Objects.equals(this.blobPartSize, that.blobPartSize)
+                && Objects.equals(this.attachmentV2MigrationReadTimeout, that.attachmentV2MigrationReadTimeout);
         }
         return false;
     }
@@ -271,7 +294,7 @@ public class CassandraConfiguration {
     public final int hashCode() {
         return Objects.hash(aclMaxRetry, messageReadChunkSize, expungeChunkSize, flagsUpdateMessageIdMaxRetry,
             flagsUpdateMessageMaxRetry, modSeqMaxRetry, uidMaxRetry, fetchNextPageInAdvanceRow, flagsUpdateChunkSize,
-            blobPartSize);
+            blobPartSize, attachmentV2MigrationReadTimeout);
     }
 
     @Override
@@ -287,6 +310,7 @@ public class CassandraConfiguration {
             .add("flagsUpdateChunkSize", flagsUpdateChunkSize)
             .add("uidMaxRetry", uidMaxRetry)
             .add("blobPartSize", blobPartSize)
+            .add("attachmentV2MigrationReadTimeout", attachmentV2MigrationReadTimeout)
             .toString();
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/b3c308e9/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraConfigurationTest.java
----------------------------------------------------------------------
diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraConfigurationTest.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraConfigurationTest.java
index 473a56e..efde00e 100644
--- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraConfigurationTest.java
+++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraConfigurationTest.java
@@ -21,7 +21,6 @@ package org.apache.james.backends.cassandra.init;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import org.apache.james.backends.cassandra.init.CassandraConfiguration;
 import org.assertj.core.api.JUnitSoftAssertions;
 import org.junit.Rule;
 import org.junit.Test;
@@ -39,7 +38,9 @@ public class CassandraConfigurationTest {
 
     @Test
     public void cassandraConfigurationShouldRespectBeanContract() {
-        EqualsVerifier.forClass(CassandraConfiguration.class).verify();
+        EqualsVerifier.forClass(CassandraConfiguration.class)
+            .allFieldsShouldBeUsed()
+            .verify();
     }
 
     @Test
@@ -193,6 +194,22 @@ public class CassandraConfigurationTest {
     }
 
     @Test
+    public void attachmentV2MigrationReadTimeoutShouldThrowOnZero() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        CassandraConfiguration.builder()
+            .attachmentV2MigrationReadTimeout(0);
+    }
+
+    @Test
+    public void attachmentV2MigrationReadTimeoutShouldThrowOnNegativeValue() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        CassandraConfiguration.builder()
+            .attachmentV2MigrationReadTimeout(-1);
+    }
+
+    @Test
     public void builderShouldCreateTheRightObject() {
         int aclMaxRetry = 1;
         int modSeqMaxRetry = 2;
@@ -204,6 +221,7 @@ public class CassandraConfigurationTest {
         int messageReadChunkSize = 8;
         int expungeChunkSize = 9;
         int blobPartSize = 10;
+        int attachmentV2MigrationReadTimeout = 11;
 
         CassandraConfiguration configuration = CassandraConfiguration.builder()
             .aclMaxRetry(aclMaxRetry)
@@ -216,6 +234,7 @@ public class CassandraConfigurationTest {
             .messageReadChunkSize(messageReadChunkSize)
             .expungeChunkSize(expungeChunkSize)
             .blobPartSize(blobPartSize)
+            .attachmentV2MigrationReadTimeout(attachmentV2MigrationReadTimeout)
             .build();
 
         softly.assertThat(configuration.getAclMaxRetry()).isEqualTo(aclMaxRetry);
@@ -228,6 +247,7 @@ public class CassandraConfigurationTest {
         softly.assertThat(configuration.getMessageReadChunkSize()).isEqualTo(messageReadChunkSize);
         softly.assertThat(configuration.getExpungeChunkSize()).isEqualTo(expungeChunkSize);
         softly.assertThat(configuration.getBlobPartSize()).isEqualTo(blobPartSize);
+        softly.assertThat(configuration.getAttachmentV2MigrationReadTimeout()).isEqualTo(attachmentV2MigrationReadTimeout);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/b3c308e9/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAO.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAO.java
index 532dea3..e3d05a5 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAO.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAO.java
@@ -24,7 +24,6 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.delete;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
-import static java.lang.Math.toIntExact;
 import static org.apache.james.mailbox.cassandra.table.CassandraAttachmentTable.FIELDS;
 import static org.apache.james.mailbox.cassandra.table.CassandraAttachmentTable.ID;
 import static org.apache.james.mailbox.cassandra.table.CassandraAttachmentTable.PAYLOAD;
@@ -36,11 +35,11 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
 import java.util.stream.Stream;
 
 import javax.inject.Inject;
 
+import org.apache.james.backends.cassandra.init.CassandraConfiguration;
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
 import org.apache.james.backends.cassandra.utils.CassandraUtils;
 import org.apache.james.mailbox.model.Attachment;
@@ -53,16 +52,16 @@ import com.google.common.base.Preconditions;
 
 public class CassandraAttachmentDAO {
 
-    public static final int SELECT_ALL_TIMEOUT = toIntExact(TimeUnit.DAYS.toMillis(1));
     private final CassandraAsyncExecutor cassandraAsyncExecutor;
     private final CassandraUtils cassandraUtils;
+    private CassandraConfiguration configuration;
     private final PreparedStatement insertStatement;
     private final PreparedStatement deleteStatement;
     private final PreparedStatement selectStatement;
     private final PreparedStatement selectAllStatement;
 
     @Inject
-    public CassandraAttachmentDAO(Session session, CassandraUtils cassandraUtils) {
+    public CassandraAttachmentDAO(Session session, CassandraUtils cassandraUtils, CassandraConfiguration configuration) {
         this.cassandraAsyncExecutor = new CassandraAsyncExecutor(session);
 
         this.selectStatement = prepareSelect(session);
@@ -70,6 +69,7 @@ public class CassandraAttachmentDAO {
         this.deleteStatement = prepareDelete(session);
         this.insertStatement = prepareInsert(session);
         this.cassandraUtils = cassandraUtils;
+        this.configuration = configuration;
     }
 
     private PreparedStatement prepareDelete(Session session) {
@@ -111,7 +111,7 @@ public class CassandraAttachmentDAO {
         return cassandraUtils.convertToStream(
             cassandraAsyncExecutor.execute(
                 selectAllStatement.bind()
-                    .setReadTimeoutMillis(SELECT_ALL_TIMEOUT)
+                    .setReadTimeoutMillis(configuration.getAttachmentV2MigrationReadTimeout())
                     .setFetchSize(1))
                 .join())
             .map(this::attachment);

http://git-wip-us.apache.org/repos/asf/james-project/blob/b3c308e9/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
index c276ce2..312accd 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
@@ -58,7 +58,7 @@ public class TestCassandraMailboxSessionMapperFactory {
             new CassandraMailboxPathDAO(session, typesProvider),
             new CassandraFirstUnseenDAO(session),
             new CassandraApplicableFlagDAO(session),
-            new CassandraAttachmentDAO(session, CassandraUtils.WITH_DEFAULT_CONFIGURATION),
+            new CassandraAttachmentDAO(session, CassandraUtils.WITH_DEFAULT_CONFIGURATION, CassandraConfiguration.DEFAULT_CONFIGURATION),
             new CassandraAttachmentDAOV2(session),
             new CassandraDeletedMessageDAO(session),
             cassandraBlobsDAO, CassandraUtils.WITH_DEFAULT_CONFIGURATION,

http://git-wip-us.apache.org/repos/asf/james-project/blob/b3c308e9/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOTest.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOTest.java
index 3b00a1a..4f53c2f 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOTest.java
@@ -26,6 +26,7 @@ import java.util.Optional;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.DockerCassandraRule;
+import org.apache.james.backends.cassandra.init.CassandraConfiguration;
 import org.apache.james.backends.cassandra.utils.CassandraUtils;
 import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
 import org.apache.james.mailbox.model.Attachment;
@@ -52,7 +53,9 @@ public class CassandraAttachmentDAOTest {
     public void setUp() throws Exception {
         cassandra = CassandraCluster.create(new CassandraAttachmentModule(),
             cassandraServer.getIp(), cassandraServer.getBindingPort());
-        testee = new CassandraAttachmentDAO(cassandra.getConf(), CassandraUtils.WITH_DEFAULT_CONFIGURATION);
+        testee = new CassandraAttachmentDAO(cassandra.getConf(),
+            CassandraUtils.WITH_DEFAULT_CONFIGURATION,
+            CassandraConfiguration.DEFAULT_CONFIGURATION);
     }
 
     @After

http://git-wip-us.apache.org/repos/asf/james-project/blob/b3c308e9/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java
index 90ad116..7408840 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java
@@ -26,6 +26,7 @@ import java.nio.charset.StandardCharsets;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.DockerCassandraRule;
+import org.apache.james.backends.cassandra.init.CassandraConfiguration;
 import org.apache.james.backends.cassandra.init.CassandraModuleComposite;
 import org.apache.james.backends.cassandra.utils.CassandraUtils;
 import org.apache.james.mailbox.cassandra.ids.BlobId;
@@ -66,7 +67,9 @@ public class CassandraAttachmentFallbackTest {
             cassandraServer.getBindingPort());
 
         attachmentDAOV2 = new CassandraAttachmentDAOV2(cassandra.getConf());
-        attachmentDAO = new CassandraAttachmentDAO(cassandra.getConf(), CassandraUtils.WITH_DEFAULT_CONFIGURATION);
+        attachmentDAO = new CassandraAttachmentDAO(cassandra.getConf(),
+            CassandraUtils.WITH_DEFAULT_CONFIGURATION,
+            CassandraConfiguration.DEFAULT_CONFIGURATION);
         blobsDAO = new CassandraBlobsDAO(cassandra.getConf());
         attachmentMapper = new CassandraAttachmentMapper(attachmentDAO, attachmentDAOV2, blobsDAO);
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/b3c308e9/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2MigrationTest.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2MigrationTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2MigrationTest.java
index 7bbbb39..1b92747 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2MigrationTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2MigrationTest.java
@@ -30,6 +30,7 @@ import java.util.stream.Stream;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.DockerCassandraRule;
+import org.apache.james.backends.cassandra.init.CassandraConfiguration;
 import org.apache.james.backends.cassandra.init.CassandraModuleComposite;
 import org.apache.james.backends.cassandra.utils.CassandraUtils;
 import org.apache.james.mailbox.cassandra.ids.BlobId;
@@ -67,7 +68,9 @@ public class AttachmentV2MigrationTest {
             cassandraServer.getIp(),
             cassandraServer.getBindingPort());
 
-        attachmentDAO = new CassandraAttachmentDAO(cassandra.getConf(), CassandraUtils.WITH_DEFAULT_CONFIGURATION);
+        attachmentDAO = new CassandraAttachmentDAO(cassandra.getConf(),
+            CassandraUtils.WITH_DEFAULT_CONFIGURATION,
+            CassandraConfiguration.DEFAULT_CONFIGURATION);
         attachmentDAOV2 = new CassandraAttachmentDAOV2(cassandra.getConf());
         blobsDAO = new CassandraBlobsDAO(cassandra.getConf());
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/b3c308e9/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
index 885e39a..fb08814 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
@@ -72,6 +72,7 @@ public class CassandraSessionModule extends AbstractModule {
     private static final String CHUNK_SIZE_MESSAGE_READ = "chunk.size.message.read";
     private static final String CHUNK_SIZE_EXPUNGE = "chunk.size.expunge";
     private static final String BLOB_PART_SIZE = "mailbox.blob.part.size";
+    private static final String ATTACHMENT_V2_MIGRATION_READ_TIMEOUT = "attachment.v2.migration.read.timeout";
     private static final String CASSANDRA_NODES = "cassandra.nodes";
 
     @Override
@@ -157,6 +158,8 @@ public class CassandraSessionModule extends AbstractModule {
                 propertiesConfiguration.getInteger(CHUNK_SIZE_EXPUNGE, null)))
             .blobPartSize(Optional.ofNullable(
                 propertiesConfiguration.getInteger(BLOB_PART_SIZE, null)))
+            .attachmentV2MigrationReadTimeout(Optional.ofNullable(
+                propertiesConfiguration.getInteger(ATTACHMENT_V2_MIGRATION_READ_TIMEOUT, null)))
             .build();
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/b3c308e9/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/mailbox/CassandraSessionModuleTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/mailbox/CassandraSessionModuleTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/mailbox/CassandraSessionModuleTest.java
index 29c3853..da0358e 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/mailbox/CassandraSessionModuleTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/mailbox/CassandraSessionModuleTest.java
@@ -60,6 +60,7 @@ public class CassandraSessionModuleTest {
                 .messageReadChunkSize(8)
                 .expungeChunkSize(9)
                 .blobPartSize(10)
+                .attachmentV2MigrationReadTimeout(11)
                 .build());
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/b3c308e9/server/container/guice/cassandra-guice/src/test/resources/modules/mailbox/cassandra.properties
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/resources/modules/mailbox/cassandra.properties b/server/container/guice/cassandra-guice/src/test/resources/modules/mailbox/cassandra.properties
index 8d6c9fe..d41cb75 100644
--- a/server/container/guice/cassandra-guice/src/test/resources/modules/mailbox/cassandra.properties
+++ b/server/container/guice/cassandra-guice/src/test/resources/modules/mailbox/cassandra.properties
@@ -8,3 +8,4 @@ chunk.size.flags.update=7
 chunk.size.message.read=8
 chunk.size.expunge=9
 mailbox.blob.part.size=10
+attachment.v2.migration.read.timeout=11

http://git-wip-us.apache.org/repos/asf/james-project/blob/b3c308e9/src/site/xdoc/server/config-cassandra.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/server/config-cassandra.xml b/src/site/xdoc/server/config-cassandra.xml
index b8dc965..c2980c9 100644
--- a/src/site/xdoc/server/config-cassandra.xml
+++ b/src/site/xdoc/server/config-cassandra.xml
@@ -171,6 +171,21 @@
 
     </subsection>
 
+    <subsection name="From V3 to V4">
+
+      <p>Migration tag on git repository: <a href="https://github.com/apache/james-project/releases/tag/cassandra_migration_v3_to_v4">cassandra_migration_v3_to_v4</a></p>
+
+      <p>Goal is to store attachments in the blob tables.</p>
+
+      <p>Summary of available options for this migration:</p>
+
+      <dl>
+        <dt><strong>attachment.v2.migration.read.timeout</strong></dt>
+        <dd>Optional. Defaults to one day.<br/> Controls how many milliseconds before the read on attachment v1 time out.</dd>
+      </dl>
+      
+    </subsection>
+
   </section>
 
 </body>


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


[10/24] james-project git commit: JAMES-2143 Add an integration test getting a message then getting it has a eml file

Posted by ad...@apache.org.
JAMES-2143 Add an integration test getting a message then getting it has a eml file


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

Branch: refs/heads/master
Commit: acaf6c2d26b9ae76ee415243de992e060f2e53b4
Parents: 0024a0c
Author: Antoine Duprat <ad...@linagora.com>
Authored: Tue Sep 12 12:15:48 2017 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:19:54 2017 +0200

----------------------------------------------------------------------
 .../integration/cucumber/DownloadStepdefs.java    | 18 +++++++++++++++---
 .../cucumber/GetMessagesMethodStepdefs.java       |  4 ++++
 .../test/resources/cucumber/DownloadGet.feature   |  9 ++++++++-
 3 files changed, 27 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/acaf6c2d/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
index e34c45c..f3a0c4c 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
@@ -35,6 +35,7 @@ import javax.mail.Flags;
 import org.apache.commons.io.IOUtils;
 import org.apache.http.Header;
 import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.fluent.Request;
 import org.apache.http.client.fluent.Response;
 import org.apache.http.client.utils.URIBuilder;
@@ -73,6 +74,7 @@ public class DownloadStepdefs {
 
     private final UserStepdefs userStepdefs;
     private final MainStepdefs mainStepdefs;
+    private final GetMessagesMethodStepdefs getMessagesMethodStepdefs;
     private HttpResponse response;
     private Multimap<String, String> attachmentsByMessageId;
     private Map<String, String> blobIdByAttachmentId;
@@ -80,9 +82,10 @@ public class DownloadStepdefs {
     private Map<AttachmentAccessTokenKey, AttachmentAccessToken> attachmentAccessTokens;
 
     @Inject
-    private DownloadStepdefs(MainStepdefs mainStepdefs, UserStepdefs userStepdefs) {
+    private DownloadStepdefs(MainStepdefs mainStepdefs, UserStepdefs userStepdefs, GetMessagesMethodStepdefs getMessagesMethodStepdefs) {
         this.mainStepdefs = mainStepdefs;
         this.userStepdefs = userStepdefs;
+        this.getMessagesMethodStepdefs = getMessagesMethodStepdefs;
         this.attachmentsByMessageId = ArrayListMultimap.create();
         this.blobIdByAttachmentId = new HashMap<>();
         this.attachmentAccessTokens = new HashMap<>();
@@ -150,8 +153,17 @@ public class DownloadStepdefs {
                 .map(MessageId::serialize)
                 .orElse(null));
 
-        URIBuilder uriBuilder = mainStepdefs.baseUri().setPath("/download/" + attachmentIdOrMessageId);
-        response = authenticatedDownloadRequest(uriBuilder, attachmentIdOrMessageId, username).execute().returnResponse();
+        downLoad(username, attachmentIdOrMessageId);
+    }
+
+    @When("^\"([^\"]*)\" downloads the message by its blobId$")
+    public void downloads(String username) throws Throwable {
+        downLoad(username, getMessagesMethodStepdefs.getBlobId());
+    }
+
+    private void downLoad(String username, String blobId) throws IOException, ClientProtocolException, URISyntaxException {
+        URIBuilder uriBuilder = mainStepdefs.baseUri().setPath("/download/" + blobId);
+        response = authenticatedDownloadRequest(uriBuilder, blobId, username).execute().returnResponse();
     }
 
     private Request authenticatedDownloadRequest(URIBuilder uriBuilder, String blobId, String username) throws URISyntaxException {

http://git-wip-us.apache.org/repos/asf/james-project/blob/acaf6c2d/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java
index f42a071..f7adb27 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java
@@ -533,4 +533,8 @@ public class GetMessagesMethodStepdefs {
         attachmentProperties.asList(TableRow.class)
             .forEach(entry -> assertThat(jsonPath.<Object>read(attachment + "." + entry.getKey())).isEqualTo(entry.getValue()));
     }
+
+    public String getBlobId() {
+        return jsonPath.<String>read(FIRST_MESSAGE + ".blobId");
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/acaf6c2d/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
index 3021f03..b450533 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
@@ -34,4 +34,11 @@ Feature: Download GET
     Given "username@domain.tld" mailbox "INBOX" contains a message "1"
     When "username@domain.tld" downloads "1"
     Then the user should receive that blob
-    And the blob size is 4963
\ No newline at end of file
+    And the blob size is 4963
+
+  Scenario: Getting a message then getting its blob
+    Given the user has a message "m1" in "INBOX" mailbox with subject "my test subject", content "testmail"
+    And the user ask for messages "m1"
+    When "username@domain.tld" downloads the message by its blobId
+    Then the user should receive that blob
+    And the blob size is 36
\ 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


[15/24] james-project git commit: JAMES-2142 Add JMAP integration test on GetMessageList filter by attachments

Posted by ad...@apache.org.
JAMES-2142 Add JMAP integration test on GetMessageList filter by attachments


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

Branch: refs/heads/master
Commit: 14a8a4f5ff1dcf3ce05584d7ce8874b14aa7aa1a
Parents: fec80a1
Author: Antoine Duprat <ad...@linagora.com>
Authored: Fri Sep 8 15:15:38 2017 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:21:07 2017 +0200

----------------------------------------------------------------------
 .../inmemory/InMemoryMailboxManager.java        |   7 ++
 mailbox/scanning-search/pom.xml                 |  16 ++-
 pom.xml                                         |  18 ++-
 server/container/guice/cassandra-guice/pom.xml  |   9 ++
 .../org/apache/james/CassandraJmapTestRule.java |   4 +-
 server/container/guice/memory-guice/pom.xml     |   9 ++
 .../org/apache/james/MemoryJmapTestRule.java    |   8 +-
 .../integration/GetMessageListMethodTest.java   | 109 +++++++++++++++++++
 .../src/test/resources/eml/attachment.pdf       | Bin 0 -> 9404 bytes
 9 files changed, 175 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/14a8a4f5/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMailboxManager.java
----------------------------------------------------------------------
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMailboxManager.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMailboxManager.java
index 55584d8..adf3044 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMailboxManager.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMailboxManager.java
@@ -39,6 +39,7 @@ import org.apache.james.mailbox.store.event.DelegatingMailboxListener;
 import org.apache.james.mailbox.store.event.MailboxEventDispatcher;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
 import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
+import org.apache.james.mailbox.store.search.MessageSearchIndex;
 
 public class InMemoryMailboxManager extends StoreMailboxManager {
 
@@ -65,6 +66,12 @@ public class InMemoryMailboxManager extends StoreMailboxManager {
     }
 
     @Override
+    @Inject
+    public void setMessageSearchIndex(MessageSearchIndex index) {
+        super.setMessageSearchIndex(index);
+    }
+
+    @Override
     public EnumSet<MailboxCapabilities> getSupportedMailboxCapabilities() {
         return EnumSet.of(MailboxCapabilities.Move, MailboxCapabilities.UserFlag, MailboxCapabilities.Namespace, MailboxCapabilities.Annotation);
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/14a8a4f5/mailbox/scanning-search/pom.xml
----------------------------------------------------------------------
diff --git a/mailbox/scanning-search/pom.xml b/mailbox/scanning-search/pom.xml
index 1ee91bc..e8d3acc 100644
--- a/mailbox/scanning-search/pom.xml
+++ b/mailbox/scanning-search/pom.xml
@@ -64,7 +64,6 @@
         <dependency>
             <groupId>org.apache.pdfbox</groupId>
             <artifactId>pdfbox</artifactId>
-            <version>2.0.7</version>
             <scope>test</scope>
         </dependency>
         <dependency>
@@ -78,4 +77,19 @@
         </dependency>
     </dependencies>
 
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>

http://git-wip-us.apache.org/repos/asf/james-project/blob/14a8a4f5/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index a5f045b..cc7b4da 100644
--- a/pom.xml
+++ b/pom.xml
@@ -804,6 +804,17 @@
             </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
+                <artifactId>apache-james-mailbox-scanning-search</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>apache-james-mailbox-scanning-search</artifactId>
+                <version>${project.version}</version>
+                <type>test-jar</type>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
                 <artifactId>apache-james-mailbox-spring</artifactId>
                 <version>${project.version}</version>
             </dependency>
@@ -1996,6 +2007,11 @@
                 <version>${maven-reporting-impl.version}</version>
             </dependency>
             <dependency>
+                <groupId>org.apache.pdfbox</groupId>
+                <artifactId>pdfbox</artifactId>
+                <version>2.0.7</version>
+            </dependency>
+            <dependency>
                 <groupId>org.apache.xbean</groupId>
                 <artifactId>xbean-spring</artifactId>
                 <version>${xbean-spring.version}</version>
@@ -2717,7 +2733,7 @@
                         <goals>
                             <goal>test-jar</goal>
                         </goals>
-			<phase>package</phase>
+                        <phase>package</phase>
                     </execution>
                 </executions>
             </plugin>

http://git-wip-us.apache.org/repos/asf/james-project/blob/14a8a4f5/server/container/guice/cassandra-guice/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/pom.xml b/server/container/guice/cassandra-guice/pom.xml
index 53f397c..598a0c4 100644
--- a/server/container/guice/cassandra-guice/pom.xml
+++ b/server/container/guice/cassandra-guice/pom.xml
@@ -73,6 +73,11 @@
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-scanning-search</artifactId>
+            <type>test-jar</type>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>apache-james-mailbox-tika</artifactId>
             <type>test-jar</type>
             <scope>test</scope>
@@ -201,6 +206,10 @@
             <artifactId>asyncretry</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.apache.pdfbox</groupId>
+            <artifactId>pdfbox</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.assertj</groupId>
             <artifactId>assertj-core</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/14a8a4f5/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJmapTestRule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJmapTestRule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJmapTestRule.java
index 5b031a4..5d45c16 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJmapTestRule.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJmapTestRule.java
@@ -19,7 +19,7 @@
 
 package org.apache.james;
 import org.apache.james.mailbox.extractor.TextExtractor;
-import org.apache.james.mailbox.store.extractor.DefaultTextExtractor;
+import org.apache.james.mailbox.store.search.PDFTextExtractor;
 import org.apache.james.modules.TestESMetricReporterModule;
 import org.apache.james.modules.TestJMAPServerModule;
 import org.junit.rules.TestRule;
@@ -49,7 +49,7 @@ public class CassandraJmapTestRule implements TestRule {
     public GuiceJamesServer jmapServer(Module... additionals) {
         return new GuiceJamesServer()
             .combineWith(CassandraJamesServerMain.cassandraServerModule, CassandraJamesServerMain.protocols)
-            .overrideWith(binder -> binder.bind(TextExtractor.class).to(DefaultTextExtractor.class))
+            .overrideWith(binder -> binder.bind(TextExtractor.class).to(PDFTextExtractor.class))
             .overrideWith(new TestJMAPServerModule(LIMIT_TO_3_MESSAGES))
             .overrideWith(new TestESMetricReporterModule())
             .overrideWith(guiceModuleTestRule.getModule())

http://git-wip-us.apache.org/repos/asf/james-project/blob/14a8a4f5/server/container/guice/memory-guice/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/memory-guice/pom.xml b/server/container/guice/memory-guice/pom.xml
index f2df5be..828b740 100644
--- a/server/container/guice/memory-guice/pom.xml
+++ b/server/container/guice/memory-guice/pom.xml
@@ -41,6 +41,11 @@
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-scanning-search</artifactId>
+            <type>test-jar</type>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>apache-mailet-base</artifactId>
             <type>test-jar</type>
             <scope>test</scope>
@@ -110,6 +115,10 @@
             <artifactId>james-server-guice-webadmin-swagger</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.apache.pdfbox</groupId>
+            <artifactId>pdfbox</artifactId>
+        </dependency>
+        <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/14a8a4f5/server/container/guice/memory-guice/src/test/java/org/apache/james/MemoryJmapTestRule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/memory-guice/src/test/java/org/apache/james/MemoryJmapTestRule.java b/server/container/guice/memory-guice/src/test/java/org/apache/james/MemoryJmapTestRule.java
index 91544aa..0aadadb 100644
--- a/server/container/guice/memory-guice/src/test/java/org/apache/james/MemoryJmapTestRule.java
+++ b/server/container/guice/memory-guice/src/test/java/org/apache/james/MemoryJmapTestRule.java
@@ -21,6 +21,10 @@ package org.apache.james;
 
 import org.apache.activemq.store.PersistenceAdapter;
 import org.apache.activemq.store.memory.MemoryPersistenceAdapter;
+import org.apache.james.mailbox.extractor.TextExtractor;
+import org.apache.james.mailbox.store.search.MessageSearchIndex;
+import org.apache.james.mailbox.store.search.PDFTextExtractor;
+import org.apache.james.mailbox.store.search.SimpleMessageSearchIndex;
 import org.apache.james.modules.TestFilesystemModule;
 import org.apache.james.modules.TestJMAPServerModule;
 import org.junit.rules.TemporaryFolder;
@@ -42,7 +46,9 @@ public class MemoryJmapTestRule implements TestRule {
             .overrideWith(modules)
             .overrideWith(new TestFilesystemModule(temporaryFolder),
                 new TestJMAPServerModule(LIMIT_TO_3_MESSAGES))
-            .overrideWith((binder) -> binder.bind(PersistenceAdapter.class).to(MemoryPersistenceAdapter.class));
+            .overrideWith(binder -> binder.bind(PersistenceAdapter.class).to(MemoryPersistenceAdapter.class))
+            .overrideWith(binder -> binder.bind(TextExtractor.class).to(PDFTextExtractor.class))
+            .overrideWith(binder -> binder.bind(MessageSearchIndex.class).to(SimpleMessageSearchIndex.class));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/14a8a4f5/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
index a58eadc..65e734c 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
@@ -31,12 +31,14 @@ import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.not;
 
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.time.LocalDate;
 import java.time.ZoneId;
 import java.util.Date;
 
 import javax.mail.Flags;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.http.client.utils.URIBuilder;
 import org.apache.james.GuiceJamesServer;
 import org.apache.james.jmap.HttpJmapAuthentication;
@@ -48,6 +50,13 @@ import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
 import org.apache.james.mailbox.store.probe.MailboxProbe;
+import org.apache.james.mime4j.dom.Message;
+import org.apache.james.mime4j.dom.MessageWriter;
+import org.apache.james.mime4j.dom.Multipart;
+import org.apache.james.mime4j.message.BodyPart;
+import org.apache.james.mime4j.message.BodyPartBuilder;
+import org.apache.james.mime4j.message.DefaultMessageWriter;
+import org.apache.james.mime4j.message.MultipartBuilder;
 import org.apache.james.modules.MailboxProbeImpl;
 import org.apache.james.probe.DataProbe;
 import org.apache.james.util.date.ImapDateTimeFormatter;
@@ -782,6 +791,106 @@ public abstract class GetMessageListMethodTest {
     }
 
     @Test
+    public void getMessageListShouldFilterMessagesWhenTextFilterDoesntMatches() throws Exception {
+        mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, username, "mailbox");
+        mailboxProbe.appendMessage(username, new MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        await();
+
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body(String.format("[[\"getMessageList\", {\"filter\":{\"text\":\"bad\"}}, \"#0\"]]"))
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(ARGUMENTS + ".messageIds", empty());
+    }
+
+    @Test
+    public void getMessageListShouldNotFilterMessagesWhenTextFilterMatchesBody() throws Exception {
+        mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, username, "mailbox");
+        ComposedMessageId message = mailboxProbe.appendMessage(username, new MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                ClassLoader.getSystemResourceAsStream("eml/twoAttachments.eml"), new Date(), false, new Flags());
+        await();
+
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body(String.format("[[\"getMessageList\", {\"filter\":{\"text\":\"html\"}}, \"#0\"]]"))
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(ARGUMENTS + ".messageIds", contains(message.getMessageId().serialize()));
+    }
+
+    @Test
+    public void getMessageListShouldFilterMessagesWhenAttachmentFilterDoesntMatches() throws Exception {
+        mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, username, "mailbox");
+        byte[] attachmentContent = IOUtils.toByteArray(ClassLoader.getSystemResourceAsStream("eml/attachment.pdf"));
+        BodyPart attachment = BodyPartBuilder.create()
+                .setBody(attachmentContent, "application/pdf")
+                .setContentDisposition("attachment")
+                .build();
+        BodyPart textPart = BodyPartBuilder.create().setBody("The message has a PDF attachment.", "plain", Charsets.UTF_8).build();
+        Multipart multipart = MultipartBuilder.create("mixed")
+                .addBodyPart(attachment)
+                .addBodyPart(textPart)
+                .build();
+        Message message = Message.Builder.of()
+                .setBody(multipart)
+                .build();
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        MessageWriter writer = new DefaultMessageWriter();
+        writer.writeMessage(message, outputStream);
+        mailboxProbe.appendMessage(username, new MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream(outputStream.toByteArray()), new Date(), false, new Flags());
+        await();
+
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body(String.format("[[\"getMessageList\", {\"filter\":{\"attachments\":\"no apple inside\"}}, \"#0\"]]"))
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(ARGUMENTS + ".messageIds", empty());
+    }
+
+    @Test
+    public void getMessageListShouldNotFilterMessagesWhenAttachmentFilterMatches() throws Exception {
+        mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, username, "mailbox");
+        byte[] attachmentContent = IOUtils.toByteArray(ClassLoader.getSystemResourceAsStream("eml/attachment.pdf"));
+        BodyPart attachment = BodyPartBuilder.create()
+                .setBody(attachmentContent, "application/pdf")
+                .setContentDisposition("attachment")
+                .build();
+        BodyPart textPart = BodyPartBuilder.create().setBody("The message has a PDF attachment.", "plain", Charsets.UTF_8).build();
+        Multipart multipart = MultipartBuilder.create("mixed")
+                .addBodyPart(attachment)
+                .addBodyPart(textPart)
+                .build();
+        Message message = Message.Builder.of()
+                .setBody(multipart)
+                .build();
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        MessageWriter writer = new DefaultMessageWriter();
+        writer.writeMessage(message, outputStream);
+        ComposedMessageId composedMessageId = mailboxProbe.appendMessage(username, new MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream(outputStream.toByteArray()), new Date(), false, new Flags());
+        await();
+
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body(String.format("[[\"getMessageList\", {\"filter\":{\"attachments\":\"beautiful banana\"}}, \"#0\"]]"))
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(ARGUMENTS + ".messageIds", contains(composedMessageId.getMessageId().serialize()));
+    }
+
+    @Test
     public void getMessageListShouldSortMessagesWhenSortedByDateDefault() throws Exception {
         mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, username, "mailbox");
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/14a8a4f5/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/attachment.pdf
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/attachment.pdf b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/attachment.pdf
new file mode 100644
index 0000000..6db56a2
Binary files /dev/null and b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/attachment.pdf differ


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


[22/24] james-project git commit: JAMES-2139 More IT function for RRT with domain mapping

Posted by ad...@apache.org.
JAMES-2139 More IT function for RRT with domain mapping


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

Branch: refs/heads/master
Commit: 3b5180de4a7bd3db411f156c92d7d9cfc81d3e5a
Parents: 8706796
Author: quynhn <qn...@linagora.com>
Authored: Mon Sep 11 12:04:40 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:23:34 2017 +0200

----------------------------------------------------------------------
 .../RecipientRewriteTableIntegrationTest.java   | 36 +++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/3b5180de/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RecipientRewriteTableIntegrationTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RecipientRewriteTableIntegrationTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RecipientRewriteTableIntegrationTest.java
index 75ae12d..931fdfe 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RecipientRewriteTableIntegrationTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RecipientRewriteTableIntegrationTest.java
@@ -25,8 +25,8 @@ import org.apache.james.mailets.configuration.MailetContainer;
 import org.apache.james.utils.SMTPMessageSender;
 import org.apache.james.modules.MailboxProbeImpl;
 import org.apache.james.probe.DataProbe;
-import org.apache.james.utils.IMAPMessageReader;
 import org.apache.james.utils.DataProbeImpl;
+import org.apache.james.utils.IMAPMessageReader;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -44,6 +44,7 @@ public class RecipientRewriteTableIntegrationTest {
     private static final String PASSWORD = "secret";
 
     private static final String JAMES_APACHE_ORG = "james.org";
+    private static final String JAMES_ANOTHER_DOMAIN = "james.com";
 
     private static final String FROM = "fromUser@" + JAMES_APACHE_ORG;
     private static final String RECIPIENT = "touser@" + JAMES_APACHE_ORG;
@@ -51,6 +52,8 @@ public class RecipientRewriteTableIntegrationTest {
     private static final String ANY_AT_JAMES = "any@" + JAMES_APACHE_ORG;
     private static final String OTHER_AT_JAMES = "other@" + JAMES_APACHE_ORG;
 
+    private static final String ANY_AT_ANOTHER_DOMAIN = "any@" + JAMES_ANOTHER_DOMAIN;
+
     @Rule
     public TemporaryFolder temporaryFolder = new TemporaryFolder();
 
@@ -80,6 +83,7 @@ public class RecipientRewriteTableIntegrationTest {
         dataProbe = jamesServer.getProbe(DataProbeImpl.class);
 
         dataProbe.addDomain(JAMES_APACHE_ORG);
+        dataProbe.addDomain(JAMES_ANOTHER_DOMAIN);
     }
 
     @After
@@ -149,6 +153,36 @@ public class RecipientRewriteTableIntegrationTest {
         }
     }
 
+    @Test
+    public void messageShouldRedirectToTheSameUserWhenDomainMapping() throws Exception {
+        dataProbe.addDomainAliasMapping(JAMES_APACHE_ORG, JAMES_ANOTHER_DOMAIN);
+
+        createUserInbox(ANY_AT_JAMES);
+        createUserInbox(ANY_AT_ANOTHER_DOMAIN);
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, JAMES_APACHE_ORG);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(FROM, ANY_AT_JAMES);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userReceivedMessage(ANY_AT_ANOTHER_DOMAIN, PASSWORD));
+        }
+    }
+
+    @Test
+    public void messageShouldNotSendToRecipientWhenDomainMapping() throws Exception {
+        dataProbe.addDomainAliasMapping(JAMES_APACHE_ORG, JAMES_ANOTHER_DOMAIN);
+
+        createUserInbox(ANY_AT_JAMES);
+        createUserInbox(ANY_AT_ANOTHER_DOMAIN);
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, JAMES_APACHE_ORG);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(FROM, ANY_AT_JAMES);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userDoesNotReceiveMessage(ANY_AT_JAMES, PASSWORD));
+        }
+    }
+
     private void createUserInbox(String username) throws Exception {
         dataProbe.addUser(username, PASSWORD);
         jamesServer.getProbe(MailboxProbeImpl.class).createMailbox(MailboxConstants.USER_NAMESPACE, username, "INBOX");


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


[11/24] james-project git commit: JAMES-2142 Add attachments in Text search filter

Posted by ad...@apache.org.
JAMES-2142 Add attachments in Text search filter


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

Branch: refs/heads/master
Commit: 33846e69f0d5ab3797ea8c0311ec2a93c3abc572
Parents: acaf6c2
Author: Antoine Duprat <ad...@linagora.com>
Authored: Fri Sep 8 10:43:54 2017 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:20:56 2017 +0200

----------------------------------------------------------------------
 .../java/org/apache/james/jmap/utils/FilterToSearchQuery.java     | 2 ++
 .../java/org/apache/james/jmap/utils/FilterToSearchQueryTest.java | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/33846e69/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java
index f619357..f357628 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java
@@ -21,6 +21,7 @@ package org.apache.james.jmap.utils;
 
 import java.util.Date;
 import java.util.Optional;
+
 import javax.mail.Flags.Flag;
 
 import org.apache.james.jmap.model.Filter;
@@ -58,6 +59,7 @@ public class FilterToSearchQuery {
                         SearchQuery.address(AddressType.Cc, text),
                         SearchQuery.address(AddressType.Bcc, text),
                         SearchQuery.headerContains("Subject", text),
+                        SearchQuery.attachmentContains(text),
                         SearchQuery.bodyContains(text)))
                 ));
         filter.getFrom().ifPresent(from -> searchQuery.andCriteria(SearchQuery.address(AddressType.From, from)));

http://git-wip-us.apache.org/repos/asf/james-project/blob/33846e69/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/FilterToSearchQueryTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/FilterToSearchQueryTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/FilterToSearchQueryTest.java
index 10f7ce0..0662003 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/FilterToSearchQueryTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/FilterToSearchQueryTest.java
@@ -170,7 +170,8 @@ public class FilterToSearchQueryTest {
                 SearchQuery.address(AddressType.Cc, text),
                 SearchQuery.address(AddressType.Bcc, text),
                 SearchQuery.headerContains("Subject", text),
-                SearchQuery.bodyContains(text))));
+                SearchQuery.bodyContains(text),
+                SearchQuery.attachmentContains(text))));
 
         SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
                 .text(text)


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


[13/24] james-project git commit: JAMES-2142 Text content in attachments may be empty

Posted by ad...@apache.org.
JAMES-2142 Text content in attachments may be empty


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

Branch: refs/heads/master
Commit: fec80a1308bbc8328cc5b9a9382fba7c7bf5980b
Parents: a9a40c7
Author: Antoine Duprat <ad...@linagora.com>
Authored: Fri Sep 8 14:12:17 2017 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:21:06 2017 +0200

----------------------------------------------------------------------
 .../james/mailbox/extractor/ParsedContent.java  |  7 +--
 .../mailbox/elasticsearch/json/MimePart.java    |  2 +-
 .../elasticsearch/json/MimePartTest.java        | 50 ++++++++++++++++++++
 .../inmemory/JsoupTextExtractorTest.java        |  4 +-
 .../store/search/PDFTextExtractorTest.java      |  4 +-
 .../mailbox/store/search/MessageSearches.java   | 14 +++---
 .../extractor/DefaultTextExtractorTest.java     |  4 +-
 .../mailbox/tika/TikaTextExtractorTest.java     | 22 ++++-----
 8 files changed, 80 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/fec80a13/mailbox/api/src/main/java/org/apache/james/mailbox/extractor/ParsedContent.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/extractor/ParsedContent.java b/mailbox/api/src/main/java/org/apache/james/mailbox/extractor/ParsedContent.java
index fc5af9f..6dcdc81 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/extractor/ParsedContent.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/extractor/ParsedContent.java
@@ -21,18 +21,19 @@ package org.apache.james.mailbox.extractor;
 
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 
 public class ParsedContent {
 
-    private final String textualContent;
+    private final Optional<String> textualContent;
     private final Map<String, List<String>> metadata;
 
     public ParsedContent(String textualContent, Map<String, List<String>> metadata) {
-        this.textualContent = textualContent;
+        this.textualContent = Optional.ofNullable(textualContent);
         this.metadata = metadata;
     }
 
-    public String getTextualContent() {
+    public Optional<String> getTextualContent() {
         return textualContent;
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/fec80a13/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MimePart.java
----------------------------------------------------------------------
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MimePart.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MimePart.java
index ea15e97..366cdd4 100644
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MimePart.java
+++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MimePart.java
@@ -120,7 +120,7 @@ public class MimePart {
             Optional<ParsedContent> parsedContent = parseContent(textExtractor);
             return new MimePart(
                 headerCollectionBuilder.build(),
-                parsedContent.map(ParsedContent::getTextualContent),
+                parsedContent.flatMap(ParsedContent::getTextualContent),
                 mediaType,
                 subType,
                 fileName,

http://git-wip-us.apache.org/repos/asf/james-project/blob/fec80a13/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MimePartTest.java
----------------------------------------------------------------------
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MimePartTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MimePartTest.java
new file mode 100644
index 0000000..2bca61a
--- /dev/null
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MimePartTest.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.mailbox.elasticsearch.json;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.junit.Test;
+
+public class MimePartTest {
+
+    @Test
+    public void buildShouldWorkWhenTextualContentFromParserIsEmpty() {
+        MimePart.builder()
+            .addBodyContent(new ByteArrayInputStream(new byte[] {}))
+            .addMediaType("text")
+            .addSubType("plain")
+            .build();
+    }
+
+    @Test
+    public void buildShouldWorkWhenTextualContentFromParserIsNonEmpty() {
+        String body = "text";
+        MimePart mimePart = MimePart.builder()
+            .addBodyContent(new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8)))
+            .addMediaType("text")
+            .addSubType("plain")
+            .build();
+        
+        assertThat(mimePart.getTextualBody()).contains(body);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fec80a13/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/JsoupTextExtractorTest.java
----------------------------------------------------------------------
diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/JsoupTextExtractorTest.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/JsoupTextExtractorTest.java
index 3a91e68..20140a7 100644
--- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/JsoupTextExtractorTest.java
+++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/JsoupTextExtractorTest.java
@@ -20,10 +20,10 @@
 package org.apache.james.mailbox.inmemory;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import org.apache.james.mailbox.extractor.TextExtractor;
 
 import java.io.InputStream;
 
+import org.apache.james.mailbox.extractor.TextExtractor;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -39,7 +39,7 @@ public class JsoupTextExtractorTest {
     public void extractedTextFromHtmlShouldNotContainTheContentOfTitleTag() throws Exception {
         InputStream inputStream = ClassLoader.getSystemResourceAsStream("documents/html.txt");
 
-        assertThat(textExtractor.extractContent(inputStream, "text/html").getTextualContent())
+        assertThat(textExtractor.extractContent(inputStream, "text/html").getTextualContent().get())
                 .doesNotContain("*|MC:SUBJECT|*");
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/fec80a13/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractorTest.java
----------------------------------------------------------------------
diff --git a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractorTest.java b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractorTest.java
index df52009..65c28fd 100644
--- a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractorTest.java
+++ b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractorTest.java
@@ -59,12 +59,12 @@ public class PDFTextExtractorTest {
 
         assertThat(testee.extractContent(inputStream, "text/plain")
             .getTextualContent())
-            .isEqualTo(content);
+            .contains(content);
     }
 
     @Test
     public void extractContentShouldExtractPDF() throws Exception {
-        String content = "Little PDF";
+        String content = "Little PDF\n";
         InputStream inputStream = ClassLoader.getSystemResourceAsStream("pdf.pdf");
 
         assertThat(testee.extractContent(inputStream, PDFTextExtractor.PDF_TYPE)

http://git-wip-us.apache.org/repos/asf/james-project/blob/fec80a13/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
index dc35559..cb14f67 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
@@ -74,6 +74,7 @@ import org.apache.james.mime4j.message.HeaderImpl;
 import org.apache.james.mime4j.stream.MimeConfig;
 import org.apache.james.mime4j.util.MimeUtil;
 import org.apache.james.mime4j.utils.search.MessageMatcher;
+import org.apache.james.util.OptionalUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -256,12 +257,13 @@ public class MessageSearches implements Iterable<SimpleMessageSearchIndex.Search
 
     private Stream<String> toAttachmentContent(Attachment attachment) {
         try {
-            return Stream.of(textExtractor
-                .extractContent(
-                    attachment.getStream(),
-                    attachment.getType())
-                .getTextualContent());
-        } catch (Exception e) {
+            return OptionalUtils.toStream(
+                    textExtractor
+                         .extractContent(
+                             attachment.getStream(),
+                             attachment.getType())
+                        .getTextualContent());
+            } catch (Exception e) {
             LOGGER.error("Error while parsing attachment content", e);
             return Stream.of();
         }

http://git-wip-us.apache.org/repos/asf/james-project/blob/fec80a13/mailbox/store/src/test/java/org/apache/james/mailbox/store/extractor/DefaultTextExtractorTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/extractor/DefaultTextExtractorTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/extractor/DefaultTextExtractorTest.java
index 353bf58..a5c5c0c 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/extractor/DefaultTextExtractorTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/extractor/DefaultTextExtractorTest.java
@@ -41,7 +41,7 @@ public class DefaultTextExtractorTest {
         assertThat(inputStream).isNotNull();
         assertThat(textExtractor.extractContent(inputStream, "text/plain")
             .getTextualContent())
-            .isEqualTo("This is some awesome text text.\n\n");
+            .contains("This is some awesome text text.\n\n");
     }
 
     @Test
@@ -52,6 +52,6 @@ public class DefaultTextExtractorTest {
             inputStream,
             "application/vnd.openxmlformats-officedocument.wordprocessingml.document")
             .getTextualContent())
-            .isNull();
+            .isEmpty();
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/fec80a13/mailbox/tika/src/test/java/org/apache/james/mailbox/tika/TikaTextExtractorTest.java
----------------------------------------------------------------------
diff --git a/mailbox/tika/src/test/java/org/apache/james/mailbox/tika/TikaTextExtractorTest.java b/mailbox/tika/src/test/java/org/apache/james/mailbox/tika/TikaTextExtractorTest.java
index a75a5ad..9794ead 100644
--- a/mailbox/tika/src/test/java/org/apache/james/mailbox/tika/TikaTextExtractorTest.java
+++ b/mailbox/tika/src/test/java/org/apache/james/mailbox/tika/TikaTextExtractorTest.java
@@ -64,7 +64,7 @@ public class TikaTextExtractorTest {
     @Test
     public void textualContentShouldReturnNullWhenInputStreamIsEmpty() throws Exception {
         assertThat(textExtractor.extractContent(IOUtils.toInputStream("", Charsets.UTF_8), "text/plain").getTextualContent())
-            .isNull();
+            .isEmpty();
     }
 
     @Test
@@ -72,7 +72,7 @@ public class TikaTextExtractorTest {
         InputStream inputStream = ClassLoader.getSystemResourceAsStream("documents/Text.txt");
         assertThat(inputStream).isNotNull();
         assertThat(textExtractor.extractContent(inputStream, "text/plain").getTextualContent())
-            .isEqualTo("This is some awesome text text.\n\n\n");
+            .contains("This is some awesome text text.\n\n\n");
     }
 
     @Test
@@ -80,7 +80,7 @@ public class TikaTextExtractorTest {
         InputStream inputStream = ClassLoader.getSystemResourceAsStream("documents/writter.docx");
         assertThat(inputStream).isNotNull();
         assertThat(textExtractor.extractContent(inputStream, "application/vnd.openxmlformats-officedocument.wordprocessingml.document").getTextualContent())
-            .isEqualTo("This is an awesome document on libroffice writter !\n");
+            .contains("This is an awesome document on libroffice writter !\n");
     }
 
     @Test
@@ -88,7 +88,7 @@ public class TikaTextExtractorTest {
         InputStream inputStream = ClassLoader.getSystemResourceAsStream("documents/writter.odt");
         assertThat(inputStream).isNotNull();
         assertThat(textExtractor.extractContent(inputStream, "application/vnd.oasis.opendocument.text").getTextualContent())
-            .isEqualTo("This is an awesome document on libroffice writter !\n");
+            .contains("This is an awesome document on libroffice writter !\n");
     }
 
     @Test
@@ -96,7 +96,7 @@ public class TikaTextExtractorTest {
         InputStream inputStream = ClassLoader.getSystemResourceAsStream("documents/fake.txt");
         assertThat(inputStream).isNotNull();
         assertThat(textExtractor.extractContent(inputStream, "application/vnd.oasis.opendocument.text").getTextualContent())
-            .isEqualTo("This is an awesome document on libroffice writter !\n");
+            .contains("This is an awesome document on libroffice writter !\n");
     }
     
     @Test
@@ -104,7 +104,7 @@ public class TikaTextExtractorTest {
         InputStream inputStream = ClassLoader.getSystemResourceAsStream("documents/slides.pptx");
         assertThat(inputStream).isNotNull();
         assertThat(textExtractor.extractContent(inputStream, "application/vnd.openxmlformats-officedocument.presentationml.presentation").getTextualContent())
-            .isEqualTo("James is awesome\nIt manages attachments so well !\n\n\n");
+            .contains("James is awesome\nIt manages attachments so well !\n\n\n");
     }
 
     @Test
@@ -112,7 +112,7 @@ public class TikaTextExtractorTest {
         InputStream inputStream = ClassLoader.getSystemResourceAsStream("documents/slides.odp");
         assertThat(inputStream).isNotNull();
         assertThat(textExtractor.extractContent(inputStream, "application/vnd.oasis.opendocument.presentation").getTextualContent())
-            .isEqualTo("James is awesome\n\nIt manages attachments so well !\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
+            .contains("James is awesome\n\nIt manages attachments so well !\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
     }
     
     @Test
@@ -120,7 +120,7 @@ public class TikaTextExtractorTest {
         InputStream inputStream = ClassLoader.getSystemResourceAsStream("documents/PDF.pdf");
         assertThat(inputStream).isNotNull();
         assertThat(textExtractor.extractContent(inputStream, "application/pdf").getTextualContent())
-            .isEqualTo("This is an awesome document on libroffice writter !\n\n\n");
+            .contains("This is an awesome document on libroffice writter !\n\n\n");
     }
     
     @Test
@@ -128,7 +128,7 @@ public class TikaTextExtractorTest {
         InputStream inputStream = ClassLoader.getSystemResourceAsStream("documents/calc.ods");
         assertThat(inputStream).isNotNull();
         assertThat(textExtractor.extractContent(inputStream, "application/vnd.oasis.opendocument.spreadsheet").getTextualContent())
-            .isEqualTo("This is an aesome LibreOffice document !\n" +
+            .contains("This is an aesome LibreOffice document !\n" +
                 "\n" +
                 "\n" +
                 "???\n" +
@@ -143,7 +143,7 @@ public class TikaTextExtractorTest {
         InputStream inputStream = ClassLoader.getSystemResourceAsStream("documents/calc.xlsx");
         assertThat(inputStream).isNotNull();
         assertThat(textExtractor.extractContent(inputStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet").getTextualContent())
-            .isEqualTo("Feuille1\n" +
+            .contains("Feuille1\n" +
                 "\tThis is an aesome LibreOffice document !\n" +
                 "\n" +
                 "&A\t\n" +
@@ -173,7 +173,7 @@ public class TikaTextExtractorTest {
         InputStream inputStream = null;
         ParsedContent parsedContent = textExtractor.extractContent(inputStream, "text/plain");
 
-        assertThat(parsedContent.getTextualContent()).isEqualTo(expectedExtractedContent);
+        assertThat(parsedContent.getTextualContent()).contains(expectedExtractedContent);
     }
 
     @Test


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


[08/24] james-project git commit: JAMES-2143 Guice injections for StoreBlobManager

Posted by ad...@apache.org.
JAMES-2143 Guice injections for StoreBlobManager


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

Branch: refs/heads/master
Commit: 55dcb3df3d136070a31f0fb7a21e77906403d5c5
Parents: a688e34
Author: benwa <bt...@linagora.com>
Authored: Mon Sep 11 16:24:22 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:19:53 2017 +0200

----------------------------------------------------------------------
 .../java/org/apache/james/mailbox/store/StoreBlobManager.java    | 3 +++
 .../org/apache/james/modules/mailbox/CassandraMailboxModule.java | 4 ++++
 .../org/apache/james/modules/mailbox/MemoryMailboxModule.java    | 4 ++++
 3 files changed, 11 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/55dcb3df/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
index e1474e3..2869354 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
@@ -22,6 +22,8 @@ package org.apache.james.mailbox.store;
 import java.io.IOException;
 import java.util.Optional;
 
+import javax.inject.Inject;
+
 import org.apache.commons.io.IOUtils;
 import org.apache.james.mailbox.AttachmentManager;
 import org.apache.james.mailbox.BlobManager;
@@ -47,6 +49,7 @@ public class StoreBlobManager implements BlobManager {
     private final MessageIdManager messageIdManager;
     private final MessageId.Factory messageIdFactory;
 
+    @Inject
     public StoreBlobManager(AttachmentManager attachmentManager, MessageIdManager messageIdManager, MessageId.Factory messageIdFactory) {
         this.attachmentManager = attachmentManager;
         this.messageIdManager = messageIdManager;

http://git-wip-us.apache.org/repos/asf/james-project/blob/55dcb3df/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
index 732b3ff..75d4bd0 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
@@ -24,6 +24,7 @@ import org.apache.james.adapter.mailbox.store.UserRepositoryAuthenticator;
 import org.apache.james.adapter.mailbox.store.UserRepositoryAuthorizator;
 import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.mailbox.AttachmentManager;
+import org.apache.james.mailbox.BlobManager;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MessageIdManager;
@@ -53,6 +54,7 @@ import org.apache.james.mailbox.store.BatchSizes;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.NoMailboxPathLocker;
 import org.apache.james.mailbox.store.StoreAttachmentManager;
+import org.apache.james.mailbox.store.StoreBlobManager;
 import org.apache.james.mailbox.store.StoreMessageIdManager;
 import org.apache.james.mailbox.store.event.MailboxEventDispatcher;
 import org.apache.james.mailbox.store.mail.AttachmentMapperFactory;
@@ -98,7 +100,9 @@ public class CassandraMailboxModule extends AbstractModule {
         bind(CassandraBlobsDAO.class).in(Scopes.SINGLETON);
         bind(CassandraAttachmentDAO.class).in(Scopes.SINGLETON);
         bind(CassandraAttachmentDAOV2.class).in(Scopes.SINGLETON);
+        bind(StoreBlobManager.class).in(Scopes.SINGLETON);
 
+        bind(BlobManager.class).to(StoreBlobManager.class);
         bind(MessageMapperFactory.class).to(CassandraMailboxSessionMapperFactory.class);
         bind(MailboxMapperFactory.class).to(CassandraMailboxSessionMapperFactory.class);
         bind(AttachmentMapperFactory.class).to(CassandraMailboxSessionMapperFactory.class);

http://git-wip-us.apache.org/repos/asf/james-project/blob/55dcb3df/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/mailbox/MemoryMailboxModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/mailbox/MemoryMailboxModule.java b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/mailbox/MemoryMailboxModule.java
index 0b28b08..a786be9 100644
--- a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/mailbox/MemoryMailboxModule.java
+++ b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/mailbox/MemoryMailboxModule.java
@@ -24,6 +24,7 @@ import javax.inject.Singleton;
 import org.apache.james.adapter.mailbox.store.UserRepositoryAuthenticator;
 import org.apache.james.adapter.mailbox.store.UserRepositoryAuthorizator;
 import org.apache.james.mailbox.AttachmentManager;
+import org.apache.james.mailbox.BlobManager;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MessageIdManager;
@@ -51,6 +52,7 @@ import org.apache.james.mailbox.store.Authorizator;
 import org.apache.james.mailbox.store.JVMMailboxPathLocker;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.StoreAttachmentManager;
+import org.apache.james.mailbox.store.StoreBlobManager;
 import org.apache.james.mailbox.store.StoreSubscriptionManager;
 import org.apache.james.mailbox.store.event.MailboxEventDispatcher;
 import org.apache.james.mailbox.store.mail.AttachmentMapperFactory;
@@ -88,6 +90,7 @@ public class MemoryMailboxModule extends AbstractModule {
         bind(MailboxId.Factory.class).to(InMemoryId.Factory.class);
         bind(MessageId.Factory.class).to(InMemoryMessageId.Factory.class);
 
+        bind(BlobManager.class).to(StoreBlobManager.class);
         bind(SubscriptionManager.class).to(StoreSubscriptionManager.class);
         bind(SubscriptionMapperFactory.class).to(InMemoryMailboxSessionMapperFactory.class);
         bind(MailboxSessionMapperFactory.class).to(InMemoryMailboxSessionMapperFactory.class);
@@ -103,6 +106,7 @@ public class MemoryMailboxModule extends AbstractModule {
         bind(MessageSearchIndex.class).to(SimpleMessageSearchIndex.class);
         bind(TextExtractor.class).to(JsoupTextExtractor.class);
 
+        bind(StoreBlobManager.class).in(Scopes.SINGLETON);
         bind(InMemoryMailboxSessionMapperFactory.class).in(Scopes.SINGLETON);
         bind(InMemoryModSeqProvider.class).in(Scopes.SINGLETON);
         bind(InMemoryUidProvider.class).in(Scopes.SINGLETON);


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


[24/24] james-project git commit: JAMES-2139 Add IT so that group does not support external address

Posted by ad...@apache.org.
JAMES-2139 Add IT so that group does not support external address


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

Branch: refs/heads/master
Commit: 81bf0a3c8c009b49a8c9bb4effd7a9af391b6469
Parents: d42ec7f
Author: quynhn <qn...@linagora.com>
Authored: Tue Sep 12 16:11:01 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:23:34 2017 +0200

----------------------------------------------------------------------
 server/mailet/integration-testing/pom.xml       |  6 ++
 .../transport/mailets/GroupMappingTest.java     | 79 +++++++++++++++++++-
 .../src/test/resources/domainlist.xml           |  4 +-
 3 files changed, 85 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/81bf0a3c/server/mailet/integration-testing/pom.xml
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/pom.xml b/server/mailet/integration-testing/pom.xml
index 147b510..02858f8 100644
--- a/server/mailet/integration-testing/pom.xml
+++ b/server/mailet/integration-testing/pom.xml
@@ -55,6 +55,12 @@
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-dnsservice-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>james-server-guice-common</artifactId>
             <type>test-jar</type>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/81bf0a3c/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
index f391fff..db99d55 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
@@ -19,14 +19,19 @@
 
 package org.apache.james.transport.mailets;
 
+import static com.jayway.restassured.RestAssured.with;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.isEmptyOrNullString;
 
+import java.net.InetAddress;
 import java.util.concurrent.TimeUnit;
 
 import javax.mail.internet.MimeMessage;
 
 import org.apache.james.core.MailAddress;
+import org.apache.james.dnsservice.api.DNSService;
+import org.apache.james.dnsservice.api.InMemoryDNSService;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailets.TemporaryJamesServer;
 import org.apache.james.mailets.configuration.CommonProcessors;
@@ -35,6 +40,7 @@ import org.apache.james.mailets.configuration.MailetContainer;
 import org.apache.james.mailets.configuration.ProcessorConfiguration;
 import org.apache.james.modules.MailboxProbeImpl;
 import org.apache.james.probe.DataProbe;
+import org.apache.james.util.streams.SwarmGenericContainer;
 import org.apache.james.utils.DataProbeImpl;
 import org.apache.james.utils.IMAPMessageReader;
 import org.apache.james.utils.SMTPMessageSender;
@@ -79,13 +85,45 @@ public class GroupMappingTest {
     private RequestSpecification restApiRequest;
 
     @Rule
+    public final SwarmGenericContainer fakeSmtp = new SwarmGenericContainer("weave/rest-smtp-sink:latest")
+        .withExposedPorts(25);
+
+    private final InMemoryDNSService inMemoryDNSService = new InMemoryDNSService();
+    @Rule
     public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+    private InetAddress containerIp;
     @Before
     public void setup() throws Exception {
+
+        containerIp = InetAddress.getByName(fakeSmtp.getContainerIp());
+        inMemoryDNSService.registerRecord("yopmail.com", containerIp, "yopmail.com");
+
         MailetContainer mailetContainer = MailetContainer.builder()
             .postmaster("postmaster@" + DOMAIN1)
             .threads(5)
-            .addProcessor(CommonProcessors.root())
+            .addProcessor(ProcessorConfiguration.builder()
+                .state("root")
+                .enableJmx(true)
+                .addMailet(MailetConfiguration.builder()
+                    .match("All")
+                    .clazz("PostmasterAlias")
+                    .build())
+                .addMailet(MailetConfiguration.builder()
+                    .match("RelayLimit=30")
+                    .clazz("Null")
+                    .build())
+                .addMailet(MailetConfiguration.builder()
+                    .match("SMTPAuthSuccessful")
+                    .clazz("ToProcessor")
+                    .addProperty("processor", "transport")
+                    .build())
+                .addMailet(MailetConfiguration.builder()
+                    .match("All")
+                    .clazz("ToProcessor")
+                    .addProperty("processor", "transport")
+                    .build())
+                .build())
             .addProcessor(CommonProcessors.error())
             .addProcessor(ProcessorConfiguration.transport()
                 .enableJmx(true)
@@ -120,7 +158,8 @@ public class GroupMappingTest {
                 .build())
             .build();
 
-        jamesServer = new TemporaryJamesServer(temporaryFolder, mailetContainer);
+        jamesServer = new TemporaryJamesServer(temporaryFolder, mailetContainer, (binder) -> binder.bind(DNSService.class).toInstance(inMemoryDNSService));
+
         Duration slowPacedPollInterval = Duration.FIVE_HUNDRED_MILLISECONDS;
         calmlyAwait = Awaitility.with().pollInterval(slowPacedPollInterval).and().with().pollDelay(slowPacedPollInterval).await();
 
@@ -388,4 +427,40 @@ public class GroupMappingTest {
             calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userReceivedMessage(USER_DOMAIN2, PASSWORD));
         }
     }
+
+    @Test
+    public void externalGroupMemberAreNotSupported() throws Exception {
+        String externalMail = "ray@yopmail.com";
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + externalMail);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+
+            calmlyAwait.atMost(1, TimeUnit.MINUTES)
+                .until(() -> {
+                    try {
+                        with()
+                            .baseUri("http://" + containerIp.getHostAddress())
+                            .port(80)
+                            .get("/api/email")
+                        .then()
+                            .statusCode(200)
+                            .body("[0].from", equalTo(SENDER))
+                            .body("[0].to[0]", equalTo(externalMail))
+                            .body("[0].text", equalTo(MESSAGE_CONTENT));
+
+                        return true;
+                    } catch(AssertionError e) {
+                        return false;
+                    }
+                });
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/81bf0a3c/server/mailet/integration-testing/src/test/resources/domainlist.xml
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/resources/domainlist.xml b/server/mailet/integration-testing/src/test/resources/domainlist.xml
index d9040c0..fc3d912 100644
--- a/server/mailet/integration-testing/src/test/resources/domainlist.xml
+++ b/server/mailet/integration-testing/src/test/resources/domainlist.xml
@@ -21,7 +21,7 @@
 <!-- See http://james.apache.org/server/3/config.html for usage -->
 
 <domainlist>
-  <autodetect>true</autodetect>
-  <autodetectIP>true</autodetectIP>
+  <autodetect>false</autodetect>
+  <autodetectIP>false</autodetectIP>
   <defaultDomain>localhost</defaultDomain>
 </domainlist>


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


[17/24] james-project git commit: MAILBOX-305 Compile time checks for Attachment mapper

Posted by ad...@apache.org.
MAILBOX-305 Compile time checks for Attachment mapper

I can not anymore access an attachment mapper in implementations that does not support it.


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

Branch: refs/heads/master
Commit: 035f0f789cae82196a3a37c57a10cc0c14681966
Parents: e6f7567
Author: benwa <bt...@linagora.com>
Authored: Thu Sep 7 15:24:43 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:21:48 2017 +0200

----------------------------------------------------------------------
 .../CachingMailboxSessionMapperFactory.java     |  7 ---
 .../cassandra/CassandraMailboxManager.java      |  6 +-
 .../CassandraMailboxSessionMapperFactory.java   | 21 +++++--
 .../cassandra/CassandraMessageManager.java      | 27 +++++++--
 .../CassandraMailboxManagerAttachmentTest.java  |  6 ++
 .../cassandra/mail/CassandraMapperProvider.java |  2 +-
 .../hbase/HBaseMailboxSessionMapperFactory.java |  7 ---
 .../jcr/JCRMailboxSessionMapperFactory.java     |  7 ---
 .../jpa/JPAMailboxSessionMapperFactory.java     |  7 ---
 .../MaildirMailboxSessionMapperFactory.java     |  9 ---
 .../InMemoryMailboxSessionMapperFactory.java    |  8 ++-
 .../inmemory/InMemoryMessageManager.java        | 24 +++++++-
 .../InMemoryMailboxManagerAttachmentTest.java   |  6 ++
 .../store/MailboxSessionMapperFactory.java      | 17 +-----
 .../mailbox/store/StoreMessageManager.java      | 19 +++----
 .../store/mail/AttachmentMapperFactory.java     |  2 +
 .../store/mail/NoopAttachmentMapper.java        | 59 --------------------
 .../AbstractMailboxManagerAttachmentTest.java   |  6 +-
 .../store/TestMailboxSessionMapperFactory.java  | 10 +---
 .../james/modules/mailbox/JPAMailboxModule.java |  2 -
 20 files changed, 105 insertions(+), 147 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/caching/src/main/java/org/apache/james/mailbox/caching/CachingMailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git a/mailbox/caching/src/main/java/org/apache/james/mailbox/caching/CachingMailboxSessionMapperFactory.java b/mailbox/caching/src/main/java/org/apache/james/mailbox/caching/CachingMailboxSessionMapperFactory.java
index eed35fa..19f6cb2 100644
--- a/mailbox/caching/src/main/java/org/apache/james/mailbox/caching/CachingMailboxSessionMapperFactory.java
+++ b/mailbox/caching/src/main/java/org/apache/james/mailbox/caching/CachingMailboxSessionMapperFactory.java
@@ -6,12 +6,10 @@ import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.SubscriptionException;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.mail.AnnotationMapper;
-import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
 import org.apache.james.mailbox.store.mail.MessageIdMapper;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.ModSeqProvider;
-import org.apache.james.mailbox.store.mail.NoopAttachmentMapper;
 import org.apache.james.mailbox.store.mail.UidProvider;
 import org.apache.james.mailbox.store.user.SubscriptionMapper;
 
@@ -53,11 +51,6 @@ public class CachingMailboxSessionMapperFactory extends
     }
 
     @Override
-    public AttachmentMapper createAttachmentMapper(MailboxSession session) throws MailboxException {
-        return new NoopAttachmentMapper();
-    }
-
-    @Override
     public AnnotationMapper createAnnotationMapper(MailboxSession session)
             throws MailboxException {
         throw new NotImplementedException();

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java
index 736ef6a..1f1527f 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java
@@ -51,6 +51,7 @@ import org.apache.james.mailbox.store.search.MessageSearchIndex;
  */
 public class CassandraMailboxManager extends StoreMailboxManager {
     private final MailboxPathLocker locker;
+    private final CassandraMailboxSessionMapperFactory mapperFactory;
 
     @Inject
     public CassandraMailboxManager(CassandraMailboxSessionMapperFactory mapperFactory, Authenticator authenticator, Authorizator authorizator,
@@ -69,6 +70,7 @@ public class CassandraMailboxManager extends StoreMailboxManager {
             mailboxEventDispatcher,
             delegatingMailboxListener);
         this.locker = locker;
+        this.mapperFactory = mapperFactory;
     }
 
     public CassandraMailboxManager(CassandraMailboxSessionMapperFactory mapperFactory, Authenticator authenticator, Authorizator authorizator,
@@ -82,6 +84,7 @@ public class CassandraMailboxManager extends StoreMailboxManager {
             messageParser,
             messageIdFactory);
         this.locker = locker;
+        this.mapperFactory = mapperFactory;
     }
 
     public CassandraMailboxManager(CassandraMailboxSessionMapperFactory mapperFactory, Authenticator authenticator,  Authorizator authorizator,
@@ -97,6 +100,7 @@ public class CassandraMailboxManager extends StoreMailboxManager {
             limitOfAnnotations,
             limitAnnotationSize);
         this.locker = locker;
+        this.mapperFactory = mapperFactory;
     }
 
     @Override
@@ -124,7 +128,7 @@ public class CassandraMailboxManager extends StoreMailboxManager {
 
     @Override
     protected StoreMessageManager createMessageManager(Mailbox mailboxRow, MailboxSession session) throws MailboxException {
-        return new CassandraMessageManager(getMapperFactory(),
+        return new CassandraMessageManager(mapperFactory,
             getMessageSearchIndex(),
             getEventDispatcher(),
             this.locker,

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
index 1c1539d..85e3349 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
@@ -50,6 +50,7 @@ import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.mail.AnnotationMapper;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
+import org.apache.james.mailbox.store.mail.AttachmentMapperFactory;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
 import org.apache.james.mailbox.store.mail.MessageIdMapper;
 import org.apache.james.mailbox.store.mail.ModSeqProvider;
@@ -61,7 +62,9 @@ import com.datastax.driver.core.Session;
 /**
  * Cassandra implementation of {@link MailboxSessionMapperFactory}
  */
-public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFactory {
+public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFactory implements AttachmentMapperFactory {
+    protected final static String ATTACHMENTMAPPER = "ATTACHMENTMAPPER";
+
     private final Session session;
     private final CassandraUidProvider uidProvider;
     private final CassandraModSeqProvider modSeqProvider;
@@ -122,7 +125,7 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa
                                           uidProvider,
                                           modSeqProvider,
                                           null,
-                                          (CassandraAttachmentMapper) createAttachmentMapper(mailboxSession),
+                                          createAttachmentMapper(mailboxSession),
                                           messageDAO,
                                           messageIdDAO,
                                           imapUidDAO,
@@ -138,7 +141,7 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa
     @Override
     public MessageIdMapper createMessageIdMapper(MailboxSession mailboxSession) throws MailboxException {
         return new CassandraMessageIdMapper(getMailboxMapper(mailboxSession), mailboxDAO,
-                (CassandraAttachmentMapper) getAttachmentMapper(mailboxSession),
+                (CassandraAttachmentMapper) createAttachmentMapper(mailboxSession),
                 imapUidDAO, messageIdDAO, messageDAO, indexTableHandler, modSeqProvider, mailboxSession,
                 cassandraConfiguration);
     }
@@ -149,7 +152,7 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa
     }
 
     @Override
-    public AttachmentMapper createAttachmentMapper(MailboxSession mailboxSession) {
+    public CassandraAttachmentMapper createAttachmentMapper(MailboxSession mailboxSession) {
         return new CassandraAttachmentMapper(attachmentDAO, attachmentDAOV2, blobsDAO);
     }
 
@@ -175,4 +178,14 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa
             throws MailboxException {
         return new CassandraAnnotationMapper(session, cassandraUtils);
     }
+
+    @Override
+    public AttachmentMapper getAttachmentMapper(MailboxSession session) throws MailboxException {
+        AttachmentMapper mapper = (AttachmentMapper) session.getAttributes().get(ATTACHMENTMAPPER);
+        if (mapper == null) {
+            mapper = createAttachmentMapper(session);
+            session.getAttributes().put(ATTACHMENTMAPPER, mapper);
+        }
+        return mapper;
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
index 585e6e3..0a8890d 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.mailbox.cassandra;
 
+import java.util.List;
+
 import javax.mail.Flags;
 
 import org.apache.james.mailbox.MailboxPathLocker;
@@ -26,31 +28,37 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
 import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
 import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
 import org.apache.james.mailbox.store.BatchSizes;
 import org.apache.james.mailbox.store.ImmutableMailboxMessage;
-import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.event.MailboxEventDispatcher;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
 import org.apache.james.mailbox.store.search.MessageSearchIndex;
 
+import com.github.steveash.guavate.Guavate;
+
 /**
  * Cassandra implementation of {@link StoreMessageManager}
  * 
  */
 public class CassandraMessageManager extends StoreMessageManager {
 
-    public CassandraMessageManager(MailboxSessionMapperFactory mapperFactory, MessageSearchIndex index, 
-            MailboxEventDispatcher dispatcher, MailboxPathLocker locker, Mailbox mailbox, QuotaManager quotaManager, 
-            QuotaRootResolver quotaRootResolver, MessageParser messageParser, MessageId.Factory messageIdFactory,
-            BatchSizes batchSizes, ImmutableMailboxMessage.Factory immutableMailboxMessageFactory) throws MailboxException {
+    private CassandraMailboxSessionMapperFactory mapperFactory;
+
+    public CassandraMessageManager(CassandraMailboxSessionMapperFactory mapperFactory, MessageSearchIndex index,
+                                   MailboxEventDispatcher dispatcher, MailboxPathLocker locker, Mailbox mailbox, QuotaManager quotaManager,
+                                   QuotaRootResolver quotaRootResolver, MessageParser messageParser, MessageId.Factory messageIdFactory,
+                                   BatchSizes batchSizes, ImmutableMailboxMessage.Factory immutableMailboxMessageFactory) throws MailboxException {
         super(mapperFactory, index, dispatcher, locker, mailbox, new UnionMailboxACLResolver(), 
                 new SimpleGroupMembershipResolver(), quotaManager, quotaRootResolver, messageParser, messageIdFactory, batchSizes, immutableMailboxMessageFactory);
 
+        this.mapperFactory = mapperFactory;
     }
 
     /**
@@ -62,4 +70,13 @@ public class CassandraMessageManager extends StoreMessageManager {
         flags.add(Flags.Flag.USER);
         return flags;
     }
+
+    @Override
+    protected void storeAttachment(final MailboxMessage message, final List<MessageAttachment> messageAttachments, final MailboxSession session) throws MailboxException {
+        mapperFactory.getAttachmentMapper(session)
+            .storeAttachments(
+                messageAttachments.stream()
+                    .map(MessageAttachment::getAttachment)
+                    .collect(Guavate.toImmutableList()));
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java
index 59cc7ee..e19e594 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java
@@ -47,6 +47,7 @@ import org.apache.james.mailbox.store.Authenticator;
 import org.apache.james.mailbox.store.Authorizator;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.NoMailboxPathLocker;
+import org.apache.james.mailbox.store.mail.AttachmentMapperFactory;
 import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
 import org.junit.After;
 import org.junit.Before;
@@ -121,4 +122,9 @@ public class CassandraMailboxManagerAttachmentTest extends AbstractMailboxManage
     protected MailboxManager getParseFailingMailboxManager() {
         return parseFailingMailboxManager;
     }
+
+    @Override
+    protected AttachmentMapperFactory getAttachmentMapperFactory() {
+        return mailboxSessionMapperFactory;
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMapperProvider.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMapperProvider.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMapperProvider.java
index d00923b..cf72181 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMapperProvider.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMapperProvider.java
@@ -86,7 +86,7 @@ public class CassandraMapperProvider implements MapperProvider {
 
     @Override
     public AttachmentMapper createAttachmentMapper() throws MailboxException {
-        return createMapperFactory().getAttachmentMapper(mailboxSession);
+        return createMapperFactory().createAttachmentMapper(mailboxSession);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseMailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseMailboxSessionMapperFactory.java b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseMailboxSessionMapperFactory.java
index d0cba35..c8ce4e3 100644
--- a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseMailboxSessionMapperFactory.java
+++ b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseMailboxSessionMapperFactory.java
@@ -47,12 +47,10 @@ import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageId.Factory;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.mail.AnnotationMapper;
-import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
 import org.apache.james.mailbox.store.mail.MessageIdMapper;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.ModSeqProvider;
-import org.apache.james.mailbox.store.mail.NoopAttachmentMapper;
 import org.apache.james.mailbox.store.mail.UidProvider;
 import org.apache.james.mailbox.store.user.SubscriptionMapper;
 
@@ -154,11 +152,6 @@ public class HBaseMailboxSessionMapperFactory extends MailboxSessionMapperFactor
         return new HBaseSubscriptionMapper(this.conf);
     }
 
-    @Override
-    public AttachmentMapper createAttachmentMapper(MailboxSession session) throws MailboxException {
-        return new NoopAttachmentMapper();
-    }
-
     /**
      * Returns the configuration object for accessing the cluster.
      * @return The configuration for accessing the cluster

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMailboxSessionMapperFactory.java b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMailboxSessionMapperFactory.java
index 8bd2fc2..47e8535 100644
--- a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMailboxSessionMapperFactory.java
+++ b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMailboxSessionMapperFactory.java
@@ -27,12 +27,10 @@ import org.apache.james.mailbox.jcr.mail.JCRMessageMapper;
 import org.apache.james.mailbox.jcr.user.JCRSubscriptionMapper;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.mail.AnnotationMapper;
-import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
 import org.apache.james.mailbox.store.mail.MessageIdMapper;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.ModSeqProvider;
-import org.apache.james.mailbox.store.mail.NoopAttachmentMapper;
 import org.apache.james.mailbox.store.mail.UidProvider;
 import org.apache.james.mailbox.store.user.SubscriptionMapper;
 
@@ -82,11 +80,6 @@ public class JCRMailboxSessionMapperFactory extends MailboxSessionMapperFactory
         return new JCRSubscriptionMapper(repository, session, DEFAULT_SCALING);
     }
     
-    @Override
-    public AttachmentMapper createAttachmentMapper(MailboxSession session) throws MailboxException {
-        return new NoopAttachmentMapper();
-    }
-    
     public MailboxSessionJCRRepository getRepository() {
         return repository;
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMailboxSessionMapperFactory.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMailboxSessionMapperFactory.java
index 036df5f..09ded1f 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMailboxSessionMapperFactory.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMailboxSessionMapperFactory.java
@@ -31,12 +31,10 @@ import org.apache.james.mailbox.jpa.mail.JPAMessageMapper;
 import org.apache.james.mailbox.jpa.user.JPASubscriptionMapper;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.mail.AnnotationMapper;
-import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
 import org.apache.james.mailbox.store.mail.MessageIdMapper;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.ModSeqProvider;
-import org.apache.james.mailbox.store.mail.NoopAttachmentMapper;
 import org.apache.james.mailbox.store.mail.UidProvider;
 import org.apache.james.mailbox.store.user.SubscriptionMapper;
 
@@ -77,11 +75,6 @@ public class JPAMailboxSessionMapperFactory extends MailboxSessionMapperFactory
     public SubscriptionMapper createSubscriptionMapper(MailboxSession session) {
         return new JPASubscriptionMapper(entityManagerFactory);
     }
-    
-    @Override
-    public AttachmentMapper createAttachmentMapper(MailboxSession session) throws MailboxException {
-        return new NoopAttachmentMapper();
-    }
 
     /**
      * Return a new {@link EntityManager} instance

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/MaildirMailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/MaildirMailboxSessionMapperFactory.java b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/MaildirMailboxSessionMapperFactory.java
index 3b0faad..8175a23 100644
--- a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/MaildirMailboxSessionMapperFactory.java
+++ b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/MaildirMailboxSessionMapperFactory.java
@@ -27,12 +27,10 @@ import org.apache.james.mailbox.maildir.mail.MaildirMessageMapper;
 import org.apache.james.mailbox.maildir.user.MaildirSubscriptionMapper;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.mail.AnnotationMapper;
-import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
 import org.apache.james.mailbox.store.mail.MessageIdMapper;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.ModSeqProvider;
-import org.apache.james.mailbox.store.mail.NoopAttachmentMapper;
 import org.apache.james.mailbox.store.mail.UidProvider;
 import org.apache.james.mailbox.store.user.SubscriptionMapper;
 
@@ -70,13 +68,6 @@ public class MaildirMailboxSessionMapperFactory extends
         return new MaildirSubscriptionMapper(store);
     }
 
-
-    @Override
-    public AttachmentMapper createAttachmentMapper(MailboxSession session) throws MailboxException {
-        return new NoopAttachmentMapper();
-    }
-
-
     @Override
     public AnnotationMapper createAnnotationMapper(MailboxSession session)
             throws MailboxException {

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMailboxSessionMapperFactory.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMailboxSessionMapperFactory.java
index 3a24427..adae134 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMailboxSessionMapperFactory.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMailboxSessionMapperFactory.java
@@ -31,6 +31,7 @@ import org.apache.james.mailbox.inmemory.user.InMemorySubscriptionMapper;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.mail.AnnotationMapper;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
+import org.apache.james.mailbox.store.mail.AttachmentMapperFactory;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
 import org.apache.james.mailbox.store.mail.MessageIdMapper;
 import org.apache.james.mailbox.store.mail.MessageMapper;
@@ -38,7 +39,7 @@ import org.apache.james.mailbox.store.mail.ModSeqProvider;
 import org.apache.james.mailbox.store.mail.UidProvider;
 import org.apache.james.mailbox.store.user.SubscriptionMapper;
 
-public class InMemoryMailboxSessionMapperFactory extends MailboxSessionMapperFactory {
+public class InMemoryMailboxSessionMapperFactory extends MailboxSessionMapperFactory implements AttachmentMapperFactory {
 
     private final MailboxMapper mailboxMapper;
     private final MessageMapper messageMapper;
@@ -105,4 +106,9 @@ public class InMemoryMailboxSessionMapperFactory extends MailboxSessionMapperFac
         return modSeqProvider;
     }
 
+    @Override
+    public AttachmentMapper getAttachmentMapper(MailboxSession session) throws MailboxException {
+        return attachmentMapper;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
----------------------------------------------------------------------
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
index 161bd5c..7620ddc 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
@@ -1,5 +1,7 @@
 package org.apache.james.mailbox.inmemory;
 
+import java.util.List;
+
 import javax.mail.Flags;
 
 import org.apache.james.mailbox.MailboxPathLocker;
@@ -7,6 +9,7 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.acl.GroupMembershipResolver;
 import org.apache.james.mailbox.acl.MailboxACLResolver;
 import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
@@ -16,15 +19,21 @@ import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.event.MailboxEventDispatcher;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
 import org.apache.james.mailbox.store.search.MessageSearchIndex;
 
+import com.github.steveash.guavate.Guavate;
+
 public class InMemoryMessageManager extends StoreMessageManager {
 
-    public InMemoryMessageManager(MailboxSessionMapperFactory mapperFactory, MessageSearchIndex index, MailboxEventDispatcher dispatcher, 
-            MailboxPathLocker locker, Mailbox mailbox, MailboxACLResolver aclResolver, GroupMembershipResolver groupMembershipResolver, 
-            QuotaManager quotaManager, QuotaRootResolver quotaRootResolver, MessageParser messageParser, MessageId.Factory messageIdFactory, BatchSizes batchSizes, ImmutableMailboxMessage.Factory immutableMailboxMessageFactory) throws MailboxException {
+    private InMemoryMailboxSessionMapperFactory mapperFactory;
+
+    public InMemoryMessageManager(MailboxSessionMapperFactory mapperFactory, MessageSearchIndex index, MailboxEventDispatcher dispatcher,
+                                  MailboxPathLocker locker, Mailbox mailbox, MailboxACLResolver aclResolver, GroupMembershipResolver groupMembershipResolver,
+                                  QuotaManager quotaManager, QuotaRootResolver quotaRootResolver, MessageParser messageParser, MessageId.Factory messageIdFactory, BatchSizes batchSizes, ImmutableMailboxMessage.Factory immutableMailboxMessageFactory) throws MailboxException {
         super(mapperFactory, index, dispatcher, locker, mailbox, aclResolver, groupMembershipResolver, quotaManager, quotaRootResolver, messageParser, messageIdFactory, batchSizes, immutableMailboxMessageFactory);
+        this.mapperFactory = (InMemoryMailboxSessionMapperFactory) mapperFactory;
     }
 
     @Override
@@ -33,4 +42,13 @@ public class InMemoryMessageManager extends StoreMessageManager {
         permanentFlags.add(Flags.Flag.USER);
         return permanentFlags;
     }
+
+    @Override
+    protected void storeAttachment(final MailboxMessage message, final List<MessageAttachment> messageAttachments, final MailboxSession session) throws MailboxException {
+        mapperFactory.getAttachmentMapper(session)
+            .storeAttachments(
+                messageAttachments.stream()
+                    .map(MessageAttachment::getAttachment)
+                    .collect(Guavate.toImmutableList()));
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxManagerAttachmentTest.java
----------------------------------------------------------------------
diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxManagerAttachmentTest.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxManagerAttachmentTest.java
index 9a9f755..d67f276 100644
--- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxManagerAttachmentTest.java
+++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxManagerAttachmentTest.java
@@ -36,6 +36,7 @@ import org.apache.james.mailbox.store.Authenticator;
 import org.apache.james.mailbox.store.Authorizator;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.NoMailboxPathLocker;
+import org.apache.james.mailbox.store.mail.AttachmentMapperFactory;
 import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
 import org.junit.Before;
 
@@ -78,4 +79,9 @@ public class InMemoryMailboxManagerAttachmentTest extends AbstractMailboxManager
     protected MailboxManager getParseFailingMailboxManager() {
         return parseFailingMailboxManager;
     }
+
+    @Override
+    protected AttachmentMapperFactory getAttachmentMapperFactory() {
+        return mailboxSessionMapperFactory;
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/store/src/main/java/org/apache/james/mailbox/store/MailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MailboxSessionMapperFactory.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MailboxSessionMapperFactory.java
index 6dd87ef..ce521d7 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MailboxSessionMapperFactory.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MailboxSessionMapperFactory.java
@@ -23,8 +23,6 @@ import org.apache.james.mailbox.RequestAware;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.SubscriptionException;
 import org.apache.james.mailbox.store.mail.AnnotationMapper;
-import org.apache.james.mailbox.store.mail.AttachmentMapper;
-import org.apache.james.mailbox.store.mail.AttachmentMapperFactory;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
 import org.apache.james.mailbox.store.mail.MailboxMapperFactory;
 import org.apache.james.mailbox.store.mail.MessageIdMapper;
@@ -40,9 +38,8 @@ import org.apache.james.mailbox.store.user.SubscriptionMapperFactory;
  * Maintain mapper instances by {@link MailboxSession}. So only one mapper instance is used
  * in a {@link MailboxSession}
  */
-public abstract class MailboxSessionMapperFactory implements RequestAware, MailboxMapperFactory, MessageMapperFactory, AttachmentMapperFactory, SubscriptionMapperFactory {
+public abstract class MailboxSessionMapperFactory implements RequestAware, MailboxMapperFactory, MessageMapperFactory, SubscriptionMapperFactory {
 
-    protected final static String ATTACHMENTMAPPER = "ATTACHMENTMAPPER";
     protected final static String MESSAGEMAPPER ="MESSAGEMAPPER";
     protected final static String MESSAGEIDMAPPER ="MESSAGEIDMAPPER";
     protected final static String MAILBOXMAPPER ="MAILBOXMAPPER";
@@ -71,15 +68,6 @@ public abstract class MailboxSessionMapperFactory implements RequestAware, Mailb
         return mapper;
     }
 
-    public AttachmentMapper getAttachmentMapper(MailboxSession session) throws MailboxException {
-        AttachmentMapper mapper = (AttachmentMapper) session.getAttributes().get(ATTACHMENTMAPPER);
-        if (mapper == null) {
-            mapper = createAttachmentMapper(session);
-            session.getAttributes().put(ATTACHMENTMAPPER, mapper);
-        }
-        return mapper;
-    }
-
     public AnnotationMapper getAnnotationMapper(MailboxSession session) throws MailboxException {
         AnnotationMapper mapper = (AnnotationMapper)session.getAttributes().get(ANNOTATIONMAPPER);
         if (mapper == null) {
@@ -103,9 +91,6 @@ public abstract class MailboxSessionMapperFactory implements RequestAware, Mailb
 
     public abstract MessageIdMapper createMessageIdMapper(MailboxSession session) throws MailboxException;
 
-    public abstract AttachmentMapper createAttachmentMapper(MailboxSession session) throws MailboxException;
-
-
     /**
      * @see org.apache.james.mailbox.store.mail.MailboxMapperFactory#getMailboxMapper(MailboxSession)
      */

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
index 85a1282..a7a0e5b 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
@@ -30,11 +30,14 @@ import java.util.List;
 import java.util.Map;
 import java.util.SortedMap;
 import java.util.TreeMap;
+
 import javax.mail.Flags;
 import javax.mail.Flags.Flag;
 import javax.mail.internet.SharedInputStream;
 import javax.mail.util.SharedFileInputStream;
 
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.input.TeeInputStream;
 import org.apache.james.mailbox.MailboxListener;
 import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxSession;
@@ -47,7 +50,6 @@ import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.ReadOnlyException;
 import org.apache.james.mailbox.exception.UnsupportedRightException;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxACL.MailboxACLRights;
@@ -67,7 +69,6 @@ import org.apache.james.mailbox.model.UpdatedFlags;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
 import org.apache.james.mailbox.store.event.MailboxEventDispatcher;
-import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.MessageMapper.FetchType;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
@@ -88,8 +89,6 @@ import org.apache.james.mime4j.stream.MimeConfig;
 import org.apache.james.mime4j.stream.MimeTokenStream;
 import org.apache.james.mime4j.stream.RecursionMode;
 import org.apache.james.util.IteratorWrapper;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.io.input.TeeInputStream;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -634,17 +633,17 @@ public class StoreMessageManager implements org.apache.james.mailbox.MessageMana
 
     protected MessageMetaData appendMessageToStore(final MailboxMessage message, final List<MessageAttachment> messageAttachments, MailboxSession session) throws MailboxException {
         final MessageMapper messageMapper = mapperFactory.getMessageMapper(session);
-        final AttachmentMapper attachmentMapper = mapperFactory.getAttachmentMapper(session);
+
         return mapperFactory.getMessageMapper(session).execute(() -> {
-            ImmutableList.Builder<Attachment> attachments = ImmutableList.builder();
-            for (MessageAttachment attachment : messageAttachments) {
-                attachments.add(attachment.getAttachment());
-            }
-            attachmentMapper.storeAttachments(attachments.build());
+            storeAttachment(message, messageAttachments, session);
             return messageMapper.add(getMailboxEntity(), message);
         });
     }
 
+    protected void storeAttachment(final MailboxMessage message, final List<MessageAttachment> messageAttachments, final MailboxSession session) throws MailboxException {
+
+    }
+
     /**
      * @see org.apache.james.mailbox.MessageManager#getMessageCount(org.apache.james.mailbox.MailboxSession)
      */

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapperFactory.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapperFactory.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapperFactory.java
index 3d08131..e3d768d 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapperFactory.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapperFactory.java
@@ -23,5 +23,7 @@ import org.apache.james.mailbox.exception.MailboxException;
 
 public interface AttachmentMapperFactory {
 
+    AttachmentMapper createAttachmentMapper(MailboxSession session) throws MailboxException;
+
     AttachmentMapper getAttachmentMapper(MailboxSession session) throws MailboxException;
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/NoopAttachmentMapper.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/NoopAttachmentMapper.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/NoopAttachmentMapper.java
deleted file mode 100644
index 9026f26..0000000
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/NoopAttachmentMapper.java
+++ /dev/null
@@ -1,59 +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.mailbox.store.mail;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.james.mailbox.exception.AttachmentNotFoundException;
-import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.model.Attachment;
-import org.apache.james.mailbox.model.AttachmentId;
-
-public class NoopAttachmentMapper implements AttachmentMapper {
-
-    @Override
-    public void endRequest() {
-
-    }
-
-    @Override
-    public <T> T execute(Transaction<T> transaction) throws MailboxException {
-        return transaction.run();
-    }
-
-    @Override
-    public Attachment getAttachment(AttachmentId attachmentId) throws AttachmentNotFoundException {
-        return null;
-    }
-
-    @Override
-    public List<Attachment> getAttachments(Collection<AttachmentId> attachmentIds) {
-        return null;
-    }
-
-    @Override
-    public void storeAttachment(Attachment attachment) throws MailboxException {
-    }
-
-    @Override
-    public void storeAttachments(Collection<Attachment> attachments) throws MailboxException {
-    }
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java
index 3657561..617d0e0 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java
@@ -20,12 +20,14 @@
 package org.apache.james.mailbox.store;
 
 import static org.assertj.core.api.Assertions.assertThat;
+
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Optional;
+
 import javax.mail.Flags;
 import javax.mail.Flags.Flag;
 
@@ -38,6 +40,7 @@ import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
+import org.apache.james.mailbox.store.mail.AttachmentMapperFactory;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.MessageMapper.FetchType;
@@ -61,6 +64,7 @@ public abstract class AbstractMailboxManagerAttachmentTest {
     protected abstract MailboxManager getMailboxManager();
     protected abstract MailboxManager getParseFailingMailboxManager();
     protected abstract MailboxSessionMapperFactory getMailboxSessionMapperFactory();
+    protected abstract AttachmentMapperFactory getAttachmentMapperFactory();
     
     public void setUp() throws Exception {
         mailboxSession = new MockMailboxSession(USERNAME);
@@ -71,7 +75,7 @@ public abstract class AbstractMailboxManagerAttachmentTest {
         mailboxManager.createMailbox(inboxPath, mailboxSession);
         inbox = mailboxMapper.findMailboxByPath(inboxPath);
         inboxMessageManager = mailboxManager.getMailbox(inboxPath, mailboxSession);
-        attachmentMapper = getMailboxSessionMapperFactory().getAttachmentMapper(mailboxSession);
+        attachmentMapper = getAttachmentMapperFactory().createAttachmentMapper(mailboxSession);
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/mailbox/store/src/test/java/org/apache/james/mailbox/store/TestMailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/TestMailboxSessionMapperFactory.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/TestMailboxSessionMapperFactory.java
index 7a93597..a2d7b03 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/TestMailboxSessionMapperFactory.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/TestMailboxSessionMapperFactory.java
@@ -22,14 +22,17 @@ package org.apache.james.mailbox.store;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
+
 import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.function.Predicate;
+
 import javax.mail.Flags;
 
+import org.apache.commons.lang.NotImplementedException;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
@@ -44,7 +47,6 @@ import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.UpdatedFlags;
 import org.apache.james.mailbox.store.mail.AnnotationMapper;
-import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
 import org.apache.james.mailbox.store.mail.MessageIdMapper;
 import org.apache.james.mailbox.store.mail.MessageMapper;
@@ -54,7 +56,6 @@ import org.apache.james.mailbox.store.mail.model.Mailbox;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox;
 import org.apache.james.mailbox.store.user.SubscriptionMapper;
-import org.apache.commons.lang.NotImplementedException;
 
 import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Preconditions;
@@ -266,11 +267,6 @@ public class TestMailboxSessionMapperFactory extends MailboxSessionMapperFactory
     }
 
     @Override
-    public AttachmentMapper createAttachmentMapper(MailboxSession session) throws MailboxException {
-        throw new NotImplementedException();
-    }
-
-    @Override
     public MailboxMapper createMailboxMapper(MailboxSession session) throws MailboxException {
         return mailboxMapper;
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/035f0f78/server/container/guice/jpa-guice/src/main/java/org/apache/james/modules/mailbox/JPAMailboxModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/jpa-guice/src/main/java/org/apache/james/modules/mailbox/JPAMailboxModule.java b/server/container/guice/jpa-guice/src/main/java/org/apache/james/modules/mailbox/JPAMailboxModule.java
index 228ffe6..43f337d 100644
--- a/server/container/guice/jpa-guice/src/main/java/org/apache/james/modules/mailbox/JPAMailboxModule.java
+++ b/server/container/guice/jpa-guice/src/main/java/org/apache/james/modules/mailbox/JPAMailboxModule.java
@@ -50,7 +50,6 @@ import org.apache.james.mailbox.store.Authenticator;
 import org.apache.james.mailbox.store.Authorizator;
 import org.apache.james.mailbox.store.JVMMailboxPathLocker;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
-import org.apache.james.mailbox.store.mail.AttachmentMapperFactory;
 import org.apache.james.mailbox.store.mail.MailboxMapperFactory;
 import org.apache.james.mailbox.store.mail.MessageMapperFactory;
 import org.apache.james.mailbox.store.mail.ModSeqProvider;
@@ -88,7 +87,6 @@ public class JPAMailboxModule extends AbstractModule {
 
         bind(MessageMapperFactory.class).to(JPAMailboxSessionMapperFactory.class);
         bind(MailboxMapperFactory.class).to(JPAMailboxSessionMapperFactory.class);
-        bind(AttachmentMapperFactory.class).to(JPAMailboxSessionMapperFactory.class);
         bind(MailboxSessionMapperFactory.class).to(JPAMailboxSessionMapperFactory.class);
         bind(MessageId.Factory.class).to(DefaultMessageId.Factory.class);
 


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


[12/24] james-project git commit: JAMES-2142 Add Attachments search filter

Posted by ad...@apache.org.
JAMES-2142 Add Attachments search filter


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

Branch: refs/heads/master
Commit: 38db514f54cc902df15bfc1785f527f91861c43d
Parents: 33846e6
Author: Antoine Duprat <ad...@linagora.com>
Authored: Fri Sep 8 10:45:39 2017 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:20:56 2017 +0200

----------------------------------------------------------------------
 .../james/jmap/model/FilterCondition.java       | 20 +++++++++++++++++---
 .../james/jmap/utils/FilterToSearchQuery.java   |  1 +
 .../james/jmap/model/FilterConditionTest.java   |  4 +++-
 .../jmap/utils/FilterToSearchQueryTest.java     | 13 +++++++++++++
 4 files changed, 34 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/38db514f/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/FilterCondition.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/FilterCondition.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/FilterCondition.java
index 334667d..0dd14a1 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/FilterCondition.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/FilterCondition.java
@@ -60,6 +60,7 @@ public class FilterCondition implements Filter {
         private String bcc;
         private String subject;
         private String body;
+        private String attachments;
         private Header header;
         private Optional<String> hasKeyword;
         private Optional<String> notKeyword;
@@ -185,6 +186,11 @@ public class FilterCondition implements Filter {
             return this;
         }
 
+        public Builder attachments(String attachments) {
+            this.attachments = attachments;
+            return this;
+        }
+
         public Builder header(Header header) {
             this.header = header;
             return this;
@@ -196,7 +202,7 @@ public class FilterCondition implements Filter {
             return new FilterCondition(inMailboxes, notInMailboxes, Optional.ofNullable(before), Optional.ofNullable(after), Optional.ofNullable(minSize), Optional.ofNullable(maxSize),
                     Optional.ofNullable(isFlagged), Optional.ofNullable(isUnread), Optional.ofNullable(isAnswered), Optional.ofNullable(isDraft), Optional.ofNullable(hasAttachment),
                     Optional.ofNullable(text), Optional.ofNullable(from), Optional.ofNullable(to), Optional.ofNullable(cc), Optional.ofNullable(bcc), Optional.ofNullable(subject),
-                    Optional.ofNullable(body), Optional.ofNullable(header), hasKeyword, notKeyword);
+                    Optional.ofNullable(body), Optional.ofNullable(attachments), Optional.ofNullable(header), hasKeyword, notKeyword);
         }
     }
 
@@ -218,6 +224,7 @@ public class FilterCondition implements Filter {
     private final Optional<String> bcc;
     private final Optional<String> subject;
     private final Optional<String> body;
+    private final Optional<String> attachments;
     private final Optional<Header> header;
     private final Optional<String> hasKeyword;
     private final Optional<String> notKeyword;
@@ -225,7 +232,7 @@ public class FilterCondition implements Filter {
     @VisibleForTesting FilterCondition(Optional<List<String>> inMailboxes, Optional<List<String>> notInMailboxes, Optional<ZonedDateTime> before, Optional<ZonedDateTime> after, Optional<Integer> minSize, Optional<Integer> maxSize,
                                        Optional<Boolean> isFlagged, Optional<Boolean> isUnread, Optional<Boolean> isAnswered, Optional<Boolean> isDraft, Optional<Boolean> hasAttachment,
                                        Optional<String> text, Optional<String> from, Optional<String> to, Optional<String> cc, Optional<String> bcc, Optional<String> subject,
-                                       Optional<String> body, Optional<Header> header, Optional<String> hasKeyword, Optional<String> notKeyword) {
+                                       Optional<String> body, Optional<String> attachments, Optional<Header> header, Optional<String> hasKeyword, Optional<String> notKeyword) {
 
         this.inMailboxes = inMailboxes;
         this.notInMailboxes = notInMailboxes;
@@ -245,6 +252,7 @@ public class FilterCondition implements Filter {
         this.bcc = bcc;
         this.subject = subject;
         this.body = body;
+        this.attachments = attachments;
         this.header = header;
         this.hasKeyword = hasKeyword;
         this.notKeyword = notKeyword;
@@ -322,6 +330,10 @@ public class FilterCondition implements Filter {
         return body;
     }
 
+    public Optional<String> getAttachments() {
+        return attachments;
+    }
+
     public Optional<Header> getHeader() {
         return header;
     }
@@ -356,6 +368,7 @@ public class FilterCondition implements Filter {
                 && Objects.equals(this.bcc, other.bcc)
                 && Objects.equals(this.subject, other.subject)
                 && Objects.equals(this.body, other.body)
+                && Objects.equals(this.attachments, other.attachments)
                 && Objects.equals(this.header, other.header)
                 && Objects.equals(this.hasKeyword, other.hasKeyword)
                 && Objects.equals(this.notKeyword, other.notKeyword);
@@ -366,7 +379,7 @@ public class FilterCondition implements Filter {
     @Override
     public final int hashCode() {
         return Objects.hash(inMailboxes, notInMailboxes, before, after, minSize, maxSize, isFlagged, isUnread, isAnswered, isDraft, hasAttachment,
-                text, from, to, cc, bcc, subject, body, header, hasKeyword, notKeyword);
+                text, from, to, cc, bcc, subject, body, attachments, header, hasKeyword, notKeyword);
     }
 
     @Override
@@ -390,6 +403,7 @@ public class FilterCondition implements Filter {
         bcc.ifPresent(x -> helper.add("bcc", x));
         subject.ifPresent(x -> helper.add("subject", x));
         body.ifPresent(x -> helper.add("body", x));
+        attachments.ifPresent(x -> helper.add("attachments", x));
         header.ifPresent(x -> helper.add("header", x));
         hasKeyword.ifPresent(x -> helper.add("hasKeyword", x));
         notKeyword.ifPresent(x -> helper.add("notKeyword", x));

http://git-wip-us.apache.org/repos/asf/james-project/blob/38db514f/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java
index f357628..d364b59 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java
@@ -67,6 +67,7 @@ public class FilterToSearchQuery {
         filter.getCc().ifPresent(cc -> searchQuery.andCriteria(SearchQuery.address(AddressType.Cc, cc)));
         filter.getBcc().ifPresent(bcc -> searchQuery.andCriteria(SearchQuery.address(AddressType.Bcc, bcc)));
         filter.getSubject().ifPresent(subject -> searchQuery.andCriteria(SearchQuery.headerContains("Subject", subject)));
+        filter.getAttachments().ifPresent(attachments ->  searchQuery.andCriteria(SearchQuery.attachmentContains(attachments)));
         filter.getBody().ifPresent(body ->  searchQuery.andCriteria(SearchQuery.bodyContains(body)));
         filter.getAfter().ifPresent(after -> searchQuery.andCriteria(SearchQuery.sentDateAfter(Date.from(after.toInstant()), DateResolution.Second)));
         filter.getBefore().ifPresent(before -> searchQuery.andCriteria(SearchQuery.sentDateBefore(Date.from(before.toInstant()), DateResolution.Second)));

http://git-wip-us.apache.org/repos/asf/james-project/blob/38db514f/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/FilterConditionTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/FilterConditionTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/FilterConditionTest.java
index 79c232f..828c94a 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/FilterConditionTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/FilterConditionTest.java
@@ -93,13 +93,14 @@ public class FilterConditionTest {
         String bcc = "blindcopy@james.org";
         String subject = "subject";
         String body = "body";
+        String attachments = "attachments";
         Header header = Header.from(ImmutableList.of("name", "value"));
         Optional<String> hasKeyword = Optional.of("$Draft");
         Optional<String> notKeyword = Optional.of("$Flagged");
 
         FilterCondition expectedFilterCondition = new FilterCondition(Optional.of(ImmutableList.of("1")), Optional.of(ImmutableList.of("2")), Optional.of(before), Optional.of(after), Optional.of(minSize), Optional.of(maxSize),
                 Optional.of(isFlagged), Optional.of(isUnread), Optional.of(isAnswered), Optional.of(isDraft), Optional.of(hasAttachment), Optional.of(text), Optional.of(from), 
-                Optional.of(to), Optional.of(cc), Optional.of(bcc), Optional.of(subject), Optional.of(body), Optional.of(header),
+                Optional.of(to), Optional.of(cc), Optional.of(bcc), Optional.of(subject), Optional.of(body), Optional.of(attachments), Optional.of(header),
                 hasKeyword, notKeyword);
 
         FilterCondition filterCondition = FilterCondition.builder()
@@ -121,6 +122,7 @@ public class FilterConditionTest {
                 .bcc(bcc)
                 .subject(subject)
                 .body(body)
+                .attachments(attachments)
                 .header(header)
                 .hasKeyword(hasKeyword)
                 .notKeyword(notKeyword)

http://git-wip-us.apache.org/repos/asf/james-project/blob/38db514f/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/FilterToSearchQueryTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/FilterToSearchQueryTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/FilterToSearchQueryTest.java
index 0662003..857af1f 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/FilterToSearchQueryTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/FilterToSearchQueryTest.java
@@ -161,6 +161,19 @@ public class FilterToSearchQueryTest {
     }
 
     @Test
+    public void filterConditionShouldMapWhenAttachments() {
+        String attachments = "attachments";
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.attachmentContains(attachments));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .attachments(attachments)
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
     public void filterConditionShouldMapWhenText() {
         String text = "text";
         SearchQuery expectedSearchQuery = new SearchQuery();


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