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/02/07 08:06:57 UTC
[08/10] james-project git commit: JAMES-1874 Cassandra optimization :
Add a table for recent messages
JAMES-1874 Cassandra optimization : Add a table for recent messages
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/c8c12826
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/c8c12826
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/c8c12826
Branch: refs/heads/master
Commit: c8c12826015ac8706d75d7d423aea5f38cc146c4
Parents: 9c28aad
Author: Benoit Tellier <bt...@linagora.com>
Authored: Fri Feb 3 19:41:02 2017 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Tue Feb 7 08:57:46 2017 +0700
----------------------------------------------------------------------
.../CassandraMailboxSessionMapperFactory.java | 15 ++-
.../mail/CassandraMailboxCounterDAO.java | 3 +
.../mail/CassandraMailboxRecentsDAO.java | 105 ++++++++++++++++++
.../mail/CassandraMessageIdMapper.java | 29 +++--
.../cassandra/mail/CassandraMessageMapper.java | 55 +++++++---
.../modules/CassandraMailboxRecentsModule.java | 68 ++++++++++++
.../table/CassandraMailboxRecentsTable.java | 26 +++++
.../cassandra/CassandraMailboxManagerTest.java | 11 +-
.../CassandraSubscriptionManagerTest.java | 8 +-
.../cassandra/CassandraTestSystemFixture.java | 10 +-
.../CassandraMailboxManagerAttachmentTest.java | 6 +-
.../mail/CassandraMailboxRecentDAOTest.java | 107 +++++++++++++++++++
.../cassandra/mail/CassandraMapperProvider.java | 6 +-
.../cassandra/host/CassandraHostSystem.java | 8 +-
.../modules/mailbox/CassandraMailboxModule.java | 1 +
15 files changed, 428 insertions(+), 30 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/c8c12826/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 e3ce7c7..b384297 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
@@ -27,6 +27,7 @@ import org.apache.james.mailbox.cassandra.mail.CassandraAnnotationMapper;
import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentMapper;
import org.apache.james.mailbox.cassandra.mail.CassandraMailboxCounterDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMailboxMapper;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxRecentsDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdMapper;
@@ -59,20 +60,24 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa
private final CassandraMessageDAO messageDAO;
private final CassandraMessageIdDAO messageIdDAO;
private final CassandraMessageIdToImapUidDAO imapUidDAO;
- private CassandraMailboxCounterDAO mailboxCounterDAO;
+ private final CassandraMailboxCounterDAO mailboxCounterDAO;
+ private final CassandraMailboxRecentsDAO mailboxRecentsDAO;
private int maxRetry;
+
@Inject
public CassandraMailboxSessionMapperFactory(UidProvider uidProvider, ModSeqProvider modSeqProvider,
Session session, CassandraTypesProvider typesProvider,
- CassandraMessageDAO messageDAO, CassandraMessageIdDAO messageIdDAO, CassandraMessageIdToImapUidDAO imapUidDAO) {
+ CassandraMessageDAO messageDAO, CassandraMessageIdDAO messageIdDAO, CassandraMessageIdToImapUidDAO imapUidDAO,
+ CassandraMailboxCounterDAO mailboxCounterDAO, CassandraMailboxRecentsDAO mailboxRecentsDAO) {
this.uidProvider = uidProvider;
this.modSeqProvider = modSeqProvider;
this.session = session;
this.messageDAO = messageDAO;
this.messageIdDAO = messageIdDAO;
this.imapUidDAO = imapUidDAO;
- this.mailboxCounterDAO = new CassandraMailboxCounterDAO(session);
+ this.mailboxCounterDAO = mailboxCounterDAO;
+ this.mailboxRecentsDAO = mailboxRecentsDAO;
this.maxRetry = DEFAULT_MAX_RETRY;
this.typesProvider = typesProvider;
}
@@ -84,13 +89,13 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa
@Override
public CassandraMessageMapper createMessageMapper(MailboxSession mailboxSession) {
return new CassandraMessageMapper(uidProvider, modSeqProvider, null, maxRetry, createAttachmentMapper(mailboxSession),
- messageDAO, messageIdDAO, imapUidDAO, mailboxCounterDAO);
+ messageDAO, messageIdDAO, imapUidDAO, mailboxCounterDAO, mailboxRecentsDAO);
}
@Override
public MessageIdMapper createMessageIdMapper(MailboxSession mailboxSession) throws MailboxException {
return new CassandraMessageIdMapper(getMailboxMapper(mailboxSession), getAttachmentMapper(mailboxSession),
- imapUidDAO, messageIdDAO, messageDAO, mailboxCounterDAO, modSeqProvider, mailboxSession);
+ imapUidDAO, messageIdDAO, messageDAO, mailboxCounterDAO, mailboxRecentsDAO, modSeqProvider, mailboxSession);
}
@Override
http://git-wip-us.apache.org/repos/asf/james-project/blob/c8c12826/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxCounterDAO.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxCounterDAO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxCounterDAO.java
index 32a1fee..7f3c35a 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxCounterDAO.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxCounterDAO.java
@@ -29,6 +29,8 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.update;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
+import javax.inject.Inject;
+
import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
import org.apache.james.mailbox.cassandra.CassandraId;
import org.apache.james.mailbox.cassandra.table.CassandraMailboxCountersTable;
@@ -49,6 +51,7 @@ public class CassandraMailboxCounterDAO {
private final PreparedStatement decrementUnseenCountStatement;
private final PreparedStatement decrementMessageCountStatement;
+ @Inject
public CassandraMailboxCounterDAO(Session session) {
cassandraAsyncExecutor = new CassandraAsyncExecutor(session);
readStatement = createReadStatement(session);
http://git-wip-us.apache.org/repos/asf/james-project/blob/c8c12826/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxRecentsDAO.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxRecentsDAO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxRecentsDAO.java
new file mode 100644
index 0000000..06df836
--- /dev/null
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxRecentsDAO.java
@@ -0,0 +1,105 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.mail;
+
+import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.delete;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import javax.inject.Inject;
+
+import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.cassandra.CassandraId;
+import org.apache.james.mailbox.cassandra.table.CassandraMailboxRecentsTable;
+
+import com.datastax.driver.core.BoundStatement;
+import com.datastax.driver.core.PreparedStatement;
+import com.datastax.driver.core.Session;
+import com.github.steveash.guavate.Guavate;
+
+public class CassandraMailboxRecentsDAO {
+
+ private final CassandraAsyncExecutor cassandraAsyncExecutor;
+ private final PreparedStatement readStatement;
+ private final PreparedStatement deleteStatement;
+ private final PreparedStatement addStatement;
+
+ @Inject
+ public CassandraMailboxRecentsDAO(Session session) {
+ cassandraAsyncExecutor = new CassandraAsyncExecutor(session);
+ readStatement = createReadStatement(session);
+ deleteStatement = createDeleteStatement(session);
+ addStatement = createAddStatement(session);
+ }
+
+ private PreparedStatement createReadStatement(Session session) {
+ return session.prepare(
+ select(CassandraMailboxRecentsTable.RECENT_MESSAGE_UID)
+ .from(CassandraMailboxRecentsTable.TABLE_NAME)
+ .where(eq(CassandraMailboxRecentsTable.MAILBOX_ID, bindMarker(CassandraMailboxRecentsTable.MAILBOX_ID))));
+ }
+
+ private PreparedStatement createDeleteStatement(Session session) {
+ return session.prepare(
+ delete()
+ .from(CassandraMailboxRecentsTable.TABLE_NAME)
+ .where(eq(CassandraMailboxRecentsTable.MAILBOX_ID, bindMarker(CassandraMailboxRecentsTable.MAILBOX_ID)))
+ .and(eq(CassandraMailboxRecentsTable.RECENT_MESSAGE_UID, bindMarker(CassandraMailboxRecentsTable.RECENT_MESSAGE_UID))));
+ }
+
+ private PreparedStatement createAddStatement(Session session) {
+ return session.prepare(
+ insertInto(CassandraMailboxRecentsTable.TABLE_NAME)
+ .value(CassandraMailboxRecentsTable.MAILBOX_ID, bindMarker(CassandraMailboxRecentsTable.MAILBOX_ID))
+ .value(CassandraMailboxRecentsTable.RECENT_MESSAGE_UID, bindMarker(CassandraMailboxRecentsTable.RECENT_MESSAGE_UID)));
+ }
+
+ public CompletableFuture<List<MessageUid>> getRecentMessageUidsInMailbox(CassandraId mailboxId) {
+ return cassandraAsyncExecutor.execute(bindWithMailbox(mailboxId, readStatement))
+ .thenApply(CassandraUtils::convertToStream)
+ .thenApply(stream -> stream.map(row -> row.getLong(CassandraMailboxRecentsTable.RECENT_MESSAGE_UID)))
+ .thenApply(stream -> stream.map(MessageUid::of))
+ .thenApply(stream -> stream.collect(Guavate.toImmutableList()));
+ }
+
+ private BoundStatement bindWithMailbox(CassandraId mailboxId, PreparedStatement statement) {
+ return statement.bind()
+ .setUUID(CassandraMailboxRecentsTable.MAILBOX_ID, mailboxId.asUuid());
+ }
+
+ public CompletableFuture<Void> removeFromRecent(CassandraId mailboxId, MessageUid messageUid) {
+ return cassandraAsyncExecutor.executeVoid(deleteStatement.bind()
+ .setUUID(CassandraMailboxRecentsTable.MAILBOX_ID, mailboxId.asUuid())
+ .setLong(CassandraMailboxRecentsTable.RECENT_MESSAGE_UID, messageUid.asLong()));
+ }
+
+ public CompletableFuture<Void> addToRecent(CassandraId mailboxId, MessageUid messageUid) {
+ return cassandraAsyncExecutor.executeVoid(addStatement.bind()
+ .setUUID(CassandraMailboxRecentsTable.MAILBOX_ID, mailboxId.asUuid())
+ .setLong(CassandraMailboxRecentsTable.RECENT_MESSAGE_UID, messageUid.asLong()));
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/c8c12826/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 b4e0474..41d8749 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
@@ -69,18 +69,20 @@ public class CassandraMessageIdMapper implements MessageIdMapper {
private final CassandraMessageIdDAO messageIdDAO;
private final CassandraMessageDAO messageDAO;
private final CassandraMailboxCounterDAO mailboxCounterDAO;
+ private final CassandraMailboxRecentsDAO mailboxRecentsDAO;
private final ModSeqProvider modSeqProvider;
private final MailboxSession mailboxSession;
public CassandraMessageIdMapper(MailboxMapper mailboxMapper, AttachmentMapper attachmentMapper,
CassandraMessageIdToImapUidDAO imapUidDAO, CassandraMessageIdDAO messageIdDAO, CassandraMessageDAO messageDAO,
- CassandraMailboxCounterDAO cassandraMailboxCounterDAO, ModSeqProvider modSeqProvider, MailboxSession mailboxSession) {
+ CassandraMailboxCounterDAO cassandraMailboxCounterDAO, CassandraMailboxRecentsDAO mailboxRecentsDAO, ModSeqProvider modSeqProvider, MailboxSession mailboxSession) {
this.mailboxMapper = mailboxMapper;
this.attachmentMapper = attachmentMapper;
this.imapUidDAO = imapUidDAO;
this.messageIdDAO = messageIdDAO;
this.messageDAO = messageDAO;
this.mailboxCounterDAO = cassandraMailboxCounterDAO;
+ this.mailboxRecentsDAO = mailboxRecentsDAO;
this.modSeqProvider = modSeqProvider;
this.mailboxSession = mailboxSession;
}
@@ -149,6 +151,7 @@ public class CassandraMessageIdMapper implements MessageIdMapper {
imapUidDAO.insert(composedMessageIdWithMetaData),
messageIdDAO.insert(composedMessageIdWithMetaData)))
.thenCompose(voidValue -> CompletableFuture.allOf(
+ mailboxRecentsDAO.addToRecent(mailboxId, mailboxMessage.getUid()),
mailboxCounterDAO.incrementCount(mailboxId),
incrementUnseenOnSave(mailboxId, mailboxMessage.createFlags())))
.join();
@@ -196,6 +199,7 @@ public class CassandraMessageIdMapper implements MessageIdMapper {
messageIdDAO.delete(mailboxId, metaData.getComposedMessageId().getUid()))
.thenCompose(voidValue -> CompletableFuture.allOf(
mailboxCounterDAO.decrementCount(mailboxId),
+ mailboxRecentsDAO.removeFromRecent(mailboxId, metaData.getComposedMessageId().getUid()),
decrementUnseenOnDelete(mailboxId, metaData.getFlags())));
}
@@ -243,20 +247,31 @@ public class CassandraMessageIdMapper implements MessageIdMapper {
private CompletableFuture<Pair<MailboxId, UpdatedFlags>> updateCounts(Pair<MailboxId, UpdatedFlags> pair) {
CassandraId cassandraId = (CassandraId) pair.getLeft();
return CompletableFuture.allOf(
- incrementCountIfNeeded(pair.getRight().getOldFlags(), pair.getRight().getNewFlags(), cassandraId),
- decrementCountIfNeeded(pair.getRight().getOldFlags(), pair.getRight().getNewFlags(), cassandraId))
+ manageRecent(pair.getRight(), cassandraId),
+ incrementCountIfNeeded(pair.getRight(), cassandraId),
+ decrementCountIfNeeded(pair.getRight(), cassandraId))
.thenApply(voidValue -> pair);
}
- private CompletableFuture<Void> incrementCountIfNeeded(Flags oldFlags, Flags newFlags, CassandraId cassandraId) {
- if (oldFlags.contains(Flags.Flag.SEEN) && !newFlags.contains(Flags.Flag.SEEN)) {
+ private CompletableFuture<Void> manageRecent(UpdatedFlags updatedFlags, CassandraId cassandraId) {
+ if (updatedFlags.isSet(Flags.Flag.RECENT)) {
+ return mailboxRecentsDAO.addToRecent(cassandraId, updatedFlags.getUid());
+ }
+ if (updatedFlags.isUnset(Flags.Flag.RECENT)){
+ return mailboxRecentsDAO.removeFromRecent(cassandraId, updatedFlags.getUid());
+ }
+ return CompletableFuture.completedFuture(null);
+ }
+
+ private CompletableFuture<Void> incrementCountIfNeeded(UpdatedFlags updatedFlags, CassandraId cassandraId) {
+ if (updatedFlags.isUnset(Flags.Flag.SEEN)) {
return mailboxCounterDAO.incrementUnseen(cassandraId);
}
return CompletableFuture.completedFuture(null);
}
- private CompletableFuture<Void> decrementCountIfNeeded(Flags oldFlags, Flags newFlags, CassandraId cassandraId) {
- if (!oldFlags.contains(Flags.Flag.SEEN) && newFlags.contains(Flags.Flag.SEEN)) {
+ private CompletableFuture<Void> decrementCountIfNeeded(UpdatedFlags updatedFlags, CassandraId cassandraId) {
+ if (updatedFlags.isSet(Flags.Flag.SEEN)) {
return mailboxCounterDAO.decrementUnseen(cassandraId);
}
return CompletableFuture.completedFuture(null);
http://git-wip-us.apache.org/repos/asf/james-project/blob/c8c12826/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 79763ee..38d27b8 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
@@ -75,10 +75,12 @@ public class CassandraMessageMapper implements MessageMapper {
private final CassandraMessageIdDAO messageIdDAO;
private final CassandraMessageIdToImapUidDAO imapUidDAO;
private final CassandraMailboxCounterDAO mailboxCounterDAO;
+ private final CassandraMailboxRecentsDAO mailboxRecentDAO;
public CassandraMessageMapper(UidProvider uidProvider, ModSeqProvider modSeqProvider,
MailboxSession mailboxSession, int maxRetries, AttachmentMapper attachmentMapper,
- CassandraMessageDAO messageDAO, CassandraMessageIdDAO messageIdDAO, CassandraMessageIdToImapUidDAO imapUidDAO, CassandraMailboxCounterDAO mailboxCounterDAO) {
+ CassandraMessageDAO messageDAO, CassandraMessageIdDAO messageIdDAO, CassandraMessageIdToImapUidDAO imapUidDAO,
+ CassandraMailboxCounterDAO mailboxCounterDAO, CassandraMailboxRecentsDAO mailboxRecentDAO) {
this.uidProvider = uidProvider;
this.modSeqProvider = modSeqProvider;
this.mailboxSession = mailboxSession;
@@ -88,6 +90,7 @@ public class CassandraMessageMapper implements MessageMapper {
this.messageIdDAO = messageIdDAO;
this.imapUidDAO = imapUidDAO;
this.mailboxCounterDAO = mailboxCounterDAO;
+ this.mailboxRecentDAO = mailboxRecentDAO;
}
@Override
@@ -123,6 +126,7 @@ public class CassandraMessageMapper implements MessageMapper {
imapUidDAO.delete(messageId, mailboxId),
messageIdDAO.delete(mailboxId, uid)
).thenCompose(voidValue -> CompletableFuture.allOf(
+ removeRecentOnDelete(mailboxId, composedMessageIdWithMetaData.getFlags(), composedMessageId.getUid()),
mailboxCounterDAO.decrementCount(mailboxId),
decrementUnseenOnDelete(mailboxId, composedMessageIdWithMetaData.getFlags())));
}
@@ -134,6 +138,14 @@ public class CassandraMessageMapper implements MessageMapper {
return mailboxCounterDAO.decrementUnseen(mailboxId);
}
+ private CompletableFuture<Void> removeRecentOnDelete(CassandraId mailboxId, Flags flags, MessageUid uid) {
+ if (flags.contains(Flag.RECENT)) {
+ return mailboxRecentDAO.removeFromRecent(mailboxId, uid);
+ }
+ return CompletableFuture.completedFuture(null);
+ }
+
+
private CompletableFuture<Optional<ComposedMessageIdWithMetaData>> retrieveMessageId(CassandraId mailboxId, MailboxMessage message) {
return messageIdDAO.retrieve(mailboxId, message.getUid());
}
@@ -167,13 +179,8 @@ public class CassandraMessageMapper implements MessageMapper {
@Override
public List<MessageUid> findRecentMessageUidsInMailbox(Mailbox mailbox) throws MailboxException {
CassandraId mailboxId = (CassandraId) mailbox.getMailboxId();
- return retrieveMessages(retrieveMessageIds(mailboxId, MessageRange.all()), FetchType.Metadata, Optional.empty())
- .filter(MailboxMessage::isRecent)
- .flatMap(message -> imapUidDAO.retrieve((CassandraMessageId) message.getMessageId(), Optional.ofNullable(mailboxId)).join())
- .map(ComposedMessageIdWithMetaData::getComposedMessageId)
- .map(ComposedMessageId::getUid)
- .sorted()
- .collect(Collectors.toList());
+ return mailboxRecentDAO.getRecentMessageUidsInMailbox(mailboxId)
+ .join();
}
@Override
@@ -225,6 +232,7 @@ public class CassandraMessageMapper implements MessageMapper {
CassandraId mailboxId = (CassandraId) mailbox.getMailboxId();
save(mailbox, message)
.thenCompose(voidValue -> CompletableFuture.allOf(
+ addRecentOnSave(mailboxId, message),
incrementUnseenOnSave(mailboxId, message.createFlags()),
mailboxCounterDAO.incrementCount(mailboxId)))
.join();
@@ -238,12 +246,19 @@ public class CassandraMessageMapper implements MessageMapper {
return mailboxCounterDAO.incrementUnseen(mailboxId);
}
+ private CompletableFuture<Void> addRecentOnSave(CassandraId mailboxId, MailboxMessage message) {
+ if (message.createFlags().contains(Flag.RECENT)) {
+ return mailboxRecentDAO.addToRecent(mailboxId, message.getUid());
+ }
+ return CompletableFuture.completedFuture(null);
+ }
+
@Override
public Iterator<UpdatedFlags> updateFlags(Mailbox mailbox, FlagsUpdateCalculator flagUpdateCalculator, MessageRange set) throws MailboxException {
CassandraId mailboxId = (CassandraId) mailbox.getMailboxId();
return retrieveMessages(retrieveMessageIds(mailboxId, set), FetchType.Metadata, Optional.empty())
.flatMap(message -> updateFlagsOnMessage(mailbox, flagUpdateCalculator, message))
- .map((UpdatedFlags updatedFlags) -> manageUnseenMessageCounts(mailbox, updatedFlags.getOldFlags(), updatedFlags.getNewFlags())
+ .map((UpdatedFlags updatedFlags) -> manageCounters(mailbox, updatedFlags)
.thenApply(voidValue -> updatedFlags))
.map(CompletableFuture::join)
.collect(Collectors.toList()) // This collect is here as we need to consume all the stream before returning result
@@ -282,17 +297,33 @@ public class CassandraMessageMapper implements MessageMapper {
imapUidDAO.insert(composedMessageIdWithMetaData));
}
- private CompletableFuture<Void> manageUnseenMessageCounts(Mailbox mailbox, Flags oldFlags, Flags newFlags) {
+ private CompletableFuture<Void> manageCounters(Mailbox mailbox, UpdatedFlags updatedFlags) {
+ return CompletableFuture.allOf(manageUnseenMessageCounts(mailbox, updatedFlags),
+ manageRecents(mailbox, updatedFlags));
+ }
+
+ private CompletableFuture<Void> manageUnseenMessageCounts(Mailbox mailbox, UpdatedFlags updatedFlags) {
CassandraId mailboxId = (CassandraId) mailbox.getMailboxId();
- if (oldFlags.contains(Flag.SEEN) && !newFlags.contains(Flag.SEEN)) {
+ if (updatedFlags.isUnset(Flag.SEEN)) {
return mailboxCounterDAO.incrementUnseen(mailboxId);
}
- if (!oldFlags.contains(Flag.SEEN) && newFlags.contains(Flag.SEEN)) {
+ if (updatedFlags.isSet(Flag.SEEN)) {
return mailboxCounterDAO.decrementUnseen(mailboxId);
}
return CompletableFuture.completedFuture(null);
}
+ private CompletableFuture<Void> manageRecents(Mailbox mailbox, UpdatedFlags updatedFlags) {
+ CassandraId mailboxId = (CassandraId) mailbox.getMailboxId();
+ if (updatedFlags.isUnset(Flag.RECENT)) {
+ return mailboxRecentDAO.removeFromRecent(mailboxId, updatedFlags.getUid());
+ }
+ if (updatedFlags.isSet(Flag.RECENT)) {
+ return mailboxRecentDAO.addToRecent(mailboxId, updatedFlags.getUid());
+ }
+ return CompletableFuture.completedFuture(null);
+ }
+
private Stream<UpdatedFlags> updateFlagsOnMessage(Mailbox mailbox, FlagsUpdateCalculator flagUpdateCalculator, MailboxMessage message) {
return tryMessageFlagsUpdate(flagUpdateCalculator, mailbox, message)
.map(Stream::of)
http://git-wip-us.apache.org/repos/asf/james-project/blob/c8c12826/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraMailboxRecentsModule.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraMailboxRecentsModule.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraMailboxRecentsModule.java
new file mode 100644
index 0000000..6cccbd8
--- /dev/null
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraMailboxRecentsModule.java
@@ -0,0 +1,68 @@
+/****************************************************************
+ * 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.modules;
+
+import static com.datastax.driver.core.DataType.bigint;
+import static com.datastax.driver.core.DataType.list;
+import static com.datastax.driver.core.DataType.timeuuid;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.james.backends.cassandra.components.CassandraIndex;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.backends.cassandra.components.CassandraTable;
+import org.apache.james.backends.cassandra.components.CassandraType;
+import org.apache.james.mailbox.cassandra.table.CassandraMailboxRecentsTable;
+
+import com.datastax.driver.core.schemabuilder.SchemaBuilder;
+
+public class CassandraMailboxRecentsModule implements CassandraModule {
+
+ private final List<CassandraTable> tables;
+ private final List<CassandraIndex> index;
+ private final List<CassandraType> types;
+
+ public CassandraMailboxRecentsModule() {
+ tables = Collections.singletonList(
+ new CassandraTable(CassandraMailboxRecentsTable.TABLE_NAME,
+ SchemaBuilder.createTable(CassandraMailboxRecentsTable.TABLE_NAME)
+ .ifNotExists()
+ .addPartitionKey(CassandraMailboxRecentsTable.MAILBOX_ID, timeuuid())
+ .addClusteringColumn(CassandraMailboxRecentsTable.RECENT_MESSAGE_UID, bigint())));
+ index = Collections.emptyList();
+ types = Collections.emptyList();
+ }
+
+ @Override
+ public List<CassandraTable> moduleTables() {
+ return tables;
+ }
+
+ @Override
+ public List<CassandraIndex> moduleIndex() {
+ return index;
+ }
+
+ @Override
+ public List<CassandraType> moduleTypes() {
+ return types;
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/c8c12826/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxRecentsTable.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxRecentsTable.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxRecentsTable.java
new file mode 100644
index 0000000..d729ae4
--- /dev/null
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxRecentsTable.java
@@ -0,0 +1,26 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.table;
+
+public interface CassandraMailboxRecentsTable {
+ String TABLE_NAME = "mailboxRecents";
+ String MAILBOX_ID = "mailboxId";
+ String RECENT_MESSAGE_UID = "recent_mesage_uid";
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/c8c12826/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 633bfbc..caadf4b 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
@@ -24,6 +24,8 @@ import org.apache.james.mailbox.acl.GroupMembershipResolver;
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.CassandraMailboxCounterDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxRecentsDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO;
@@ -34,6 +36,7 @@ import org.apache.james.mailbox.cassandra.modules.CassandraAnnotationModule;
import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
import org.apache.james.mailbox.cassandra.modules.CassandraMailboxCounterModule;
import org.apache.james.mailbox.cassandra.modules.CassandraMailboxModule;
+import org.apache.james.mailbox.cassandra.modules.CassandraMailboxRecentsModule;
import org.apache.james.mailbox.cassandra.modules.CassandraMessageModule;
import org.apache.james.mailbox.cassandra.modules.CassandraModSeqModule;
import org.apache.james.mailbox.cassandra.modules.CassandraSubscriptionModule;
@@ -60,6 +63,7 @@ public class CassandraMailboxManagerTest {
new CassandraMailboxModule(),
new CassandraMessageModule(),
new CassandraMailboxCounterModule(),
+ new CassandraMailboxRecentsModule(),
new CassandraUidModule(),
new CassandraModSeqModule(),
new CassandraSubscriptionModule(),
@@ -77,13 +81,18 @@ public class CassandraMailboxManagerTest {
CassandraMessageIdDAO messageIdDAO = new CassandraMessageIdDAO(CASSANDRA.getConf(), messageIdFactory);
CassandraMessageIdToImapUidDAO imapUidDAO = new CassandraMessageIdToImapUidDAO(CASSANDRA.getConf(), messageIdFactory);
CassandraMessageDAO messageDAO = new CassandraMessageDAO(CASSANDRA.getConf(), CASSANDRA.getTypesProvider(), messageIdFactory);
+ CassandraMailboxCounterDAO mailboxCounterDAO = new CassandraMailboxCounterDAO(CASSANDRA.getConf());
+ CassandraMailboxRecentsDAO mailboxRecentsDAO = new CassandraMailboxRecentsDAO(CASSANDRA.getConf());
+
CassandraMailboxSessionMapperFactory mapperFactory = new CassandraMailboxSessionMapperFactory(uidProvider,
modSeqProvider,
CASSANDRA.getConf(),
CASSANDRA.getTypesProvider(),
messageDAO,
messageIdDAO,
- imapUidDAO);
+ imapUidDAO,
+ mailboxCounterDAO,
+ mailboxRecentsDAO);
MailboxACLResolver aclResolver = new UnionMailboxACLResolver();
GroupMembershipResolver groupMembershipResolver = new SimpleGroupMembershipResolver();
http://git-wip-us.apache.org/repos/asf/james-project/blob/c8c12826/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 f253f53..5d5e6c1 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
@@ -23,6 +23,8 @@ import org.apache.james.backends.cassandra.CassandraCluster;
import org.apache.james.backends.cassandra.init.CassandraModuleComposite;
import org.apache.james.mailbox.AbstractSubscriptionManagerTest;
import org.apache.james.mailbox.SubscriptionManager;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxCounterDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxRecentsDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO;
@@ -45,6 +47,8 @@ public class CassandraSubscriptionManagerTest extends AbstractSubscriptionManage
CassandraMessageIdToImapUidDAO imapUidDAO = null;
CassandraMessageDAO messageDAO = null;
CassandraMessageIdDAO messageIdDAO = null;
+ CassandraMailboxCounterDAO mailboxCounterDAO = null;
+ CassandraMailboxRecentsDAO mailboxRecentsDAO = null;
return new CassandraSubscriptionManager(
new CassandraMailboxSessionMapperFactory(
new CassandraUidProvider(cassandra.getConf()),
@@ -53,7 +57,9 @@ public class CassandraSubscriptionManagerTest extends AbstractSubscriptionManage
cassandra.getTypesProvider(),
messageDAO,
messageIdDAO,
- imapUidDAO
+ imapUidDAO,
+ mailboxCounterDAO,
+ mailboxRecentsDAO
)
);
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/c8c12826/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 fdf3abe..0999c8e 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,8 @@ 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.CassandraMailboxCounterDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxRecentsDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO;
@@ -33,6 +35,7 @@ import org.apache.james.mailbox.cassandra.modules.CassandraAnnotationModule;
import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
import org.apache.james.mailbox.cassandra.modules.CassandraMailboxCounterModule;
import org.apache.james.mailbox.cassandra.modules.CassandraMailboxModule;
+import org.apache.james.mailbox.cassandra.modules.CassandraMailboxRecentsModule;
import org.apache.james.mailbox.cassandra.modules.CassandraMessageModule;
import org.apache.james.mailbox.cassandra.modules.CassandraModSeqModule;
import org.apache.james.mailbox.cassandra.modules.CassandraUidModule;
@@ -50,6 +53,7 @@ public class CassandraTestSystemFixture {
new CassandraMailboxModule(),
new CassandraMessageModule(),
new CassandraMailboxCounterModule(),
+ new CassandraMailboxRecentsModule(),
new CassandraUidModule(),
new CassandraModSeqModule(),
new CassandraAttachmentModule(),
@@ -64,13 +68,17 @@ public class CassandraTestSystemFixture {
CassandraMessageIdDAO messageIdDAO = new CassandraMessageIdDAO(CASSANDRA.getConf(), messageIdFactory);
CassandraMessageIdToImapUidDAO imapUidDAO = new CassandraMessageIdToImapUidDAO(CASSANDRA.getConf(), messageIdFactory);
CassandraMessageDAO messageDAO = new CassandraMessageDAO(CASSANDRA.getConf(), CASSANDRA.getTypesProvider(), messageIdFactory);
+ CassandraMailboxCounterDAO mailboxCounterDAO = new CassandraMailboxCounterDAO(CASSANDRA.getConf());
+ CassandraMailboxRecentsDAO mailboxRecentsDAO = new CassandraMailboxRecentsDAO(CASSANDRA.getConf());
return new CassandraMailboxSessionMapperFactory(uidProvider,
modSeqProvider,
CASSANDRA.getConf(),
CASSANDRA.getTypesProvider(),
messageDAO,
messageIdDAO,
- imapUidDAO);
+ imapUidDAO,
+ mailboxCounterDAO,
+ mailboxRecentsDAO);
}
public static CassandraMailboxManager createMailboxManager(CassandraMailboxSessionMapperFactory mapperFactory) throws Exception{
http://git-wip-us.apache.org/repos/asf/james-project/blob/c8c12826/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 b923c1f..93228aa 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
@@ -32,6 +32,7 @@ import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
import org.apache.james.mailbox.cassandra.modules.CassandraMailboxCounterModule;
import org.apache.james.mailbox.cassandra.modules.CassandraMailboxModule;
+import org.apache.james.mailbox.cassandra.modules.CassandraMailboxRecentsModule;
import org.apache.james.mailbox.cassandra.modules.CassandraMessageModule;
import org.apache.james.mailbox.cassandra.modules.CassandraModSeqModule;
import org.apache.james.mailbox.cassandra.modules.CassandraUidModule;
@@ -47,6 +48,7 @@ public class CassandraMailboxManagerAttachmentTest extends AbstractMailboxManage
new CassandraMailboxModule(),
new CassandraMessageModule(),
new CassandraMailboxCounterModule(),
+ new CassandraMailboxRecentsModule(),
new CassandraModSeqModule(),
new CassandraUidModule(),
new CassandraAttachmentModule()));
@@ -64,7 +66,9 @@ public class CassandraMailboxManagerAttachmentTest extends AbstractMailboxManage
cassandra.getTypesProvider(),
new CassandraMessageDAO(cassandra.getConf(), cassandra.getTypesProvider(), messageIdFactory),
new CassandraMessageIdDAO(cassandra.getConf(), messageIdFactory),
- new CassandraMessageIdToImapUidDAO(cassandra.getConf(), messageIdFactory));
+ new CassandraMessageIdToImapUidDAO(cassandra.getConf(), messageIdFactory),
+ new CassandraMailboxCounterDAO(cassandra.getConf()),
+ new CassandraMailboxRecentsDAO(cassandra.getConf()));
Authenticator noAuthenticator = null;
mailboxManager = new CassandraMailboxManager(mailboxSessionMapperFactory, noAuthenticator, new NoMailboxPathLocker(), new MessageParser(), messageIdFactory);
mailboxManager.init();
http://git-wip-us.apache.org/repos/asf/james-project/blob/c8c12826/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxRecentDAOTest.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxRecentDAOTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxRecentDAOTest.java
new file mode 100644
index 0000000..81bb313
--- /dev/null
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxRecentDAOTest.java
@@ -0,0 +1,107 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.mail;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+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.modules.CassandraMailboxRecentsModule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CassandraMailboxRecentDAOTest {
+ public static final MessageUid UID1 = MessageUid.of(36L);
+ public static final MessageUid UID2 = MessageUid.of(37L);
+ public static final CassandraId CASSANDRA_ID = CassandraId.timeBased();
+
+ private CassandraCluster cassandra;
+ private CassandraMailboxRecentsDAO testee;
+
+ @Before
+ public void setUp() {
+ cassandra = CassandraCluster.create(new CassandraMailboxRecentsModule());
+ cassandra.ensureAllTables();
+
+ testee = new CassandraMailboxRecentsDAO(cassandra.getConf());
+ }
+
+ @After
+ public void tearDown() {
+ cassandra.clearAllTables();
+ }
+
+ @Test
+ public void getRecentMessageUidsInMailboxShouldBeEmptyByDefault() throws Exception {
+ assertThat(testee.getRecentMessageUidsInMailbox(CASSANDRA_ID).join()).isEmpty();
+ }
+
+ @Test
+ public void addToRecentShouldAddUidWhenEmpty() throws Exception {
+ testee.addToRecent(CASSANDRA_ID, UID1).join();
+
+ assertThat(testee.getRecentMessageUidsInMailbox(CASSANDRA_ID).join()).containsOnly(UID1);
+ }
+
+ @Test
+ public void removeFromRecentShouldRemoveUidWhenOnlyOneUid() throws Exception {
+ testee.addToRecent(CASSANDRA_ID, UID1).join();
+
+ testee.removeFromRecent(CASSANDRA_ID, UID1).join();
+
+ assertThat(testee.getRecentMessageUidsInMailbox(CASSANDRA_ID).join()).isEmpty();
+ }
+
+ @Test
+ public void removeFromRecentShouldNotFailIfNotExisting() throws Exception {
+ testee.removeFromRecent(CASSANDRA_ID, UID1).join();
+
+ assertThat(testee.getRecentMessageUidsInMailbox(CASSANDRA_ID).join()).isEmpty();
+ }
+
+ @Test
+ public void addToRecentShouldAddUidWhenNotEmpty() throws Exception {
+ testee.addToRecent(CASSANDRA_ID, UID1).join();
+
+ testee.addToRecent(CASSANDRA_ID, UID2).join();
+
+ assertThat(testee.getRecentMessageUidsInMailbox(CASSANDRA_ID).join()).containsOnly(UID1, UID2);
+ }
+
+ @Test
+ public void removeFromRecentShouldOnlyRemoveUidWhenNotEmpty() throws Exception {
+ testee.addToRecent(CASSANDRA_ID, UID1).join();
+ testee.addToRecent(CASSANDRA_ID, UID2).join();
+
+ testee.removeFromRecent(CASSANDRA_ID, UID2).join();
+
+ assertThat(testee.getRecentMessageUidsInMailbox(CASSANDRA_ID).join()).containsOnly(UID1);
+ }
+
+ @Test
+ public void addToRecentShouldBeIdempotent() throws Exception {
+ testee.addToRecent(CASSANDRA_ID, UID1).join();
+ testee.addToRecent(CASSANDRA_ID, UID1).join();
+
+ assertThat(testee.getRecentMessageUidsInMailbox(CASSANDRA_ID).join()).containsOnly(UID1);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/c8c12826/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 2516944..ba39d49 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
@@ -33,6 +33,7 @@ import org.apache.james.mailbox.cassandra.modules.CassandraAnnotationModule;
import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
import org.apache.james.mailbox.cassandra.modules.CassandraMailboxCounterModule;
import org.apache.james.mailbox.cassandra.modules.CassandraMailboxModule;
+import org.apache.james.mailbox.cassandra.modules.CassandraMailboxRecentsModule;
import org.apache.james.mailbox.cassandra.modules.CassandraMessageModule;
import org.apache.james.mailbox.cassandra.modules.CassandraModSeqModule;
import org.apache.james.mailbox.cassandra.modules.CassandraUidModule;
@@ -59,6 +60,7 @@ public class CassandraMapperProvider implements MapperProvider {
new CassandraMailboxModule(),
new CassandraMessageModule(),
new CassandraMailboxCounterModule(),
+ new CassandraMailboxRecentsModule(),
new CassandraModSeqModule(),
new CassandraUidModule(),
new CassandraAttachmentModule(),
@@ -100,7 +102,9 @@ public class CassandraMapperProvider implements MapperProvider {
cassandra.getTypesProvider(),
new CassandraMessageDAO(cassandra.getConf(), cassandra.getTypesProvider(), MESSAGE_ID_FACTORY),
new CassandraMessageIdDAO(cassandra.getConf(), MESSAGE_ID_FACTORY),
- new CassandraMessageIdToImapUidDAO(cassandra.getConf(), MESSAGE_ID_FACTORY));
+ new CassandraMessageIdToImapUidDAO(cassandra.getConf(), MESSAGE_ID_FACTORY),
+ new CassandraMailboxCounterDAO(cassandra.getConf()),
+ new CassandraMailboxRecentsDAO(cassandra.getConf()));
}
@Override
http://git-wip-us.apache.org/repos/asf/james-project/blob/c8c12826/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 16ef829..3b8b46c 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,8 @@ 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.CassandraMailboxCounterDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxRecentsDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO;
@@ -39,6 +41,7 @@ import org.apache.james.mailbox.cassandra.modules.CassandraAnnotationModule;
import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
import org.apache.james.mailbox.cassandra.modules.CassandraMailboxCounterModule;
import org.apache.james.mailbox.cassandra.modules.CassandraMailboxModule;
+import org.apache.james.mailbox.cassandra.modules.CassandraMailboxRecentsModule;
import org.apache.james.mailbox.cassandra.modules.CassandraMessageModule;
import org.apache.james.mailbox.cassandra.modules.CassandraModSeqModule;
import org.apache.james.mailbox.cassandra.modules.CassandraQuotaModule;
@@ -78,6 +81,7 @@ public class CassandraHostSystem extends JamesImapHostSystem {
new CassandraMailboxModule(),
new CassandraMessageModule(),
new CassandraMailboxCounterModule(),
+ new CassandraMailboxRecentsModule(),
new CassandraUidModule(),
new CassandraModSeqModule(),
new CassandraSubscriptionModule(),
@@ -94,9 +98,11 @@ public class CassandraHostSystem extends JamesImapHostSystem {
CassandraMessageDAO messageDAO = new CassandraMessageDAO(session, typesProvider, messageIdFactory);
CassandraMessageIdDAO messageIdDAO = new CassandraMessageIdDAO(session, messageIdFactory);
CassandraMessageIdToImapUidDAO imapUidDAO = new CassandraMessageIdToImapUidDAO(session, messageIdFactory);
+ CassandraMailboxCounterDAO mailboxCounterDAO = new CassandraMailboxCounterDAO(session);
+ CassandraMailboxRecentsDAO mailboxRecentsDAO = new CassandraMailboxRecentsDAO(session);
CassandraMailboxSessionMapperFactory mapperFactory = new CassandraMailboxSessionMapperFactory(uidProvider, modSeqProvider,
- session, typesProvider, messageDAO, messageIdDAO, imapUidDAO);
+ session, typesProvider, messageDAO, messageIdDAO, imapUidDAO, mailboxCounterDAO, mailboxRecentsDAO);
mailboxManager = new CassandraMailboxManager(mapperFactory, userManager, new JVMMailboxPathLocker(), new MessageParser(), messageIdFactory);
QuotaRootResolver quotaRootResolver = new DefaultQuotaRootResolver(mapperFactory);
http://git-wip-us.apache.org/repos/asf/james-project/blob/c8c12826/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 7ad3a28..df0693f 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
@@ -98,6 +98,7 @@ public class CassandraMailboxModule extends AbstractModule {
Multibinder<CassandraModule> cassandraDataDefinitions = Multibinder.newSetBinder(binder(), CassandraModule.class);
cassandraDataDefinitions.addBinding().to(org.apache.james.mailbox.cassandra.modules.CassandraAclModule.class);
cassandraDataDefinitions.addBinding().to(org.apache.james.mailbox.cassandra.modules.CassandraMailboxCounterModule.class);
+ cassandraDataDefinitions.addBinding().to(org.apache.james.mailbox.cassandra.modules.CassandraMailboxRecentsModule.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.CassandraSubscriptionModule.class);
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org