MAILBOX-339 Use both MailboxPathDAOs in mapper

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

Branch: refs/heads/master
Commit: e9014c25745bfa1350e56e08f56c33c73b46b389
Parents: 3861fa4
Author: Antoine Duprat <adup...@linagora.com>
Authored: Tue May 15 14:35:30 2018 +0200
Committer: Matthieu Baechler <matth...@apache.org>
Committed: Mon May 28 17:38:45 2018 +0200

----------------------------------------------------------------------
 .../CassandraMailboxSessionMapperFactory.java   |   7 +-
 .../cassandra/mail/CassandraMailboxMapper.java  |  70 ++++--
 .../CassandraSubscriptionManagerTest.java       |   3 +
 ...estCassandraMailboxSessionMapperFactory.java |   2 +
 .../CassandraMailboxMapperConcurrencyTest.java  |   2 +
 .../mail/CassandraMailboxMapperTest.java        | 230 ++++++++++++++++++-
 .../modules/mailbox/CassandraMailboxModule.java |   2 +
 7 files changed, 293 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/e9014c25/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 60ee504..e0a3db6 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
@@ -40,6 +40,7 @@ import 
org.apache.james.mailbox.cassandra.mail.CassandraMailboxCounterDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxMapper;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAOImpl;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathV2DAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxRecentsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
@@ -80,6 +81,7 @@ public class CassandraMailboxSessionMapperFactory extends 
MailboxSessionMapperFa
     private final CassandraIndexTableHandler indexTableHandler;
     private final CassandraMailboxDAO mailboxDAO;
     private final CassandraMailboxPathDAOImpl mailboxPathDAO;
+    private final CassandraMailboxPathV2DAO mailboxPathV2DAO;
     private final CassandraFirstUnseenDAO firstUnseenDAO;
     private final CassandraApplicableFlagDAO applicableFlagDAO;
     private final CassandraAttachmentDAO attachmentDAO;
@@ -98,7 +100,7 @@ public class CassandraMailboxSessionMapperFactory extends 
MailboxSessionMapperFa
                                                 CassandraMessageDAO messageDAO,
                                                 CassandraMessageIdDAO 
messageIdDAO, CassandraMessageIdToImapUidDAO imapUidDAO,
                                                 CassandraMailboxCounterDAO 
mailboxCounterDAO, CassandraMailboxRecentsDAO mailboxRecentsDAO, 
CassandraMailboxDAO mailboxDAO,
-                                                CassandraMailboxPathDAOImpl 
mailboxPathDAO, CassandraFirstUnseenDAO firstUnseenDAO, 
CassandraApplicableFlagDAO applicableFlagDAO,
+                                                CassandraMailboxPathDAOImpl 
mailboxPathDAO, CassandraMailboxPathV2DAO mailboxPathV2DAO, 
CassandraFirstUnseenDAO firstUnseenDAO, CassandraApplicableFlagDAO 
applicableFlagDAO,
                                                 CassandraAttachmentDAO 
attachmentDAO, CassandraAttachmentDAOV2 attachmentDAOV2, 
CassandraDeletedMessageDAO deletedMessageDAO,
                                                 ObjectStore objectStore, 
CassandraAttachmentMessageIdDAO attachmentMessageIdDAO,
                                                 CassandraAttachmentOwnerDAO 
ownerDAO, CassandraACLMapper aclMapper,
@@ -114,6 +116,7 @@ public class CassandraMailboxSessionMapperFactory extends 
MailboxSessionMapperFa
         this.mailboxRecentsDAO = mailboxRecentsDAO;
         this.mailboxDAO = mailboxDAO;
         this.mailboxPathDAO = mailboxPathDAO;
+        this.mailboxPathV2DAO = mailboxPathV2DAO;
         this.firstUnseenDAO = firstUnseenDAO;
         this.attachmentDAO = attachmentDAO;
         this.attachmentDAOV2 = attachmentDAOV2;
