This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 05bd2f6a8620d64114ab3a0f4518c266c6fd6053 Author: Benoit Tellier <[email protected]> AuthorDate: Sun Apr 12 20:36:49 2020 +0700 JAMES-3148 Cleanup First Unseen DAO --- .../CassandraMailboxSessionMapperFactory.java | 2 +- .../mailbox/cassandra/DeleteMessageListener.java | 8 +++++- .../cassandra/mail/CassandraFirstUnseenDAO.java | 13 +++++++++ .../cassandra/CassandraMailboxManagerTest.java | 33 ++++++++++++++++++++++ .../mail/CassandraFirstUnseenDAOTest.java | 27 ++++++++++++++++++ 5 files changed, 81 insertions(+), 2 deletions(-) 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 62ccb3a..13a6d95 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 @@ -205,6 +205,6 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa public DeleteMessageListener deleteMessageListener() { return new DeleteMessageListener(imapUidDAO, messageIdDAO, messageDAO, attachmentDAOV2, ownerDAO, - attachmentMessageIdDAO, aclMapper, userMailboxRightsDAO, applicableFlagDAO); + attachmentMessageIdDAO, aclMapper, userMailboxRightsDAO, applicableFlagDAO, firstUnseenDAO); } } diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java index c4de8cc..7c24b4e 100644 --- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java @@ -33,6 +33,7 @@ import org.apache.james.mailbox.cassandra.mail.CassandraApplicableFlagDAO; import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAOV2; import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentMessageIdDAO; import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentOwnerDAO; +import org.apache.james.mailbox.cassandra.mail.CassandraFirstUnseenDAO; import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO; import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO; import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO; @@ -67,11 +68,14 @@ public class DeleteMessageListener implements MailboxListener.GroupMailboxListen private final CassandraACLMapper aclMapper; private final CassandraUserMailboxRightsDAO rightsDAO; private final CassandraApplicableFlagDAO applicableFlagDAO; + private final CassandraFirstUnseenDAO firstUnseenDAO; @Inject public DeleteMessageListener(CassandraMessageIdToImapUidDAO imapUidDAO, CassandraMessageIdDAO messageIdDAO, CassandraMessageDAO messageDAO, CassandraAttachmentDAOV2 attachmentDAO, CassandraAttachmentOwnerDAO ownerDAO, - CassandraAttachmentMessageIdDAO attachmentMessageIdDAO, CassandraACLMapper aclMapper, CassandraUserMailboxRightsDAO rightsDAO, CassandraApplicableFlagDAO applicableFlagDAO) { + CassandraAttachmentMessageIdDAO attachmentMessageIdDAO, CassandraACLMapper aclMapper, + CassandraUserMailboxRightsDAO rightsDAO, CassandraApplicableFlagDAO applicableFlagDAO, + CassandraFirstUnseenDAO firstUnseenDAO) { this.imapUidDAO = imapUidDAO; this.messageIdDAO = messageIdDAO; this.messageDAO = messageDAO; @@ -81,6 +85,7 @@ public class DeleteMessageListener implements MailboxListener.GroupMailboxListen this.aclMapper = aclMapper; this.rightsDAO = rightsDAO; this.applicableFlagDAO = applicableFlagDAO; + this.firstUnseenDAO = firstUnseenDAO; } @Override @@ -118,6 +123,7 @@ public class DeleteMessageListener implements MailboxListener.GroupMailboxListen .then(messageIdDAO.delete(mailboxId, metadata.getUid()))) .then(deleteAcl(mailboxId)) .then(applicableFlagDAO.delete(mailboxId)) + .then(firstUnseenDAO.removeAll(mailboxId)) .block(); } } diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraFirstUnseenDAO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraFirstUnseenDAO.java index 94fc03b..d3fffc2 100644 --- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraFirstUnseenDAO.java +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraFirstUnseenDAO.java @@ -44,6 +44,7 @@ public class CassandraFirstUnseenDAO { private final CassandraAsyncExecutor cassandraAsyncExecutor; private final PreparedStatement addStatement; private final PreparedStatement deleteStatement; + private final PreparedStatement deleteAllStatement; private final PreparedStatement readStatement; @Inject @@ -51,6 +52,7 @@ public class CassandraFirstUnseenDAO { this.cassandraAsyncExecutor = new CassandraAsyncExecutor(session); this.addStatement = prepareAddStatement(session); this.deleteStatement = prepareDeleteStatement(session); + this.deleteAllStatement = prepareDeleteAllStatement(session); this.readStatement = prepareReadStatement(session); } @@ -69,6 +71,12 @@ public class CassandraFirstUnseenDAO { .and(eq(UID, bindMarker(UID)))); } + private PreparedStatement prepareDeleteAllStatement(Session session) { + return session.prepare(delete() + .from(TABLE_NAME) + .where(eq(MAILBOX_ID, bindMarker(MAILBOX_ID)))); + } + private PreparedStatement prepareAddStatement(Session session) { return session.prepare(insertInto(TABLE_NAME) .value(MAILBOX_ID, bindMarker(MAILBOX_ID)) @@ -88,6 +96,11 @@ public class CassandraFirstUnseenDAO { .setLong(UID, uid.asLong())); } + public Mono<Void> removeAll(CassandraId cassandraId) { + return cassandraAsyncExecutor.executeVoid(deleteAllStatement.bind() + .setUUID(MAILBOX_ID, cassandraId.asUuid())); + } + public Mono<MessageUid> retrieveFirstUnread(CassandraId cassandraId) { return cassandraAsyncExecutor.executeSingleRow( readStatement.bind() 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 de77b65..56d9221 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 @@ -45,6 +45,7 @@ import org.apache.james.mailbox.cassandra.mail.CassandraApplicableFlagDAO; import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAOV2; import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentMessageIdDAO; import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentOwnerDAO; +import org.apache.james.mailbox.cassandra.mail.CassandraFirstUnseenDAO; import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO; import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO; import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO; @@ -613,6 +614,38 @@ public class CassandraMailboxManagerTest extends MailboxManagerTest<CassandraMai .isEmpty(); } + @Test + void deleteMailboxShouldCleanUpFirstUnseenWhenFail(CassandraCluster cassandraCluster) throws Exception { + inboxManager.appendMessage(MessageManager.AppendCommand.builder() + .withFlags(new Flags()) + .build(ClassLoaderUtils.getSystemResourceAsByteArray("eml/emailWithOnlyAttachment.eml")), session); + + mailboxManager.deleteMailbox(inbox, session); + + assertThat(firstUnseenDAO(cassandraCluster).retrieveFirstUnread((CassandraId) inboxId).blockOptional()) + .isEmpty(); + } + + @Test + void deleteMailboxShouldCleanUpFirstUnseen(CassandraCluster cassandraCluster) throws Exception { + inboxManager.appendMessage(MessageManager.AppendCommand.builder() + .withFlags(new Flags()) + .build(ClassLoaderUtils.getSystemResourceAsByteArray("eml/emailWithOnlyAttachment.eml")), session); + + cassandraCluster.getConf().registerScenario(fail() + .times(1) + .whenQueryStartsWith("DELETE FROM firstUnseen WHERE mailboxId=:mailboxId;")); + + mailboxManager.deleteMailbox(inbox, session); + + assertThat(firstUnseenDAO(cassandraCluster).retrieveFirstUnread((CassandraId) inboxId).blockOptional()) + .isEmpty(); + } + + private CassandraFirstUnseenDAO firstUnseenDAO(CassandraCluster cassandraCluster) { + return new CassandraFirstUnseenDAO(cassandraCluster.getConf()); + } + private CassandraApplicableFlagDAO applicableFlagDAO(CassandraCluster cassandraCluster) { return new CassandraApplicableFlagDAO(cassandraCluster.getConf()); } diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraFirstUnseenDAOTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraFirstUnseenDAOTest.java index 882ed3c..f9f54aa 100644 --- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraFirstUnseenDAOTest.java +++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraFirstUnseenDAOTest.java @@ -20,6 +20,7 @@ package org.apache.james.mailbox.cassandra.mail; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; import org.apache.james.backends.cassandra.CassandraCluster; import org.apache.james.backends.cassandra.CassandraClusterExtension; @@ -60,6 +61,32 @@ class CassandraFirstUnseenDAOTest { } @Test + void addUnreadShouldNotReturnRemovedEntries() { + testee.addUnread(MAILBOX_ID, UID_1).block(); + + testee.removeAll(MAILBOX_ID).block(); + + assertThat(testee.retrieveFirstUnread(MAILBOX_ID).blockOptional()) + .isEmpty(); + } + + @Test + void removeAllShouldDeleteAllUidEntries() { + testee.addUnread(MAILBOX_ID, UID_1).block(); + testee.addUnread(MAILBOX_ID, UID_2).block(); + + testee.removeAll(MAILBOX_ID).block(); + + assertThat(testee.retrieveFirstUnread(MAILBOX_ID).blockOptional()) + .isEmpty(); + } + + @Test + void removeAllShouldNotThrowWhenAbsent() { + assertThatCode(() -> testee.removeAll(MAILBOX_ID).block()).doesNotThrowAnyException(); + } + + @Test void retrieveFirstUnreadShouldReturnLowestUnreadUid() { testee.addUnread(MAILBOX_ID, UID_1).block(); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
