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/07/10 17:54:18 UTC

[06/41] james-project git commit: JAMES-2082 From MessageMapper layer, write to V2, read from V2 or V1 and Migration on fly

JAMES-2082 From MessageMapper layer, write to V2, read from V2 or V1 and Migration on fly


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

Branch: refs/heads/master
Commit: 31567b215cfcd32def54adc7bb567652f3c5ae33
Parents: 3b621a3
Author: benwa <bt...@linagora.com>
Authored: Thu Jul 6 17:15:51 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Mon Jul 10 14:23:55 2017 +0200

----------------------------------------------------------------------
 .../CassandraMailboxSessionMapperFactory.java   |  12 +-
 .../cassandra/mail/AttachmentLoader.java        |  18 ++
 .../cassandra/mail/CassandraMessageDAO.java     |  16 +-
 .../mail/CassandraMessageIdMapper.java          |  30 ++-
 .../cassandra/mail/CassandraMessageMapper.java  |  48 +++--
 .../mail/MessageWithoutAttachment.java          |  10 +
 .../mail/migration/V1ToV2Migration.java         |  90 +++++++++
 .../modules/CassandraMessageModule.java         |   4 +-
 .../CassandraMailboxManagerProvider.java        |   5 +
 .../CassandraMailboxManagerStressTest.java      |   2 +
 .../cassandra/CassandraMailboxManagerTest.java  |   2 +
 .../CassandraSubscriptionManagerTest.java       |   3 +
 .../cassandra/CassandraTestSystemFixture.java   |   7 +
 .../CassandraMailboxManagerAttachmentTest.java  |   9 +-
 .../cassandra/mail/CassandraMapperProvider.java |  10 +-
 .../cassandra/mail/CassandraMessageDAOTest.java |  26 ++-
 .../mail/migration/V1ToV2MigrationTest.java     | 185 +++++++++++++++++++
 .../store/mail/model/MessageMapperTest.java     |   9 +
 .../cassandra/host/CassandraHostSystem.java     |   7 +
 .../modules/mailbox/CassandraMailboxModule.java |   1 +
 20 files changed, 446 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/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 0168e84..4ddd2db 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
@@ -64,6 +64,7 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa
     private final CassandraUidProvider uidProvider;
     private final CassandraModSeqProvider modSeqProvider;
     private final CassandraMessageDAO messageDAO;
+    private final CassandraMessageDAOV2 messageDAOV2;
     private final CassandraMessageIdDAO messageIdDAO;
     private final CassandraMessageIdToImapUidDAO imapUidDAO;
     private final CassandraMailboxCounterDAO mailboxCounterDAO;