@@ -163,7 +166,7 @@ public class CassandraMailboxSessionMapperFactory extends 
MailboxSessionMapperFa
 
     @Override
     public MailboxMapper createMailboxMapper(MailboxSession mailboxSession) {
-        return new CassandraMailboxMapper(mailboxDAO, mailboxPathDAO, 
userMailboxRightsDAO, aclMapper, cassandraConfiguration);
+        return new CassandraMailboxMapper(mailboxDAO, mailboxPathDAO, 
mailboxPathV2DAO, userMailboxRightsDAO, aclMapper, cassandraConfiguration);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/e9014c25/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
index 8fe6f26..af580da 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
@@ -26,6 +26,7 @@ import java.util.Optional;
 import java.util.StringTokenizer;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionException;
+import java.util.function.Function;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -57,6 +58,7 @@ import 
com.datastax.driver.core.exceptions.InvalidQueryException;
 import com.github.fge.lambdas.Throwing;
 import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
 
 public class CassandraMailboxMapper implements MailboxMapper {
 
@@ -65,15 +67,17 @@ public class CassandraMailboxMapper implements 
MailboxMapper {
     public static final String CLUSTERING_COLUMNS_IS_TOO_LONG = "The sum of 
all clustering columns is too long";
     public static final Logger LOGGER = 
LoggerFactory.getLogger(CassandraMailboxMapper.class);
 
-    private final CassandraMailboxPathDAOImpl mailboxPathDAO;
     private final CassandraMailboxDAO mailboxDAO;
+    private final CassandraMailboxPathDAOImpl mailboxPathDAO;
+    private final CassandraMailboxPathV2DAO mailboxPathV2DAO;
     private final CassandraACLMapper cassandraACLMapper;
     private final CassandraUserMailboxRightsDAO userMailboxRightsDAO;
 
     @Inject
-    public CassandraMailboxMapper(CassandraMailboxDAO mailboxDAO, 
CassandraMailboxPathDAOImpl mailboxPathDAO, CassandraUserMailboxRightsDAO 
userMailboxRightsDAO, CassandraACLMapper aclMapper, CassandraConfiguration 
cassandraConfiguration) {
+    public CassandraMailboxMapper(CassandraMailboxDAO mailboxDAO, 
CassandraMailboxPathDAOImpl mailboxPathDAO, CassandraMailboxPathV2DAO 
mailboxPathV2DAO, CassandraUserMailboxRightsDAO userMailboxRightsDAO, 
CassandraACLMapper aclMapper, CassandraConfiguration cassandraConfiguration) {
         this.mailboxDAO = mailboxDAO;
         this.mailboxPathDAO = mailboxPathDAO;
+        this.mailboxPathV2DAO = mailboxPathV2DAO;
         this.userMailboxRightsDAO = userMailboxRightsDAO;
         this.cassandraACLMapper = aclMapper;
     }
@@ -81,20 +85,20 @@ public class CassandraMailboxMapper implements 
MailboxMapper {
     @Override
     public void delete(Mailbox mailbox) throws MailboxException {
         CassandraId mailboxId = (CassandraId) mailbox.getMailboxId();
-        mailboxPathDAO.delete(mailbox.generateAssociatedPath())
-            .thenCompose(any -> mailboxDAO.delete(mailboxId))
+        
FluentFutureStream.ofFutures(mailboxPathDAO.delete(mailbox.generateAssociatedPath()),
 mailboxPathV2DAO.delete(mailbox.generateAssociatedPath()))
+            .thenComposeOnAll(any -> mailboxDAO.delete(mailboxId))
             .join();
     }
 
     @Override
     public Mailbox findMailboxByPath(MailboxPath path) throws MailboxException 
{
         try {
-            return mailboxPathDAO.retrieveId(path)
+            return mailboxPathV2DAO.retrieveId(path)
                 .thenCompose(cassandraIdOptional ->
                     cassandraIdOptional
                         .map(CassandraIdAndPath::getCassandraId)
                         .map(this::retrieveMailbox)
-                        
.orElse(CompletableFuture.completedFuture(Optional.empty())))
+                        .orElseGet(Throwing.supplier(() -> 
fromPreviousTable(path))))
                 .join()
                 .orElseThrow(() -> new MailboxNotFoundException(path));
         } catch (CompletionException e) {
@@ -110,6 +114,27 @@ public class CassandraMailboxMapper implements 
MailboxMapper {
         }
     }
 
+    private CompletableFuture<Optional<SimpleMailbox>> 
fromPreviousTable(MailboxPath path) throws MailboxException {
+        try {
+            return mailboxPathDAO.retrieveId(path)
+                .thenCompose(cassandraIdOptional ->
+                    cassandraIdOptional
+                        .map(CassandraIdAndPath::getCassandraId)
+                        .map(this::retrieveMailbox)
+                        
.orElse(CompletableFuture.completedFuture(Optional.empty())));
+        } catch (CompletionException e) {
+            if (e.getCause() instanceof InvalidQueryException) {
+                String errorMessage = e.getCause().getMessage();
+                if (StringUtils.containsIgnoreCase(errorMessage, 
VALUES_MAY_NOT_BE_LARGER_THAN_64_K) 
+                        || StringUtils.containsIgnoreCase(errorMessage, 
CLUSTERING_COLUMNS_IS_TOO_LONG)) {
+                    throw new TooLongMailboxNameException("too long mailbox 
name");
+                }
+                throw new MailboxException("It has error with cassandra 
storage", e.getCause());
+            }
+            throw e;
+        }
+    }
+
     @Override
     public Mailbox findMailboxById(MailboxId id) throws MailboxException {
         CassandraId mailboxId = (CassandraId) id;
@@ -136,13 +161,21 @@ public class CassandraMailboxMapper implements 
MailboxMapper {
 
     @Override
     public List<Mailbox> findMailboxWithPathLike(MailboxPath path) throws 
MailboxException {
-        Pattern regex = 
Pattern.compile(constructEscapedRegexForMailboxNameMatching(path));
+        List<Mailbox> mailboxes = toMailboxes(path, 
mailboxPathV2DAO.listUserMailboxes(path.getNamespace(), path.getUser()));
+        if (mailboxes.isEmpty()) {
+            return toMailboxes(path, 
mailboxPathDAO.listUserMailboxes(path.getNamespace(), path.getUser()));
+        }
+        return mailboxes;
+    }
 
-        return 
FluentFutureStream.of(mailboxPathDAO.listUserMailboxes(path.getNamespace(), 
path.getUser()))
-            .filter(idAndPath -> 
regex.matcher(idAndPath.getMailboxPath().getName()).matches())
-            .thenFlatComposeOnOptional(this::retrieveMailbox)
-            .join()
-            .collect(Guavate.toImmutableList());
+    private List<Mailbox> toMailboxes(MailboxPath path, 
CompletableFuture<Stream<CassandraIdAndPath>> listUserMailboxes) {
+        Pattern regex = 
Pattern.compile(constructEscapedRegexForMailboxNameMatching(path));
+        
+        return FluentFutureStream.of(listUserMailboxes)
+                .filter(idAndPath -> 
regex.matcher(idAndPath.getMailboxPath().getName()).matches())
+                .thenFlatComposeOnOptional(this::retrieveMailbox)
+                .join()
+                .collect(Guavate.toImmutableList());
     }
 
     private CompletableFuture<Optional<SimpleMailbox>> 
retrieveMailbox(CassandraIdAndPath idAndPath) {
@@ -170,12 +203,12 @@ public class CassandraMailboxMapper implements 
MailboxMapper {
     }
 
     private CompletableFuture<Boolean> trySave(SimpleMailbox cassandraMailbox, 
CassandraId cassandraId) {
-        return mailboxPathDAO.save(cassandraMailbox.generateAssociatedPath(), 
cassandraId)
+        return 
mailboxPathV2DAO.save(cassandraMailbox.generateAssociatedPath(), cassandraId)
             .thenCompose(CompletableFutureUtil.composeIfTrue(
                 () -> retrieveMailbox(cassandraId)
                     .thenCompose(optional -> CompletableFuture
                         .allOf(optional
-                                .map(storedMailbox -> 
mailboxPathDAO.delete(storedMailbox.generateAssociatedPath()))
+                                .map(storedMailbox -> 
mailboxPathV2DAO.delete(storedMailbox.generateAssociatedPath()))
                                 
.orElse(CompletableFuture.completedFuture(null)),
                             mailboxDAO.save(cassandraMailbox)))));
     }
@@ -202,10 +235,11 @@ public class CassandraMailboxMapper implements 
MailboxMapper {
 
     @Override
     public boolean hasChildren(Mailbox mailbox, char delimiter) {
-        return mailboxPathDAO.listUserMailboxes(mailbox.getNamespace(), 
mailbox.getUser())
-            .thenApply(stream -> stream
-                .anyMatch(idAndPath -> 
idAndPath.getMailboxPath().getName().startsWith(mailbox.getName() + 
String.valueOf(delimiter))))
-            .join();
+        return 
ImmutableList.of(mailboxPathDAO.listUserMailboxes(mailbox.getNamespace(), 
mailbox.getUser()), mailboxPathV2DAO.listUserMailboxes(mailbox.getNamespace(), 
mailbox.getUser()))
+            .stream()
+            .map(CompletableFuture::join)
+            .flatMap(Function.identity())
+            .anyMatch(idAndPath -> 
idAndPath.getMailboxPath().getName().startsWith(mailbox.getName() + 
String.valueOf(delimiter)));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/e9014c25/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 29ec40f..e6bf8c1 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
@@ -38,6 +38,7 @@ import 
org.apache.james.mailbox.cassandra.mail.CassandraFirstUnseenDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxCounterDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAOImpl;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathV2DAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxRecentsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
@@ -89,6 +90,7 @@ public class CassandraSubscriptionManagerTest extends 
AbstractSubscriptionManage
         CassandraMailboxRecentsDAO mailboxRecentsDAO = null;
         CassandraMailboxDAO mailboxDAO = null;
         CassandraMailboxPathDAOImpl mailboxPathDAO = null;
+        CassandraMailboxPathV2DAO mailboxPathV2DAO = null;
         CassandraFirstUnseenDAO firstUnseenDAO = null;
         CassandraApplicableFlagDAO applicableFlagDAO = null;
         CassandraAttachmentDAO attachmentDAO = null;
@@ -111,6 +113,7 @@ public class CassandraSubscriptionManagerTest extends 
AbstractSubscriptionManage
                 mailboxRecentsDAO,
                 mailboxDAO,
                 mailboxPathDAO,
+                mailboxPathV2DAO,
                 firstUnseenDAO,
                 applicableFlagDAO,
                 attachmentDAO,

http://git-wip-us.apache.org/repos/asf/james-project/blob/e9014c25/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 d26350a..202ca30 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
@@ -36,6 +36,7 @@ import 
org.apache.james.mailbox.cassandra.mail.CassandraFirstUnseenDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxCounterDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAOImpl;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathV2DAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxRecentsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
@@ -71,6 +72,7 @@ public class TestCassandraMailboxSessionMapperFactory {
             new CassandraMailboxRecentsDAO(session),
             new CassandraMailboxDAO(session, typesProvider),
             new CassandraMailboxPathDAOImpl(session, typesProvider),
+            new CassandraMailboxPathV2DAO(session, 
CassandraUtils.WITH_DEFAULT_CONFIGURATION),
             new CassandraFirstUnseenDAO(session),
             new CassandraApplicableFlagDAO(session),
             new CassandraAttachmentDAO(session, utils, cassandraConfiguration),

http://git-wip-us.apache.org/repos/asf/james-project/blob/e9014c25/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperConcurrencyTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperConcurrencyTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperConcurrencyTest.java
index 3d2bd73..3cba151 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperConcurrencyTest.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperConcurrencyTest.java
@@ -58,10 +58,12 @@ public class CassandraMailboxMapperConcurrencyTest {
         cassandra = CassandraCluster.create(modules, cassandraServer.getIp(), 
cassandraServer.getBindingPort());
         CassandraMailboxDAO mailboxDAO = new 
CassandraMailboxDAO(cassandra.getConf(), cassandra.getTypesProvider());
         CassandraMailboxPathDAOImpl mailboxPathDAO = new 
CassandraMailboxPathDAOImpl(cassandra.getConf(), cassandra.getTypesProvider());
+        CassandraMailboxPathV2DAO mailboxPathV2DAO = new 
CassandraMailboxPathV2DAO(cassandra.getConf(), 
CassandraUtils.WITH_DEFAULT_CONFIGURATION);
         CassandraUserMailboxRightsDAO userMailboxRightsDAO = new 
CassandraUserMailboxRightsDAO(cassandra.getConf(), 
CassandraUtils.WITH_DEFAULT_CONFIGURATION);
         testee = new CassandraMailboxMapper(
             mailboxDAO,
             mailboxPathDAO,
+            mailboxPathV2DAO,
             userMailboxRightsDAO,
             new CassandraACLMapper(cassandra.getConf(),
                 userMailboxRightsDAO,

http://git-wip-us.apache.org/repos/asf/james-project/blob/e9014c25/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
index 350c523..b5c651f 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
@@ -22,15 +22,20 @@ package org.apache.james.mailbox.cassandra.mail;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
+import java.util.List;
+
 import org.apache.commons.lang3.StringUtils;
 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.CassandraId;
 import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraMailboxModule;
+import org.apache.james.mailbox.exception.MailboxNotFoundException;
 import org.apache.james.mailbox.exception.TooLongMailboxNameException;
+import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
 import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox;
@@ -42,24 +47,32 @@ import org.junit.Test;
 public class CassandraMailboxMapperTest {
     
     private static final int UID_VALIDITY = 52;
-    private static final MailboxPath MAILBOX_PATH = 
MailboxPath.forUser("user", "name");
+    private static final String USER = "user";
+    private static final CassandraId MAILBOX_ID = CassandraId.timeBased();
+    private static final MailboxPath MAILBOX_PATH = MailboxPath.forUser(USER, 
"name");
+    private static final Mailbox MAILBOX = new SimpleMailbox(MAILBOX_PATH, 
UID_VALIDITY, MAILBOX_ID);
+    private static final String WILDCARD = "%";
 
     @ClassRule public static DockerCassandraRule cassandraServer = new 
DockerCassandraRule();
     
     private CassandraCluster cassandra;
+    private CassandraMailboxDAO mailboxDAO;
     private CassandraMailboxPathDAOImpl mailboxPathDAO;
+    private CassandraMailboxPathV2DAO mailboxPathV2DAO;
     private CassandraMailboxMapper testee;
 
     @Before
     public void setUp() {
         CassandraModuleComposite modules = new CassandraModuleComposite(new 
CassandraMailboxModule(), new CassandraAclModule());
         cassandra = CassandraCluster.create(modules, cassandraServer.getIp(), 
cassandraServer.getBindingPort());
-        CassandraMailboxDAO mailboxDAO = new 
CassandraMailboxDAO(cassandra.getConf(), cassandra.getTypesProvider());
+        mailboxDAO = new CassandraMailboxDAO(cassandra.getConf(), 
cassandra.getTypesProvider());
         mailboxPathDAO = new CassandraMailboxPathDAOImpl(cassandra.getConf(), 
cassandra.getTypesProvider());
+        mailboxPathV2DAO = new CassandraMailboxPathV2DAO(cassandra.getConf(), 
CassandraUtils.WITH_DEFAULT_CONFIGURATION);
         CassandraUserMailboxRightsDAO userMailboxRightsDAO = new 
CassandraUserMailboxRightsDAO(cassandra.getConf(), 
CassandraUtils.WITH_DEFAULT_CONFIGURATION);
         testee = new CassandraMailboxMapper(
             mailboxDAO,
             mailboxPathDAO,
+            mailboxPathV2DAO,
             userMailboxRightsDAO,
             new CassandraACLMapper(cassandra.getConf(),
                 new CassandraUserMailboxRightsDAO(cassandra.getConf(), 
CassandraUtils.WITH_DEFAULT_CONFIGURATION),
@@ -82,11 +95,222 @@ public class CassandraMailboxMapperTest {
             testee.save(newMailbox))
             .isInstanceOf(TooLongMailboxNameException.class);
 
-        assertThat(mailboxPathDAO.retrieveId(MAILBOX_PATH).join())
+        assertThat(mailboxPathV2DAO.retrieveId(MAILBOX_PATH).join())
             .isPresent();
     }
 
     private MailboxPath tooLongMailboxPath(MailboxPath fromMailboxPath) {
         return new MailboxPath(fromMailboxPath, StringUtils.repeat("b", 
65537));
     }
+
+    @Test
+    public void deleteShouldDeleteMailboxAndMailboxPathFromV1Table() throws 
Exception {
+        mailboxDAO.save(MAILBOX)
+            .join();
+        mailboxPathDAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+
+        testee.delete(MAILBOX);
+
+        assertThatThrownBy(() -> testee.findMailboxByPath(MAILBOX_PATH))
+            .isInstanceOf(MailboxNotFoundException.class);
+    }
+
+    @Test
+    public void deleteShouldDeleteMailboxAndMailboxPathFromV2Table() throws 
Exception {
+        mailboxDAO.save(MAILBOX)
+            .join();
+        mailboxPathV2DAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+
+        testee.delete(MAILBOX);
+
+        assertThatThrownBy(() -> testee.findMailboxByPath(MAILBOX_PATH))
+            .isInstanceOf(MailboxNotFoundException.class);
+    }
+
+    @Test
+    public void findMailboxByPathShouldReturnMailboxWhenExistsInV1Table() 
throws Exception {
+        mailboxDAO.save(MAILBOX)
+            .join();
+        mailboxPathDAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+
+        Mailbox mailbox = testee.findMailboxByPath(MAILBOX_PATH);
+
+        assertThat(mailbox.generateAssociatedPath()).isEqualTo(MAILBOX_PATH);
+    }
+
+    @Test
+    public void findMailboxByPathShouldReturnMailboxWhenExistsInV2Table() 
throws Exception {
+        mailboxDAO.save(MAILBOX)
+            .join();
+        mailboxPathV2DAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+
+        Mailbox mailbox = testee.findMailboxByPath(MAILBOX_PATH);
+
+        assertThat(mailbox.generateAssociatedPath()).isEqualTo(MAILBOX_PATH);
+    }
+
+    @Test
+    public void findMailboxByPathShouldReturnMailboxWhenExistsInBothTables() 
throws Exception {
+        mailboxDAO.save(MAILBOX)
+            .join();
+        mailboxPathDAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+        mailboxPathV2DAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+
+        Mailbox mailbox = testee.findMailboxByPath(MAILBOX_PATH);
+
+        assertThat(mailbox.generateAssociatedPath()).isEqualTo(MAILBOX_PATH);
+    }
+
+    @Test
+    public void deleteShouldRemoveMailboxWhenInBothTables() {
+        mailboxDAO.save(MAILBOX)
+            .join();
+        mailboxPathDAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+        mailboxPathV2DAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+
+        testee.delete(MAILBOX);
+
+        assertThatThrownBy(() -> testee.findMailboxByPath(MAILBOX_PATH))
+            .isInstanceOf(MailboxNotFoundException.class);
+    }
+
+    @Test
+    public void deleteShouldRemoveMailboxWhenInV1Tables() {
+        mailboxDAO.save(MAILBOX)
+            .join();
+        mailboxPathDAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+
+        testee.delete(MAILBOX);
+
+        assertThatThrownBy(() -> testee.findMailboxByPath(MAILBOX_PATH))
+            .isInstanceOf(MailboxNotFoundException.class);
+    }
+
+    @Test
+    public void deleteShouldRemoveMailboxWhenInV2Table() {
+        mailboxDAO.save(MAILBOX)
+            .join();
+        mailboxPathV2DAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+
+        testee.delete(MAILBOX);
+
+        assertThatThrownBy(() -> testee.findMailboxByPath(MAILBOX_PATH))
+            .isInstanceOf(MailboxNotFoundException.class);
+    }
+
+    @Test
+    public void findMailboxByPathShouldThrowWhenDoesntExistInBothTables() {
+        mailboxDAO.save(MAILBOX)
+            .join();
+
+        assertThatThrownBy(() -> testee.findMailboxByPath(MAILBOX_PATH))
+            .isInstanceOf(MailboxNotFoundException.class);
+    }
+
+    @Test
+    public void 
findMailboxWithPathLikeShouldReturnMailboxesWhenExistsInV1Table() throws 
Exception {
+        mailboxDAO.save(MAILBOX)
+            .join();
+        mailboxPathDAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+    
+        List<Mailbox> mailboxes = testee.findMailboxWithPathLike(new 
MailboxPath(MailboxConstants.USER_NAMESPACE, USER, WILDCARD));
+
+        assertThat(mailboxes).containsOnly(MAILBOX);
+    }
+
+    @Test
+    public void 
findMailboxWithPathLikeShouldReturnMailboxesWhenExistsInBothTables() {
+        mailboxDAO.save(MAILBOX)
+            .join();
+        mailboxPathDAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+        mailboxPathV2DAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+
+        List<Mailbox> mailboxes = testee.findMailboxWithPathLike(new 
MailboxPath(MailboxConstants.USER_NAMESPACE, USER, WILDCARD));
+
+        assertThat(mailboxes).containsOnly(MAILBOX);
+    }
+
+    @Test
+    public void 
findMailboxWithPathLikeShouldReturnMailboxesWhenExistsInV2Table() throws 
Exception {
+        mailboxDAO.save(MAILBOX)
+            .join();
+        mailboxPathV2DAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+    
+        List<Mailbox> mailboxes = testee.findMailboxWithPathLike(new 
MailboxPath(MailboxConstants.USER_NAMESPACE, USER, WILDCARD));
+
+        assertThat(mailboxes).containsOnly(MAILBOX);
+    }
+
+    @Test
+    public void hasChildrenShouldReturnChildWhenExistsInV1Table() throws 
Exception {
+        mailboxDAO.save(MAILBOX)
+            .join();
+        mailboxPathDAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+        CassandraId childMailboxId = CassandraId.timeBased();
+        MailboxPath childMailboxPath = MailboxPath.forUser(USER, "name.child");
+        Mailbox childMailbox = new SimpleMailbox(childMailboxPath, 
UID_VALIDITY, childMailboxId);
+        mailboxDAO.save(childMailbox)
+            .join();
+        mailboxPathDAO.save(childMailboxPath, childMailboxId)
+            .join();
+    
+        boolean hasChildren = testee.hasChildren(MAILBOX, '.');
+
+        assertThat(hasChildren).isTrue();
+    }
+
+    @Test
+    public void hasChildrenShouldReturnChildWhenExistsInBothTables() {
+        mailboxDAO.save(MAILBOX)
+            .join();
+        mailboxPathDAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+        mailboxPathV2DAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+        CassandraId childMailboxId = CassandraId.timeBased();
+        MailboxPath childMailboxPath = MailboxPath.forUser(USER, "name.child");
+        Mailbox childMailbox = new SimpleMailbox(childMailboxPath, 
UID_VALIDITY, childMailboxId);
+        mailboxDAO.save(childMailbox)
+            .join();
+        mailboxPathDAO.save(childMailboxPath, childMailboxId)
+            .join();
+
+        boolean hasChildren = testee.hasChildren(MAILBOX, '.');
+
+        assertThat(hasChildren).isTrue();
+    }
+
+    @Test
+    public void hasChildrenShouldReturnChildWhenExistsInV2Table() throws 
Exception {
+        mailboxDAO.save(MAILBOX)
+            .join();
+        mailboxPathV2DAO.save(MAILBOX_PATH, MAILBOX_ID)
+            .join();
+        CassandraId childMailboxId = CassandraId.timeBased();
+        MailboxPath childMailboxPath = MailboxPath.forUser(USER, "name.child");
+        Mailbox childMailbox = new SimpleMailbox(childMailboxPath, 
UID_VALIDITY, childMailboxId);
+        mailboxDAO.save(childMailbox)
+            .join();
+        mailboxPathV2DAO.save(childMailboxPath, childMailboxId)
+            .join();
+    
+        boolean hasChildren = testee.hasChildren(MAILBOX, '.');
+    
+        assertThat(hasChildren).isTrue();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/e9014c25/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 f63ba6d..80db393 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
@@ -47,6 +47,7 @@ import 
org.apache.james.mailbox.cassandra.mail.CassandraMailboxCounterDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxMapper;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAOImpl;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathV2DAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxRecentsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
@@ -104,6 +105,7 @@ public class CassandraMailboxModule extends AbstractModule {
         bind(CassandraMailboxCounterDAO.class).in(Scopes.SINGLETON);
         bind(CassandraMailboxDAO.class).in(Scopes.SINGLETON);
         bind(CassandraMailboxPathDAOImpl.class).in(Scopes.SINGLETON);
+        bind(CassandraMailboxPathV2DAO.class).in(Scopes.SINGLETON);
         bind(CassandraMailboxRecentsDAO.class).in(Scopes.SINGLETON);
         bind(CassandraMessageDAO.class).in(Scopes.SINGLETON);
         bind(CassandraMessageIdDAO.class).in(Scopes.SINGLETON);


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

Reply via email to