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