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 bt...@apache.org on 2020/05/07 02:12:40 UTC
[james-project] 16/22: JAMES-3148 Cleanup Deleted Messages DAO
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 03d0cf4b19c4efe4902e7c4ecf4409f61238de03
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Sun Apr 12 20:47:22 2020 +0700
JAMES-3148 Cleanup Deleted Messages DAO
---
.../CassandraMailboxSessionMapperFactory.java | 2 +-
.../mailbox/cassandra/DeleteMessageListener.java | 6 +++-
.../cassandra/mail/CassandraDeletedMessageDAO.java | 13 ++++++++
.../cassandra/CassandraMailboxManagerTest.java | 35 ++++++++++++++++++++++
.../mail/CassandraDeletedMessageDAOTest.java | 20 +++++++++++++
5 files changed, 74 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 13a6d95..ba80ed4 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, firstUnseenDAO);
+ attachmentMessageIdDAO, aclMapper, userMailboxRightsDAO, applicableFlagDAO, firstUnseenDAO, deletedMessageDAO);
}
}
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 7c24b4e..c0f74d9 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.CassandraDeletedMessageDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraFirstUnseenDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
@@ -69,13 +70,14 @@ public class DeleteMessageListener implements MailboxListener.GroupMailboxListen
private final CassandraUserMailboxRightsDAO rightsDAO;
private final CassandraApplicableFlagDAO applicableFlagDAO;
private final CassandraFirstUnseenDAO firstUnseenDAO;
+ private final CassandraDeletedMessageDAO deletedMessageDAO;
@Inject
public DeleteMessageListener(CassandraMessageIdToImapUidDAO imapUidDAO, CassandraMessageIdDAO messageIdDAO, CassandraMessageDAO messageDAO,
CassandraAttachmentDAOV2 attachmentDAO, CassandraAttachmentOwnerDAO ownerDAO,
CassandraAttachmentMessageIdDAO attachmentMessageIdDAO, CassandraACLMapper aclMapper,
CassandraUserMailboxRightsDAO rightsDAO, CassandraApplicableFlagDAO applicableFlagDAO,
- CassandraFirstUnseenDAO firstUnseenDAO) {
+ CassandraFirstUnseenDAO firstUnseenDAO, CassandraDeletedMessageDAO deletedMessageDAO) {
this.imapUidDAO = imapUidDAO;
this.messageIdDAO = messageIdDAO;
this.messageDAO = messageDAO;
@@ -86,6 +88,7 @@ public class DeleteMessageListener implements MailboxListener.GroupMailboxListen
this.rightsDAO = rightsDAO;
this.applicableFlagDAO = applicableFlagDAO;
this.firstUnseenDAO = firstUnseenDAO;
+ this.deletedMessageDAO = deletedMessageDAO;
}
@Override
@@ -124,6 +127,7 @@ public class DeleteMessageListener implements MailboxListener.GroupMailboxListen
.then(deleteAcl(mailboxId))
.then(applicableFlagDAO.delete(mailboxId))
.then(firstUnseenDAO.removeAll(mailboxId))
+ .then(deletedMessageDAO.removeAll(mailboxId))
.block();
}
}
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraDeletedMessageDAO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraDeletedMessageDAO.java
index cfdebae..8e45984 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraDeletedMessageDAO.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraDeletedMessageDAO.java
@@ -53,6 +53,7 @@ public class CassandraDeletedMessageDAO {
private final CassandraAsyncExecutor cassandraAsyncExecutor;
private final PreparedStatement addStatement;
private final PreparedStatement deleteStatement;
+ private final PreparedStatement deleteAllStatement;
private final PreparedStatement selectAllUidStatement;
private final PreparedStatement selectOneUidStatement;
@@ -65,6 +66,7 @@ public class CassandraDeletedMessageDAO {
this.cassandraAsyncExecutor = new CassandraAsyncExecutor(session);
this.addStatement = prepareAddStatement(session);
this.deleteStatement = prepareDeleteStatement(session);
+ this.deleteAllStatement = prepareDeleteAllStatement(session);
this.selectAllUidStatement = prepareAllUidStatement(session);
this.selectOneUidStatement = prepareOneUidStatement(session);
this.selectBetweenUidStatement = prepareBetweenUidStatement(session);
@@ -112,6 +114,12 @@ public class CassandraDeletedMessageDAO {
.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))
@@ -131,6 +139,11 @@ public class CassandraDeletedMessageDAO {
.setLong(UID, uid.asLong()));
}
+ public Mono<Void> removeAll(CassandraId cassandraId) {
+ return cassandraAsyncExecutor.executeVoid(deleteAllStatement.bind()
+ .setUUID(MAILBOX_ID, cassandraId.asUuid()));
+ }
+
public Flux<MessageUid> retrieveDeletedMessage(CassandraId cassandraId, MessageRange range) {
return retrieveResultSetOfDeletedMessage(cassandraId, range)
.flatMapMany(this::resultSetToFlux);
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 56d9221..5f78c72 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.CassandraDeletedMessageDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraFirstUnseenDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
@@ -642,6 +643,40 @@ public class CassandraMailboxManagerTest extends MailboxManagerTest<CassandraMai
.isEmpty();
}
+ @Test
+ void deleteMailboxShouldCleanUpDeletedMessages(CassandraCluster cassandraCluster) throws Exception {
+ inboxManager.appendMessage(MessageManager.AppendCommand.builder()
+ .withFlags(new Flags(Flags.Flag.DELETED))
+ .build(ClassLoaderUtils.getSystemResourceAsByteArray("eml/emailWithOnlyAttachment.eml")), session);
+
+ mailboxManager.deleteMailbox(inbox, session);
+
+ assertThat(deletedMessageDAO(cassandraCluster).retrieveDeletedMessage((CassandraId) inboxId, MessageRange.all())
+ .collectList().block())
+ .isEmpty();
+ }
+
+ @Test
+ void deleteMailboxShouldCleanUpDeletedMessagesWhenFailure(CassandraCluster cassandraCluster) throws Exception {
+ inboxManager.appendMessage(MessageManager.AppendCommand.builder()
+ .withFlags(new Flags(Flags.Flag.DELETED))
+ .build(ClassLoaderUtils.getSystemResourceAsByteArray("eml/emailWithOnlyAttachment.eml")), session);
+
+ cassandraCluster.getConf().registerScenario(fail()
+ .times(1)
+ .whenQueryStartsWith("DELETE FROM messageDeleted WHERE mailboxId=:mailboxId;"));
+
+ mailboxManager.deleteMailbox(inbox, session);
+
+ assertThat(deletedMessageDAO(cassandraCluster).retrieveDeletedMessage((CassandraId) inboxId, MessageRange.all())
+ .collectList().block())
+ .isEmpty();
+ }
+
+ private CassandraDeletedMessageDAO deletedMessageDAO(CassandraCluster cassandraCluster) {
+ return new CassandraDeletedMessageDAO(cassandraCluster.getConf());
+ }
+
private CassandraFirstUnseenDAO firstUnseenDAO(CassandraCluster cassandraCluster) {
return new CassandraFirstUnseenDAO(cassandraCluster.getConf());
}
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraDeletedMessageDAOTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraDeletedMessageDAOTest.java
index 6197506..f3154fe 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraDeletedMessageDAOTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraDeletedMessageDAOTest.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 java.util.List;
import java.util.UUID;
@@ -76,6 +77,25 @@ class CassandraDeletedMessageDAOTest {
}
@Test
+ void retrieveDeletedMessageShouldNotReturnDeletedEntries() {
+ testee.addDeleted(MAILBOX_ID, UID_1).block();
+ testee.addDeleted(MAILBOX_ID, UID_2).block();
+
+ testee.removeAll(MAILBOX_ID).block();
+
+ List<MessageUid> result = testee.retrieveDeletedMessage(MAILBOX_ID, MessageRange.all())
+ .collectList()
+ .block();
+
+ assertThat(result).isEmpty();
+ }
+
+ @Test
+ void removeAllShouldNotThrowWhenEmpty() {
+ assertThatCode(() -> testee.removeAll(MAILBOX_ID).block()).doesNotThrowAnyException();
+ }
+
+ @Test
void addDeletedMessageShouldBeIdempotent() {
testee.addDeleted(MAILBOX_ID, UID_1).block();
testee.addDeleted(MAILBOX_ID, UID_1).block();
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org