@@ -79,7 +80,8 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa
 
     @Inject
     public CassandraMailboxSessionMapperFactory(CassandraUidProvider uidProvider, CassandraModSeqProvider modSeqProvider, Session session,
-                                                CassandraMessageDAO messageDAO, CassandraMessageIdDAO messageIdDAO, CassandraMessageIdToImapUidDAO imapUidDAO,
+                                                CassandraMessageDAO messageDAO, CassandraMessageDAOV2 messageDAOV2,
+                                                CassandraMessageIdDAO messageIdDAO, CassandraMessageIdToImapUidDAO imapUidDAO,
                                                 CassandraMailboxCounterDAO mailboxCounterDAO, CassandraMailboxRecentsDAO mailboxRecentsDAO, CassandraMailboxDAO mailboxDAO,
                                                 CassandraMailboxPathDAO mailboxPathDAO, CassandraFirstUnseenDAO firstUnseenDAO, CassandraApplicableFlagDAO applicableFlagDAO,
                                                 CassandraDeletedMessageDAO deletedMessageDAO, CassandraUtils cassandraUtils, CassandraConfiguration cassandraConfiguration) {
@@ -87,6 +89,7 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa
         this.modSeqProvider = modSeqProvider;
         this.session = session;
         this.messageDAO = messageDAO;
+        this.messageDAOV2 = messageDAOV2;
         this.messageIdDAO = messageIdDAO;
         this.imapUidDAO = imapUidDAO;
         this.mailboxCounterDAO = mailboxCounterDAO;
@@ -111,6 +114,7 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa
         CassandraModSeqProvider modSeqProvider,
         Session session,
         CassandraMessageDAO messageDAO,
+        CassandraMessageDAOV2 messageDAOV2,
         CassandraMessageIdDAO messageIdDAO,
         CassandraMessageIdToImapUidDAO imapUidDAO,
         CassandraMailboxCounterDAO mailboxCounterDAO,
@@ -121,7 +125,7 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa
         CassandraApplicableFlagDAO applicableFlagDAO,
         CassandraDeletedMessageDAO deletedMesageDAO) {
 
-        this(uidProvider, modSeqProvider, session, messageDAO, messageIdDAO, imapUidDAO, mailboxCounterDAO,
+        this(uidProvider, modSeqProvider, session, messageDAO, messageDAOV2, messageIdDAO, imapUidDAO, mailboxCounterDAO,
              mailboxRecentsDAO, mailboxDAO, mailboxPathDAO, firstUnseenDAO, applicableFlagDAO, deletedMesageDAO,
             CassandraUtils.WITH_DEFAULT_CONFIGURATION, CassandraConfiguration.DEFAULT_CONFIGURATION);
     }
@@ -134,6 +138,7 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa
                                           null,
                                           (CassandraAttachmentMapper) createAttachmentMapper(mailboxSession),
                                           messageDAO,
+                                          messageDAOV2,
                                           messageIdDAO,
                                           imapUidDAO,
                                           mailboxCounterDAO,
@@ -149,7 +154,8 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa
     public MessageIdMapper createMessageIdMapper(MailboxSession mailboxSession) throws MailboxException {
         return new CassandraMessageIdMapper(getMailboxMapper(mailboxSession), mailboxDAO,
                 (CassandraAttachmentMapper) getAttachmentMapper(mailboxSession),
-                imapUidDAO, messageIdDAO, messageDAO, indexTableHandler, modSeqProvider, mailboxSession, cassandraConfiguration);
+                imapUidDAO, messageIdDAO, messageDAO, messageDAOV2, indexTableHandler, modSeqProvider, mailboxSession,
+                cassandraConfiguration);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/AttachmentLoader.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/AttachmentLoader.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/AttachmentLoader.java
index cd70e55..59933be 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/AttachmentLoader.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/AttachmentLoader.java
@@ -24,10 +24,14 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
 import java.util.function.Function;
+import java.util.stream.Stream;
 
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
+import org.apache.james.util.FluentFutureStream;
 import org.apache.james.util.OptionalConverter;
 
 import com.github.steveash.guavate.Guavate;
@@ -42,6 +46,20 @@ public class AttachmentLoader {
         this.attachmentMapper = attachmentMapper;
     }
 
+    public CompletableFuture<Stream<SimpleMailboxMessage>> toMailboxMessageWithAttachments(
+                CompletableFuture<Stream<Pair<MessageWithoutAttachment, Stream<MessageAttachmentRepresentation>>>> messageRepresentations) {
+
+        return FluentFutureStream.of(messageRepresentations)
+            .thenComposeOnAll(pair -> getAttachments(pair.getRight().collect(Guavate.toImmutableList()))
+                    .thenApply(attachments -> Pair.of(pair.getLeft(), attachments)))
+            .map(pair ->
+                pair.getLeft()
+                    .toMailboxMessage(pair.getRight()
+                        .stream()
+                        .collect(Guavate.toImmutableList())))
+            .completableFuture();
+    }
+
     public CompletableFuture<Collection<MessageAttachment>> getAttachments(List<MessageAttachmentRepresentation> attachmentRepresentations) {
         CompletableFuture<Map<AttachmentId, Attachment>> attachmentsByIdFuture =
             attachmentsById(attachmentRepresentations.stream()

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java
index d9d6eaf..ed29a11 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java
@@ -57,6 +57,7 @@ import org.apache.james.backends.cassandra.CassandraConfiguration;
 import org.apache.james.backends.cassandra.init.CassandraTypesProvider;
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
 import org.apache.james.mailbox.cassandra.CassandraMessageId;
+import org.apache.james.mailbox.cassandra.Limit;
 import org.apache.james.mailbox.cassandra.table.CassandraMessageV1Table.Attachments;
 import org.apache.james.mailbox.cassandra.table.CassandraMessageV1Table.Properties;
 import org.apache.james.mailbox.exception.MailboxException;
@@ -186,9 +187,13 @@ public class CassandraMessageDAO {
         return ByteBuffer.wrap(ByteStreams.toByteArray(stream));
     }
 
-    public CompletableFuture<Stream<Pair<MessageWithoutAttachment, Stream<MessageAttachmentRepresentation>>>> retrieveMessages(List<ComposedMessageIdWithMetaData> messageIds, FetchType fetchType, Optional<Integer> limit) {
+    public CompletableFuture<Stream<Pair<MessageWithoutAttachment, Stream<MessageAttachmentRepresentation>>>> retrieveMessages(
+        List<ComposedMessageIdWithMetaData> messageIds,
+        FetchType fetchType,
+        Limit limit
+    ) {
         return CompletableFutureUtil.chainAll(
-            getLimitedIdStream(messageIds.stream().distinct(), limit)
+            limit.applyOnStream(messageIds.stream().distinct())
                 .collect(JamesCollectors.chunker(cassandraConfiguration.getMessageReadChunkSize())),
             ids -> FluentFutureStream.of(
                 ids.stream()
@@ -199,13 +204,6 @@ public class CassandraMessageDAO {
             .thenApply(stream -> stream.flatMap(Function.identity()));
     }
 
-    private Stream<ComposedMessageIdWithMetaData> getLimitedIdStream(Stream<ComposedMessageIdWithMetaData> messageIds, Optional<Integer> limit) {
-        return limit
-            .filter(value -> value > 0)
-            .map(messageIds::limit)
-            .orElse(messageIds);
-    }
-
     private CompletableFuture<ResultSet> retrieveRow(ComposedMessageIdWithMetaData messageId, FetchType fetchType) {
         CassandraMessageId cassandraMessageId = (CassandraMessageId) messageId.getComposedMessageId().getMessageId();
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdMapper.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdMapper.java
index 81d2cf1..d84c8c8 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdMapper.java
@@ -36,6 +36,8 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.cassandra.CassandraId;
 import org.apache.james.mailbox.cassandra.CassandraMessageId;
+import org.apache.james.mailbox.cassandra.Limit;
+import org.apache.james.mailbox.cassandra.mail.migration.V1ToV2Migration;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
@@ -51,6 +53,7 @@ import org.apache.james.mailbox.store.mail.ModSeqProvider;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
 import org.apache.james.util.CompletableFutureUtil;
+import org.apache.james.util.FluentFutureStream;
 import org.apache.james.util.OptionalConverter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -59,6 +62,7 @@ import com.github.fge.lambdas.Throwing;
 import com.github.fge.lambdas.functions.FunctionChainer;
 import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
 
 public class CassandraMessageIdMapper implements MessageIdMapper {
     private static final Logger LOGGER = LoggerFactory.getLogger(CassandraMessageIdMapper.class);
@@ -67,26 +71,31 @@ public class CassandraMessageIdMapper implements MessageIdMapper {
     private final CassandraMailboxDAO mailboxDAO;
     private final CassandraMessageIdToImapUidDAO imapUidDAO;
     private final CassandraMessageIdDAO messageIdDAO;
-    private final CassandraMessageDAO messageDAO;
+    private final CassandraMessageDAOV2 messageDAOV2;
     private final CassandraIndexTableHandler indexTableHandler;
     private final ModSeqProvider modSeqProvider;
     private final MailboxSession mailboxSession;
     private final AttachmentLoader attachmentLoader;
+    private final V1ToV2Migration v1ToV2Migration;
     private final CassandraConfiguration cassandraConfiguration;
 
     public CassandraMessageIdMapper(MailboxMapper mailboxMapper, CassandraMailboxDAO mailboxDAO, CassandraAttachmentMapper attachmentMapper,
-                                    CassandraMessageIdToImapUidDAO imapUidDAO, CassandraMessageIdDAO messageIdDAO, CassandraMessageDAO messageDAO,
-                                    CassandraIndexTableHandler indexTableHandler, ModSeqProvider modSeqProvider, MailboxSession mailboxSession, CassandraConfiguration cassandraConfiguration) {
+                                    CassandraMessageIdToImapUidDAO imapUidDAO, CassandraMessageIdDAO messageIdDAO,
+                                    CassandraMessageDAO messageDAOV1, CassandraMessageDAOV2 messageDAOV2,
+                                    CassandraIndexTableHandler indexTableHandler, ModSeqProvider modSeqProvider, MailboxSession mailboxSession,
+                                    CassandraConfiguration cassandraConfiguration) {
+
         this.mailboxMapper = mailboxMapper;
         this.mailboxDAO = mailboxDAO;
         this.imapUidDAO = imapUidDAO;
         this.messageIdDAO = messageIdDAO;
-        this.messageDAO = messageDAO;
+        this.messageDAOV2 = messageDAOV2;
         this.indexTableHandler = indexTableHandler;
         this.modSeqProvider = modSeqProvider;
         this.mailboxSession = mailboxSession;
         this.attachmentLoader = new AttachmentLoader(attachmentMapper);
         this.cassandraConfiguration = cassandraConfiguration;
+        this.v1ToV2Migration = new V1ToV2Migration(messageDAOV1, messageDAOV2, attachmentMapper);
     }
 
     @Override
@@ -101,7 +110,7 @@ public class CassandraMessageIdMapper implements MessageIdMapper {
                 .map(messageId -> imapUidDAO.retrieve((CassandraMessageId) messageId, Optional.empty())))
             .thenApply(stream -> stream.flatMap(Function.identity()))
             .thenApply(stream -> stream.collect(Guavate.toImmutableList()))
-            .thenCompose(composedMessageIds -> messageDAO.retrieveMessages(composedMessageIds, fetchType, Optional.empty()))
+            .thenCompose(composedMessageIds -> retrieveMessages(fetchType, composedMessageIds))
             .thenCompose(stream -> CompletableFutureUtil.allOf(
                 stream.map(pair -> mailboxExists(pair.getLeft())
                     .thenApply(b -> Optional.of(pair).filter(any -> b)))))
@@ -113,6 +122,14 @@ public class CassandraMessageIdMapper implements MessageIdMapper {
             .sorted(Comparator.comparing(MailboxMessage::getUid));
     }
 
+    private CompletableFuture<Stream<Pair<MessageWithoutAttachment, Stream<MessageAttachmentRepresentation>>>>
+            retrieveMessages(FetchType fetchType, ImmutableList<ComposedMessageIdWithMetaData> composedMessageIds) {
+        return messageDAOV2.retrieveMessages(composedMessageIds, fetchType, Limit.unlimited())
+                .thenCompose(messageResults -> FluentFutureStream.of(messageResults
+                        .map(v1ToV2Migration::moveFromV1toV2))
+                        .completableFuture());
+    }
+
     private CompletableFuture<Boolean> mailboxExists(MessageWithoutAttachment messageWithoutAttachment) {
         CassandraId cassandraId = (CassandraId) messageWithoutAttachment.getMailboxId();
         return mailboxDAO.retrieveMailbox(cassandraId)
@@ -163,7 +180,7 @@ public class CassandraMessageIdMapper implements MessageIdMapper {
             .flags(mailboxMessage.createFlags())
             .modSeq(mailboxMessage.getModSeq())
             .build();
-        messageDAO.save(mailboxMessage)
+        messageDAOV2.save(mailboxMessage)
             .thenCompose(voidValue -> CompletableFuture.allOf(
                 imapUidDAO.insert(composedMessageIdWithMetaData),
                 messageIdDAO.insert(composedMessageIdWithMetaData)))
@@ -194,7 +211,6 @@ public class CassandraMessageIdMapper implements MessageIdMapper {
     public void delete(MessageId messageId) {
         CassandraMessageId cassandraMessageId = (CassandraMessageId) messageId;
         retrieveAndDeleteIndices(cassandraMessageId, Optional.empty())
-            .thenCompose(voidValue -> messageDAO.delete(cassandraMessageId))
             .join();
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
index 55bf43d..6d716b7 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
@@ -39,6 +39,8 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.cassandra.CassandraId;
 import org.apache.james.mailbox.cassandra.CassandraMessageId;
+import org.apache.james.mailbox.cassandra.Limit;
+import org.apache.james.mailbox.cassandra.mail.migration.V1ToV2Migration;
 import org.apache.james.mailbox.cassandra.mail.utils.FlagsUpdateStageResult;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.ComposedMessageId;
@@ -73,7 +75,7 @@ public class CassandraMessageMapper implements MessageMapper {
     private final CassandraModSeqProvider modSeqProvider;
     private final MailboxSession mailboxSession;
     private final CassandraUidProvider uidProvider;
-    private final CassandraMessageDAO messageDAO;
+    private final CassandraMessageDAOV2 messageDAOV2;
     private final CassandraMessageIdDAO messageIdDAO;
     private final CassandraMessageIdToImapUidDAO imapUidDAO;
     private final CassandraMailboxCounterDAO mailboxCounterDAO;
@@ -83,17 +85,21 @@ public class CassandraMessageMapper implements MessageMapper {
     private final CassandraFirstUnseenDAO firstUnseenDAO;
     private final AttachmentLoader attachmentLoader;
     private final CassandraDeletedMessageDAO deletedMessageDAO;
+    private final V1ToV2Migration v1ToV2Migration;
     private final CassandraConfiguration cassandraConfiguration;
 
+
+
     public CassandraMessageMapper(CassandraUidProvider uidProvider, CassandraModSeqProvider modSeqProvider,
                                   MailboxSession mailboxSession, CassandraAttachmentMapper attachmentMapper,
-                                  CassandraMessageDAO messageDAO, CassandraMessageIdDAO messageIdDAO, CassandraMessageIdToImapUidDAO imapUidDAO,
+                                  CassandraMessageDAO messageDAO, CassandraMessageDAOV2 messageDAOV2,
+                                  CassandraMessageIdDAO messageIdDAO, CassandraMessageIdToImapUidDAO imapUidDAO,
                                   CassandraMailboxCounterDAO mailboxCounterDAO, CassandraMailboxRecentsDAO mailboxRecentDAO, CassandraApplicableFlagDAO applicableFlagDAO,
                                   CassandraIndexTableHandler indexTableHandler, CassandraFirstUnseenDAO firstUnseenDAO, CassandraDeletedMessageDAO deletedMessageDAO, CassandraConfiguration cassandraConfiguration) {
         this.uidProvider = uidProvider;
         this.modSeqProvider = modSeqProvider;
         this.mailboxSession = mailboxSession;
-        this.messageDAO = messageDAO;
+        this.messageDAOV2 = messageDAOV2;
         this.messageIdDAO = messageIdDAO;
         this.imapUidDAO = imapUidDAO;
         this.mailboxCounterDAO = mailboxCounterDAO;
@@ -103,6 +109,7 @@ public class CassandraMessageMapper implements MessageMapper {
         this.attachmentLoader = new AttachmentLoader(attachmentMapper);
         this.applicableFlagDAO = applicableFlagDAO;
         this.deletedMessageDAO = deletedMessageDAO;
+        this.v1ToV2Migration = new V1ToV2Migration(messageDAO, messageDAOV2, attachmentMapper);
         this.cassandraConfiguration = cassandraConfiguration;
     }
 
@@ -169,7 +176,7 @@ public class CassandraMessageMapper implements MessageMapper {
     @Override
     public Iterator<MailboxMessage> findInMailbox(Mailbox mailbox, MessageRange messageRange, FetchType ftype, int max) throws MailboxException {
         CassandraId mailboxId = (CassandraId) mailbox.getMailboxId();
-        return retrieveMessages(retrieveMessageIds(mailboxId, messageRange), ftype, Optional.of(max))
+        return retrieveMessages(retrieveMessageIds(mailboxId, messageRange), ftype, Limit.from(max))
                 .join()
                 .map(SimpleMailboxMessage -> (MailboxMessage) SimpleMailboxMessage)
                 .sorted(Comparator.comparing(MailboxMessage::getUid))
@@ -182,21 +189,12 @@ public class CassandraMessageMapper implements MessageMapper {
                 .collect(Guavate.toImmutableList());
     }
 
-    private CompletableFuture<Stream<SimpleMailboxMessage>> retrieveMessages(List<ComposedMessageIdWithMetaData> messageIds, FetchType fetchType, Optional<Integer> limit) {
-        CompletableFuture<Stream<Pair<CassandraMessageDAO.MessageWithoutAttachment, Stream<CassandraMessageDAO.MessageAttachmentRepresentation>>>>
-            messageRepresentations = messageDAO.retrieveMessages(messageIds, fetchType, limit);
+    private CompletableFuture<Stream<SimpleMailboxMessage>> retrieveMessages(List<ComposedMessageIdWithMetaData> messageIds, FetchType fetchType, Limit limit) {
+        CompletableFuture<Stream<Pair<MessageWithoutAttachment, Stream<MessageAttachmentRepresentation>>>>
+            messageRepresentations = retrieveMessagesAndDoMigrationIfNeeded(messageIds, fetchType, limit);
+
         if (fetchType == FetchType.Body || fetchType == FetchType.Full) {
-            return FluentFutureStream.of(messageRepresentations)
-                .thenComposeOnAll(pair ->
-                    attachmentLoader.getAttachments(pair.getRight().collect(Guavate.toImmutableList()))
-                        .thenApply(attachments -> Pair.of(pair.getLeft(), attachments))
-                )
-                .map(pair ->
-                    pair.getLeft()
-                        .toMailboxMessage(pair.getRight()
-                            .stream()
-                            .collect(Guavate.toImmutableList())))
-                .completableFuture();
+            return attachmentLoader.toMailboxMessageWithAttachments(messageRepresentations);
         } else {
             return FluentFutureStream.of(messageRepresentations)
                 .map(pair ->
@@ -207,6 +205,8 @@ public class CassandraMessageMapper implements MessageMapper {
         }
     }
 
+
+
     @Override
     public List<MessageUid> findRecentMessageUidsInMailbox(Mailbox mailbox) throws MailboxException {
         CassandraId mailboxId = (CassandraId) mailbox.getMailboxId();
@@ -240,12 +240,20 @@ public class CassandraMessageMapper implements MessageMapper {
             .map(uid -> messageIdDAO.retrieve(mailboxId, uid)))
             .flatMap(OptionalConverter::toStream)
             .performOnAll(this::deleteUsingMailboxId)
-            .thenComposeOnAll(idWithMetadata -> messageDAO.retrieveMessages(ImmutableList.of(idWithMetadata), FetchType.Metadata, Optional.empty()))
+            .thenComposeOnAll(idWithMetadata -> retrieveMessagesAndDoMigrationIfNeeded(ImmutableList.of(idWithMetadata), FetchType.Metadata, Limit.unlimited()))
             .flatMap(s -> s)
             .map(pair -> pair.getKey().toMailboxMessage(ImmutableList.of()))
             .completableFuture();
     }
 
+    private CompletableFuture<Stream<Pair<MessageWithoutAttachment, Stream<MessageAttachmentRepresentation>>>> retrieveMessagesAndDoMigrationIfNeeded(
+            List<ComposedMessageIdWithMetaData> messageIds, FetchType fetchType, Limit limit) {
+        return messageDAOV2.retrieveMessages(messageIds, fetchType, limit)
+                .thenCompose(messageResults -> FluentFutureStream.of(messageResults
+                        .map(v1ToV2Migration::moveFromV1toV2))
+                        .completableFuture());
+    }
+
     @Override
     public MessageMetaData move(Mailbox destinationMailbox, MailboxMessage original) throws MailboxException {
         CassandraId originalMailboxId = (CassandraId) original.getMailboxId();
@@ -377,7 +385,7 @@ public class CassandraMessageMapper implements MessageMapper {
 
     private CompletableFuture<Void> save(Mailbox mailbox, MailboxMessage message) throws MailboxException {
         CassandraId mailboxId = (CassandraId) mailbox.getMailboxId();
-        return messageDAO.save(message)
+        return messageDAOV2.save(message)
             .thenCompose(aVoid -> insertIds(message, mailboxId));
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/MessageWithoutAttachment.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/MessageWithoutAttachment.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/MessageWithoutAttachment.java
index e5bca7b..1c63cee 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/MessageWithoutAttachment.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/MessageWithoutAttachment.java
@@ -25,6 +25,8 @@ import javax.mail.Flags;
 import javax.mail.util.SharedByteArrayInputStream;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.model.ComposedMessageId;
+import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
@@ -73,7 +75,15 @@ public class MessageWithoutAttachment {
         return messageId;
     }
 
+    public ComposedMessageIdWithMetaData getMetadata() {
+        return new ComposedMessageIdWithMetaData(new ComposedMessageId(mailboxId, messageId, messageUid), flags, modSeq);
+    }
+
     public SharedByteArrayInputStream getContent() {
         return content;
     }
+
+    public PropertyBuilder getPropertyBuilder() {
+        return propertyBuilder;
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/V1ToV2Migration.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/V1ToV2Migration.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/V1ToV2Migration.java
new file mode 100644
index 0000000..6ae6e4f
--- /dev/null
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/V1ToV2Migration.java
@@ -0,0 +1,90 @@
+/****************************************************************
+ * 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 java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.stream.Stream;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.james.mailbox.cassandra.CassandraMessageId;
+import org.apache.james.mailbox.cassandra.Limit;
+import org.apache.james.mailbox.cassandra.mail.AttachmentLoader;
+import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentMapper;
+import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAOV2;
+import org.apache.james.mailbox.cassandra.mail.MessageAttachmentRepresentation;
+import org.apache.james.mailbox.cassandra.mail.MessageWithoutAttachment;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
+import org.apache.james.mailbox.store.mail.MessageMapper;
+import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
+
+import com.google.common.collect.ImmutableList;
+
+public class V1ToV2Migration {
+    private final CassandraMessageDAO messageDAOV1;
+    private final CassandraMessageDAOV2 messageDAOV2;
+    private final AttachmentLoader attachmentLoader;
+
+    public V1ToV2Migration(CassandraMessageDAO messageDAOV1, CassandraMessageDAOV2 messageDAOV2, CassandraAttachmentMapper attachmentMapper) {
+        this.messageDAOV1 = messageDAOV1;
+        this.messageDAOV2 = messageDAOV2;
+        this.attachmentLoader = new AttachmentLoader(attachmentMapper);
+    }
+
+    public CompletableFuture<Pair<MessageWithoutAttachment, Stream<MessageAttachmentRepresentation>>>
+            moveFromV1toV2(CassandraMessageDAOV2.MessageResult result) {
+
+        if (result.isFound()) {
+            return CompletableFuture.completedFuture(result.message());
+        }
+
+        return messageDAOV1.retrieveMessages(ImmutableList.of(result.getMetadata()), MessageMapper.FetchType.Full, Limit.unlimited())
+            .thenApply(results -> results.findAny()
+                .orElseThrow(() -> new IllegalArgumentException("Message not found in DAO V1" + result.getMetadata())))
+            .thenCompose(this::performV1ToV2Migration);
+    }
+
+    private CompletableFuture<Pair<MessageWithoutAttachment, Stream<MessageAttachmentRepresentation>>> performV1ToV2Migration(Pair<MessageWithoutAttachment, Stream<MessageAttachmentRepresentation>> messageV1) {
+        return attachmentLoader.toMailboxMessageWithAttachments(
+            CompletableFuture.completedFuture(Stream.of(messageV1)))
+            .thenApply(stream -> stream.findAny().get())
+            .thenCompose(this::saveInV2FromV1)
+            .thenCompose(this::deleteInV1)
+            .thenApply(any -> messageV1);
+    }
+
+    private CompletableFuture<Void> deleteInV1(Optional<SimpleMailboxMessage> optional) {
+        return optional.map(SimpleMailboxMessage::getMessageId)
+            .map(messageId -> (CassandraMessageId) messageId)
+            .map(messageDAOV1::delete)
+            .orElse(CompletableFuture.completedFuture(null));
+    }
+
+    private CompletionStage<Optional<SimpleMailboxMessage>> saveInV2FromV1(SimpleMailboxMessage message) {
+        try {
+            return messageDAOV2.save(message).thenApply(any -> Optional.of(message));
+        } catch (MailboxException e) {
+            return CompletableFuture.completedFuture(Optional.<SimpleMailboxMessage>empty());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraMessageModule.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraMessageModule.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraMessageModule.java
index 3a55d6f..db1bc58 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraMessageModule.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraMessageModule.java
@@ -112,8 +112,8 @@ public class CassandraMessageModule implements CassandraModule {
                     .addColumn(CassandraMessageV2Table.BODY_OCTECTS, bigint())
                     .addColumn(CassandraMessageV2Table.TEXTUAL_LINE_COUNT, bigint())
                     .addColumn(CassandraMessageV2Table.FULL_CONTENT_OCTETS, bigint())
-                    .addColumn(CassandraMessageV2Table.BODY_CONTENT, timeuuid())
-                    .addColumn(CassandraMessageV2Table.HEADER_CONTENT, timeuuid())
+                    .addColumn(CassandraMessageV2Table.BODY_CONTENT, text())
+                    .addColumn(CassandraMessageV2Table.HEADER_CONTENT, text())
                     .addUDTListColumn(CassandraMessageV2Table.ATTACHMENTS, SchemaBuilder.frozen(CassandraMessageV2Table.ATTACHMENTS))
                     .addUDTListColumn(CassandraMessageV2Table.PROPERTIES, SchemaBuilder.frozen(CassandraMessageV2Table.PROPERTIES))));
         types = ImmutableList.of(

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerProvider.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerProvider.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerProvider.java
index c34effb..7f02c9c 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerProvider.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerProvider.java
@@ -25,6 +25,7 @@ import org.apache.james.mailbox.acl.MailboxACLResolver;
 import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
 import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
 import org.apache.james.mailbox.cassandra.mail.CassandraApplicableFlagDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraBlobsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraDeletedMessageDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraFirstUnseenDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxCounterDAO;
@@ -32,6 +33,7 @@ import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxRecentsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAOV2;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraModSeqProvider;
@@ -55,7 +57,9 @@ public class CassandraMailboxManagerProvider {
         CassandraMessageId.Factory messageIdFactory = new CassandraMessageId.Factory();
         CassandraMessageIdDAO messageIdDAO = new CassandraMessageIdDAO(session, messageIdFactory);
         CassandraMessageIdToImapUidDAO imapUidDAO = new CassandraMessageIdToImapUidDAO(session, messageIdFactory);
+        CassandraBlobsDAO blobsDAO = new CassandraBlobsDAO(session);
         CassandraMessageDAO messageDAO = new CassandraMessageDAO(session, cassandraTypesProvider);
+        CassandraMessageDAOV2 messageDAOV2 = new CassandraMessageDAOV2(session, cassandraTypesProvider, blobsDAO);
         CassandraMailboxCounterDAO mailboxCounterDAO = new CassandraMailboxCounterDAO(session);
         CassandraMailboxRecentsDAO mailboxRecentsDAO = new CassandraMailboxRecentsDAO(session);
         CassandraMailboxDAO mailboxDAO = new CassandraMailboxDAO(session, cassandraTypesProvider);
@@ -68,6 +72,7 @@ public class CassandraMailboxManagerProvider {
             modSeqProvider,
             session,
             messageDAO,
+            messageDAOV2,
             messageIdDAO,
             imapUidDAO,
             mailboxCounterDAO,

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerStressTest.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerStressTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerStressTest.java
index 5ba536a..93ec3c9 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerStressTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerStressTest.java
@@ -27,6 +27,7 @@ import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraAnnotationModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraApplicableFlagsModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
+import org.apache.james.mailbox.cassandra.modules.CassandraBlobModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraDeletedMessageModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraFirstUnseenModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraMailboxCounterModule;
@@ -45,6 +46,7 @@ public class CassandraMailboxManagerStressTest extends MailboxManagerStressTest
         new CassandraAclModule(),
         new CassandraMailboxModule(),
         new CassandraMessageModule(),
+        new CassandraBlobModule(),
         new CassandraMailboxCounterModule(),
         new CassandraMailboxRecentsModule(),
         new CassandraFirstUnseenModule(),

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
index 271c163..9bc0934 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
@@ -26,6 +26,7 @@ import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraAnnotationModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraApplicableFlagsModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
+import org.apache.james.mailbox.cassandra.modules.CassandraBlobModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraDeletedMessageModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraFirstUnseenModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraMailboxCounterModule;
@@ -50,6 +51,7 @@ public class CassandraMailboxManagerTest extends MailboxManagerTest {
                     new CassandraAclModule(),
                     new CassandraMailboxModule(),
                     new CassandraMessageModule(),
+                    new CassandraBlobModule(),
                     new CassandraMailboxCounterModule(),
                     new CassandraMailboxRecentsModule(),
                     new CassandraFirstUnseenModule(),

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/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 0ae1dd6..c2c89bf 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
@@ -31,6 +31,7 @@ import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxRecentsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAOV2;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraModSeqProvider;
@@ -68,6 +69,7 @@ public class CassandraSubscriptionManagerTest extends AbstractSubscriptionManage
     public SubscriptionManager createSubscriptionManager() {
         CassandraMessageIdToImapUidDAO imapUidDAO = null;
         CassandraMessageDAO messageDAO = null;
+        CassandraMessageDAOV2 messageDAOV2 = null;
         CassandraMessageIdDAO messageIdDAO = null;
         CassandraMailboxCounterDAO mailboxCounterDAO = null;
         CassandraMailboxRecentsDAO mailboxRecentsDAO = null;
@@ -82,6 +84,7 @@ public class CassandraSubscriptionManagerTest extends AbstractSubscriptionManage
                 new CassandraModSeqProvider(cassandra.getConf()),
                 cassandra.getConf(),
                 messageDAO,
+                messageDAOV2,
                 messageIdDAO,
                 imapUidDAO,
                 mailboxCounterDAO,

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraTestSystemFixture.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraTestSystemFixture.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraTestSystemFixture.java
index a58b348..ea41086 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraTestSystemFixture.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraTestSystemFixture.java
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.mock;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.init.CassandraModuleComposite;
+import org.apache.james.mailbox.cassandra.mail.CassandraBlobsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraDeletedMessageDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraFirstUnseenDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraApplicableFlagDAO;
@@ -31,6 +32,7 @@ import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxRecentsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAOV2;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraModSeqProvider;
@@ -39,6 +41,7 @@ import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraAnnotationModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraApplicableFlagsModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
+import org.apache.james.mailbox.cassandra.modules.CassandraBlobModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraDeletedMessageModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraFirstUnseenModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraMailboxCounterModule;
@@ -68,7 +71,9 @@ public class CassandraTestSystemFixture {
         CassandraMessageId.Factory messageIdFactory = new CassandraMessageId.Factory();
         CassandraMessageIdDAO messageIdDAO = new CassandraMessageIdDAO(cassandra.getConf(), messageIdFactory);
         CassandraMessageIdToImapUidDAO imapUidDAO = new CassandraMessageIdToImapUidDAO(cassandra.getConf(), messageIdFactory);
+        CassandraBlobsDAO blobsDAO = new CassandraBlobsDAO(cassandra.getConf());
         CassandraMessageDAO messageDAO = new CassandraMessageDAO(cassandra.getConf(), cassandra.getTypesProvider());
+        CassandraMessageDAOV2 messageDAOV2 = new CassandraMessageDAOV2(cassandra.getConf(), cassandra.getTypesProvider(), blobsDAO);
         CassandraMailboxCounterDAO mailboxCounterDAO = new CassandraMailboxCounterDAO(cassandra.getConf());
         CassandraMailboxRecentsDAO mailboxRecentsDAO = new CassandraMailboxRecentsDAO(cassandra.getConf());
         CassandraApplicableFlagDAO applicableFlagDAO = new CassandraApplicableFlagDAO(cassandra.getConf());
@@ -81,6 +86,7 @@ public class CassandraTestSystemFixture {
             modSeqProvider,
             cassandra.getConf(),
             messageDAO,
+            messageDAOV2,
             messageIdDAO,
             imapUidDAO,
             mailboxCounterDAO,
@@ -118,6 +124,7 @@ public class CassandraTestSystemFixture {
                     new CassandraAclModule(),
                     new CassandraMailboxModule(),
                     new CassandraMessageModule(),
+                    new CassandraBlobModule(),
                     new CassandraMailboxCounterModule(),
                     new CassandraMailboxRecentsModule(),
                     new CassandraFirstUnseenModule(),

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/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 722e7f7..d7c5097 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
@@ -31,6 +31,7 @@ import org.apache.james.mailbox.cassandra.CassandraMessageId;
 import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraApplicableFlagsModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
+import org.apache.james.mailbox.cassandra.modules.CassandraBlobModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraDeletedMessageModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraFirstUnseenModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraMailboxCounterModule;
@@ -59,6 +60,7 @@ public class CassandraMailboxManagerAttachmentTest extends AbstractMailboxManage
                     new CassandraAclModule(),
                     new CassandraMailboxModule(),
                     new CassandraMessageModule(),
+                    new CassandraBlobModule(),
                     new CassandraMailboxCounterModule(),
                     new CassandraMailboxRecentsModule(),
                     new CassandraFirstUnseenModule(),
@@ -85,11 +87,16 @@ public class CassandraMailboxManagerAttachmentTest extends AbstractMailboxManage
         CassandraMailboxPathDAO mailboxPathDAO = new CassandraMailboxPathDAO(cassandra.getConf(), cassandra.getTypesProvider());
         CassandraFirstUnseenDAO firstUnseenDAO = new CassandraFirstUnseenDAO(cassandra.getConf());
         CassandraDeletedMessageDAO deletedMessageDAO = new CassandraDeletedMessageDAO(cassandra.getConf());
+
+        CassandraBlobsDAO blobsDAO = new CassandraBlobsDAO(cassandra.getConf());
+        CassandraMessageDAO messageDAO = new CassandraMessageDAO(cassandra.getConf(), cassandra.getTypesProvider());
+        CassandraMessageDAOV2 messageDAOV2 = new CassandraMessageDAOV2(cassandra.getConf(), cassandra.getTypesProvider(), blobsDAO);
         mailboxSessionMapperFactory = new CassandraMailboxSessionMapperFactory(
                 new CassandraUidProvider(cassandra.getConf()),
                 new CassandraModSeqProvider(cassandra.getConf()),
                 cassandra.getConf(),
-                new CassandraMessageDAO(cassandra.getConf(), cassandra.getTypesProvider()),
+                messageDAO,
+                messageDAOV2,
                 new CassandraMessageIdDAO(cassandra.getConf(), messageIdFactory),
                 new CassandraMessageIdToImapUidDAO(cassandra.getConf(), messageIdFactory),
                 new CassandraMailboxCounterDAO(cassandra.getConf()),

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/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 74602f3..4357abe 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
@@ -32,6 +32,7 @@ import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraAnnotationModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraApplicableFlagsModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
+import org.apache.james.mailbox.cassandra.modules.CassandraBlobModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraDeletedMessageModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraFirstUnseenModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraMailboxCounterModule;
@@ -79,7 +80,8 @@ public class CassandraMapperProvider implements MapperProvider {
                     new CassandraAnnotationModule(),
                     new CassandraFirstUnseenModule(),
                     new CassandraApplicableFlagsModule(),
-                    new CassandraDeletedMessageModule()));
+                    new CassandraDeletedMessageModule(),
+                    new CassandraBlobModule()));
         messageUidProvider = new MessageUidProvider();
         cassandraModSeqProvider = new CassandraModSeqProvider(this.cassandra.getConf());
     }
@@ -109,11 +111,15 @@ public class CassandraMapperProvider implements MapperProvider {
         CassandraMailboxPathDAO mailboxPathDAO = new CassandraMailboxPathDAO(cassandra.getConf(), cassandra.getTypesProvider());
         CassandraFirstUnseenDAO firstUnseenDAO = new CassandraFirstUnseenDAO(cassandra.getConf());
         CassandraDeletedMessageDAO deletedMessageDAO = new CassandraDeletedMessageDAO(cassandra.getConf());
+        CassandraBlobsDAO blobsDAO = new CassandraBlobsDAO(cassandra.getConf());
+        CassandraMessageDAO messageDAO = new CassandraMessageDAO(cassandra.getConf(), cassandra.getTypesProvider());
+        CassandraMessageDAOV2 messageDAOV2 = new CassandraMessageDAOV2(cassandra.getConf(), cassandra.getTypesProvider(), blobsDAO);
         return new CassandraMailboxSessionMapperFactory(
             new CassandraUidProvider(cassandra.getConf()),
             cassandraModSeqProvider,
             cassandra.getConf(),
-            new CassandraMessageDAO(cassandra.getConf(), cassandra.getTypesProvider()),
+            messageDAO,
+            messageDAOV2,
             new CassandraMessageIdDAO(cassandra.getConf(), MESSAGE_ID_FACTORY),
             new CassandraMessageIdToImapUidDAO(cassandra.getConf(), MESSAGE_ID_FACTORY),
             new CassandraMailboxCounterDAO(cassandra.getConf()),

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAOTest.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAOTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAOTest.java
index 3f69d26..2ba82cc 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAOTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAOTest.java
@@ -29,6 +29,7 @@ import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.cassandra.CassandraId;
 import org.apache.james.mailbox.cassandra.CassandraMessageId;
+import org.apache.james.mailbox.cassandra.Limit;
 import org.apache.james.mailbox.cassandra.modules.CassandraMessageModule;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
@@ -106,7 +107,8 @@ public class CassandraMessageDAOTest {
 
         testee.save(messageWith1Attachment).join();
 
-        List<Optional<MessageAttachmentRepresentation>> attachmentRepresentation = testee.retrieveMessages(messageIds, MessageMapper.FetchType.Body, Optional.empty())
+        List<Optional<MessageAttachmentRepresentation>> attachmentRepresentation =
+            testee.retrieveMessages(messageIds, MessageMapper.FetchType.Body, Limit.unlimited())
                 .get()
                 .map(pair -> pair.getRight())
                 .map(streamAttachemnt -> streamAttachemnt.findFirst())
@@ -128,7 +130,8 @@ public class CassandraMessageDAOTest {
 
         testee.save(messageWith1Attachment).join();
 
-        List<Optional<MessageAttachmentRepresentation>> attachmentRepresentation = testee.retrieveMessages(messageIds, MessageMapper.FetchType.Body, Optional.empty())
+        List<Optional<MessageAttachmentRepresentation>> attachmentRepresentation =
+            testee.retrieveMessages(messageIds, MessageMapper.FetchType.Body, Limit.unlimited())
                 .get()
                 .map(pair -> pair.getRight())
                 .map(streamAttachemnt -> streamAttachemnt.findFirst())
@@ -138,8 +141,23 @@ public class CassandraMessageDAOTest {
         assertThat(attachmentRepresentation.get(0).get().getCid().isPresent()).isFalse();
     }
 
-    private SimpleMailboxMessage createMessage(MessageId messageId, String content, int bodyStart, PropertyBuilder propertyBuilder, List<MessageAttachment> attachments) {
-        return new SimpleMailboxMessage(messageId, new Date(), content.length(), bodyStart, new SharedByteArrayInputStream(content.getBytes()), new Flags(), propertyBuilder, MAILBOX_ID, attachments);
+    private SimpleMailboxMessage createMessage(
+        MessageId messageId,
+        String content,
+        int bodyStart,
+        PropertyBuilder propertyBuilder,
+        List<MessageAttachment> attachments
+    ) {
+        return new SimpleMailboxMessage(
+            messageId,
+            new Date(),
+            content.length(),
+            bodyStart,
+            new SharedByteArrayInputStream(content.getBytes()),
+            new Flags(),
+            propertyBuilder,
+            MAILBOX_ID,
+            attachments);
     }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/V1ToV2MigrationTest.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/V1ToV2MigrationTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/V1ToV2MigrationTest.java
new file mode 100644
index 0000000..c1c505d
--- /dev/null
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/V1ToV2MigrationTest.java
@@ -0,0 +1,185 @@
+/****************************************************************
+ * 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 java.util.Date;
+import java.util.List;
+import java.util.Optional;
+
+import javax.mail.Flags;
+import javax.mail.util.SharedByteArrayInputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.backends.cassandra.init.CassandraModuleComposite;
+import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.cassandra.CassandraId;
+import org.apache.james.mailbox.cassandra.CassandraMessageId;
+import org.apache.james.mailbox.cassandra.Limit;
+import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentMapper;
+import org.apache.james.mailbox.cassandra.mail.CassandraBlobsDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAOV2;
+import org.apache.james.mailbox.cassandra.mail.MessageAttachmentRepresentation;
+import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
+import org.apache.james.mailbox.cassandra.modules.CassandraBlobModule;
+import org.apache.james.mailbox.cassandra.modules.CassandraMessageModule;
+import org.apache.james.mailbox.model.Attachment;
+import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.Cid;
+import org.apache.james.mailbox.model.ComposedMessageId;
+import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
+import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.store.mail.MessageMapper;
+import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
+import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
+import org.apache.james.util.OptionalConverter;
+import org.assertj.core.api.JUnitSoftAssertions;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableList;
+
+public class V1ToV2MigrationTest {
+    private static final int BODY_START = 16;
+    private static final CassandraId MAILBOX_ID = CassandraId.timeBased();
+    private static final String CONTENT = "Subject: Test7 \n\nBody7\n.\n";
+    private static final MessageUid messageUid = MessageUid.of(1);
+
+    private CassandraCluster cassandra;
+
+    private CassandraMessageDAO messageDAOV1;
+    private CassandraMessageDAOV2 messageDAOV2;
+    private CassandraAttachmentMapper attachmentMapper;
+    private V1ToV2Migration testee;
+
+    private Attachment attachment;
+    private CassandraMessageId messageId;
+    private CassandraMessageId.Factory messageIdFactory;
+    private ComposedMessageId composedMessageId;
+    private List<ComposedMessageIdWithMetaData> metaDataList;
+    private ComposedMessageIdWithMetaData metaData;
+    private MessageAttachment messageAttachment;
+    
+    @Rule
+    public final JUnitSoftAssertions softly = new JUnitSoftAssertions();
+
+    @Before
+    public void setUp() {
+        cassandra = CassandraCluster.create(new CassandraModuleComposite(
+            new CassandraMessageModule(),
+            new CassandraBlobModule(),
+            new CassandraAttachmentModule()));
+        cassandra.ensureAllTables();
+
+        messageDAOV1 = new CassandraMessageDAO(cassandra.getConf(), cassandra.getTypesProvider());
+        CassandraBlobsDAO blobsDAO = new CassandraBlobsDAO(cassandra.getConf());
+        messageDAOV2 = new CassandraMessageDAOV2(cassandra.getConf(), cassandra.getTypesProvider(), blobsDAO);
+        attachmentMapper = new CassandraAttachmentMapper(cassandra.getConf());
+        testee = new V1ToV2Migration(messageDAOV1, messageDAOV2, attachmentMapper);
+
+
+        messageIdFactory = new CassandraMessageId.Factory();
+        messageId = messageIdFactory.generate();
+
+        attachment = Attachment.builder()
+                .attachmentId(AttachmentId.from("123"))
+                .bytes("attachment".getBytes())
+                .type("content")
+                .build();
+
+        composedMessageId = new ComposedMessageId(MAILBOX_ID, messageId, messageUid);
+
+        metaData = ComposedMessageIdWithMetaData.builder()
+            .composedMessageId(composedMessageId)
+            .flags(new Flags())
+            .modSeq(1)
+            .build();
+        metaDataList = ImmutableList.of(metaData);
+        messageAttachment = MessageAttachment.builder()
+            .attachment(attachment)
+            .cid(Cid.from("<cid>"))
+            .isInline(true)
+            .name("toto.png")
+            .build();
+    }
+
+    @After
+    public void tearDown() {
+        cassandra.clearAllTables();
+        cassandra.close();
+    }
+
+    @Test
+    public void migrationShouldWorkWithoutAttachments() throws Exception {
+        SimpleMailboxMessage originalMessage = createMessage(messageId, CONTENT, BODY_START,
+            new PropertyBuilder(), ImmutableList.of());
+        messageDAOV1.save(originalMessage).join();
+
+        testee.moveFromV1toV2(CassandraMessageDAOV2.notFound(metaData)).join();
+
+        Optional<CassandraMessageDAOV2.MessageResult> messageResult = messageDAOV2.retrieveMessages(metaDataList, MessageMapper.FetchType.Full, Limit.unlimited())
+            .join()
+            .findAny();
+
+        assertThat(messageResult.isPresent()).isTrue();
+        softly.assertThat(messageResult.get().message().getLeft().getMessageId()).isEqualTo(messageId);
+        softly.assertThat(IOUtils.toString(messageResult.get().message().getLeft().getContent(), Charsets.UTF_8))
+            .isEqualTo(CONTENT);
+        softly.assertThat(messageResult.get().message().getRight().findAny().isPresent()).isFalse();
+    }
+
+    @Test
+    public void migrationShouldWorkWithAttachments() throws Exception {
+        SimpleMailboxMessage originalMessage = createMessage(messageId, CONTENT, BODY_START,
+            new PropertyBuilder(), ImmutableList.of(messageAttachment));
+
+        attachmentMapper.storeAttachment(attachment);
+
+        messageDAOV1.save(originalMessage).join();
+
+        testee.moveFromV1toV2(CassandraMessageDAOV2.notFound(metaData)).join();
+
+        Optional<CassandraMessageDAOV2.MessageResult> messageResult = messageDAOV2.retrieveMessages(metaDataList, MessageMapper.FetchType.Full, Limit.unlimited())
+            .join()
+            .findAny();
+
+        assertThat(messageResult.isPresent()).isTrue();
+        softly.assertThat(messageResult.get().message().getLeft().getMessageId()).isEqualTo(messageId);
+        softly.assertThat(IOUtils.toString(messageResult.get().message().getLeft().getContent(), Charsets.UTF_8))
+            .isEqualTo(CONTENT);
+        softly.assertThat(messageResult.get().message().getRight().findAny().get()).isEqualTo(MessageAttachmentRepresentation.builder()
+            .attachmentId(attachment.getAttachmentId())
+            .cid(OptionalConverter.fromGuava(messageAttachment.getCid()))
+            .isInline(messageAttachment.isInline())
+            .name(messageAttachment.getName().get())
+            .build());
+    }
+
+    private SimpleMailboxMessage createMessage(MessageId messageId, String content, int bodyStart, PropertyBuilder propertyBuilder, List<MessageAttachment> attachments) {
+        return new SimpleMailboxMessage(messageId, new Date(), content.length(), bodyStart, new SharedByteArrayInputStream(content.getBytes()), new Flags(), propertyBuilder, MAILBOX_ID, attachments);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java
index 6e9e1b5..215a846 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java
@@ -286,6 +286,15 @@ public abstract class MessageMapperTest {
     }
 
     @Test
+    public void messagesRetrievedUsingFetchTypeFullShouldHaveBodyDataLoaded() throws MailboxException, IOException{
+        saveMessages();
+        MessageMapper.FetchType fetchType = FetchType.Full;
+        Iterator<MailboxMessage> retrievedMessageIterator = messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(message1.getUid()), fetchType, LIMIT);
+        assertThat(retrievedMessageIterator.next()).isEqualToWithoutAttachment(message1, fetchType);
+        assertThat(retrievedMessageIterator).isEmpty();
+    }
+
+    @Test
     public void retrievingMessagesWithALimitShouldLimitTheNumberOfMessages() throws MailboxException {
         int limit = 2;
         saveMessages();

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/mpt/impl/imap-mailbox/cassandra/src/test/java/org/apache/james/mpt/imapmailbox/cassandra/host/CassandraHostSystem.java
----------------------------------------------------------------------
diff --git a/mpt/impl/imap-mailbox/cassandra/src/test/java/org/apache/james/mpt/imapmailbox/cassandra/host/CassandraHostSystem.java b/mpt/impl/imap-mailbox/cassandra/src/test/java/org/apache/james/mpt/imapmailbox/cassandra/host/CassandraHostSystem.java
index 9a9077a..d191bb1 100644
--- a/mpt/impl/imap-mailbox/cassandra/src/test/java/org/apache/james/mpt/imapmailbox/cassandra/host/CassandraHostSystem.java
+++ b/mpt/impl/imap-mailbox/cassandra/src/test/java/org/apache/james/mpt/imapmailbox/cassandra/host/CassandraHostSystem.java
@@ -29,6 +29,7 @@ import org.apache.james.mailbox.SubscriptionManager;
 import org.apache.james.mailbox.cassandra.CassandraMailboxManager;
 import org.apache.james.mailbox.cassandra.CassandraMailboxSessionMapperFactory;
 import org.apache.james.mailbox.cassandra.CassandraMessageId;
+import org.apache.james.mailbox.cassandra.mail.CassandraBlobsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraDeletedMessageDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraFirstUnseenDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraApplicableFlagDAO;
@@ -37,6 +38,7 @@ import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxRecentsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAOV2;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraModSeqProvider;
@@ -45,6 +47,7 @@ import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraAnnotationModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraApplicableFlagsModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
+import org.apache.james.mailbox.cassandra.modules.CassandraBlobModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraDeletedMessageModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraFirstUnseenModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraMailboxCounterModule;
@@ -89,6 +92,7 @@ public class CassandraHostSystem extends JamesImapHostSystem {
             new CassandraAclModule(),
             new CassandraMailboxModule(),
             new CassandraMessageModule(),
+            new CassandraBlobModule(),
             new CassandraMailboxCounterModule(),
             new CassandraMailboxRecentsModule(),
             new CassandraFirstUnseenModule(),
@@ -107,6 +111,8 @@ public class CassandraHostSystem extends JamesImapHostSystem {
         CassandraTypesProvider typesProvider = new CassandraTypesProvider(mailboxModule, session);
         CassandraMessageId.Factory messageIdFactory = new CassandraMessageId.Factory();
         CassandraMessageDAO messageDAO = new CassandraMessageDAO(session, typesProvider);
+        CassandraBlobsDAO cassandraBlobDao = new CassandraBlobsDAO(session);
+        CassandraMessageDAOV2 messageDAOV2 = new CassandraMessageDAOV2(session, typesProvider, cassandraBlobDao);
         CassandraMessageIdDAO messageIdDAO = new CassandraMessageIdDAO(session, messageIdFactory);
         CassandraMessageIdToImapUidDAO imapUidDAO = new CassandraMessageIdToImapUidDAO(session, messageIdFactory);
         CassandraMailboxCounterDAO mailboxCounterDAO = new CassandraMailboxCounterDAO(session);
@@ -122,6 +128,7 @@ public class CassandraHostSystem extends JamesImapHostSystem {
             modSeqProvider,
             session,
             messageDAO,
+            messageDAOV2,
             messageIdDAO,
             imapUidDAO,
             mailboxCounterDAO,

http://git-wip-us.apache.org/repos/asf/james-project/blob/31567b21/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 78221b7..d45cbc0 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
@@ -116,6 +116,7 @@ public class CassandraMailboxModule extends AbstractModule {
         cassandraDataDefinitions.addBinding().to(org.apache.james.mailbox.cassandra.modules.CassandraFirstUnseenModule.class);
         cassandraDataDefinitions.addBinding().to(org.apache.james.mailbox.cassandra.modules.CassandraMailboxModule.class);
         cassandraDataDefinitions.addBinding().to(org.apache.james.mailbox.cassandra.modules.CassandraMessageModule.class);
+        cassandraDataDefinitions.addBinding().to(org.apache.james.mailbox.cassandra.modules.CassandraBlobModule.class);
         cassandraDataDefinitions.addBinding().to(org.apache.james.mailbox.cassandra.modules.CassandraSubscriptionModule.class);
         cassandraDataDefinitions.addBinding().to(org.apache.james.mailbox.cassandra.modules.CassandraUidModule.class);
         cassandraDataDefinitions.addBinding().to(org.apache.james.mailbox.cassandra.modules.CassandraModSeqModule.class);


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