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 a42e36ecd7fd6ea24f06735065ce7adb2090ee29 Author: Benoit Tellier <[email protected]> AuthorDate: Sun Apr 12 14:36:30 2020 +0700 JAMES-3148 Add a listener for cleaning mailbox/cassandra upon deletions --- .../apache/james/mailbox/MailboxManagerTest.java | 4 +- .../CassandraMailboxSessionMapperFactory.java | 4 + .../mailbox/cassandra/DeleteMessageListener.java | 145 ++++++++++++ .../cassandra/mail/CassandraMessageDAO.java | 4 +- .../cassandra/CassandraMailboxManagerProvider.java | 1 + .../cassandra/CassandraMailboxManagerTest.java | 255 +++++++++++++++++++++ .../cassandra/CassandraTestSystemFixture.java | 1 + .../modules/mailbox/CassandraMailboxModule.java | 7 +- 8 files changed, 414 insertions(+), 7 deletions(-) diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java index f3dfaa4..28f5f94 100644 --- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java +++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java @@ -111,9 +111,9 @@ public abstract class MailboxManagerTest<T extends MailboxManager> { public static final Username USER_2 = Username.of("USER_2"); private static final int DEFAULT_MAXIMUM_LIMIT = 256; - private T mailboxManager; + protected T mailboxManager; private MailboxSession session; - private Message.Builder message; + protected Message.Builder message; private PreDeletionHook preDeletionHook1; private PreDeletionHook preDeletionHook2; 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 c4177b6..7d29e36 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 @@ -202,4 +202,8 @@ public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFa } return mapper; } + + public DeleteMessageListener deleteMessageListener() { + return new DeleteMessageListener(imapUidDAO, messageIdDAO, messageDAO, attachmentDAOV2, ownerDAO, attachmentMessageIdDAO); + } } 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 new file mode 100644 index 0000000..15d7b35 --- /dev/null +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java @@ -0,0 +1,145 @@ +/**************************************************************** + * 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; + +import static org.apache.james.util.FunctionalUtils.negate; + +import java.util.Optional; + +import javax.inject.Inject; + +import org.apache.james.mailbox.cassandra.ids.CassandraId; +import org.apache.james.mailbox.cassandra.ids.CassandraMessageId; +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.CassandraMessageDAO; +import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO; +import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO; +import org.apache.james.mailbox.cassandra.mail.MessageAttachmentRepresentation; +import org.apache.james.mailbox.cassandra.mail.MessageRepresentation; +import org.apache.james.mailbox.events.Event; +import org.apache.james.mailbox.events.Group; +import org.apache.james.mailbox.events.MailboxListener; +import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData; +import org.apache.james.mailbox.model.MessageMetaData; +import org.apache.james.mailbox.model.MessageRange; +import org.apache.james.mailbox.store.mail.MessageMapper; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public class DeleteMessageListener implements MailboxListener.GroupMailboxListener { + private static final Optional<CassandraId> ALL_MAILBOXES = Optional.empty(); + + public static class DeleteMessageListenerGroup extends Group { + + } + + @Inject + public DeleteMessageListener(CassandraMessageIdToImapUidDAO imapUidDAO, CassandraMessageIdDAO messageIdDAO, CassandraMessageDAO messageDAO, + CassandraAttachmentDAOV2 attachmentDAO, CassandraAttachmentOwnerDAO ownerDAO, + CassandraAttachmentMessageIdDAO attachmentMessageIdDAO) { + this.imapUidDAO = imapUidDAO; + this.messageIdDAO = messageIdDAO; + this.messageDAO = messageDAO; + this.attachmentDAO = attachmentDAO; + this.ownerDAO = ownerDAO; + this.attachmentMessageIdDAO = attachmentMessageIdDAO; + } + + private final CassandraMessageIdToImapUidDAO imapUidDAO; + private final CassandraMessageIdDAO messageIdDAO; + private final CassandraMessageDAO messageDAO; + private final CassandraAttachmentDAOV2 attachmentDAO; + private final CassandraAttachmentOwnerDAO ownerDAO; + private final CassandraAttachmentMessageIdDAO attachmentMessageIdDAO; + + @Override + public Group getDefaultGroup() { + return new DeleteMessageListenerGroup(); + } + + @Override + public boolean isHandling(Event event) { + return event instanceof Expunged || event instanceof MailboxDeletion; + } + + @Override + public void event(Event event) { + if (event instanceof Expunged) { + Expunged expunged = (Expunged) event; + + Flux.fromIterable(expunged.getExpunged() + .values()) + .map(MessageMetaData::getMessageId) + .map(CassandraMessageId.class::cast) + .concatMap(this::handleDeletion) + .then() + .block(); + } + if (event instanceof MailboxDeletion) { + MailboxDeletion mailboxDeletion = (MailboxDeletion) event; + + CassandraId mailboxId = (CassandraId) mailboxDeletion.getMailboxId(); + + messageIdDAO.retrieveMessages(mailboxId, MessageRange.all()) + .map(ComposedMessageIdWithMetaData::getComposedMessageId) + .concatMap(metadata -> imapUidDAO.delete((CassandraMessageId) metadata.getMessageId(), mailboxId) + .then(messageIdDAO.delete(mailboxId, metadata.getUid())) + .then(handleDeletion((CassandraMessageId) metadata.getMessageId()))) + .then() + .block(); + } + } + + private Mono<Void> handleDeletion(CassandraMessageId messageId) { + return Mono.just(messageId) + .filterWhen(this::isReferenced) + .flatMap(id -> readMessage(id) + .flatMap(this::deleteUnreferencedAttachments) + .then(messageDAO.delete(messageId))); + } + + private Mono<MessageRepresentation> readMessage(CassandraMessageId id) { + return messageDAO.retrieveMessage(id, MessageMapper.FetchType.Metadata); + } + + private Mono<Void> deleteUnreferencedAttachments(MessageRepresentation message) { + return Flux.fromIterable(message.getAttachments()) + .filterWhen(attachment -> ownerDAO.retrieveOwners(attachment.getAttachmentId()).hasElements().map(negate())) + .filterWhen(attachment -> hasOtherMessagesReferences(message, attachment)) + .concatMap(attachment -> attachmentDAO.delete(attachment.getAttachmentId())) + .then(); + } + + private Mono<Boolean> hasOtherMessagesReferences(MessageRepresentation message, MessageAttachmentRepresentation attachment) { + return attachmentMessageIdDAO.getOwnerMessageIds(attachment.getAttachmentId()) + .filter(messageId -> !message.getMessageId().equals(messageId)) + .hasElements() + .map(negate()); + } + + private Mono<Boolean> isReferenced(CassandraMessageId id) { + return imapUidDAO.retrieve(id, ALL_MAILBOXES) + .hasElements() + .map(negate()); + } +} diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java index baa1466..800b296 100644 --- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java @@ -227,10 +227,10 @@ public class CassandraMessageDAO { public Mono<MessageRepresentation> retrieveMessage(ComposedMessageIdWithMetaData id, FetchType fetchType) { CassandraMessageId cassandraMessageId = (CassandraMessageId) id.getComposedMessageId().getMessageId(); - return retrieveMessage(fetchType, cassandraMessageId); + return retrieveMessage(cassandraMessageId, fetchType); } - private Mono<MessageRepresentation> retrieveMessage(FetchType fetchType, CassandraMessageId cassandraMessageId) { + public Mono<MessageRepresentation> retrieveMessage(CassandraMessageId cassandraMessageId, FetchType fetchType) { return retrieveRow(cassandraMessageId, fetchType) .flatMap(resultSet -> message(resultSet, cassandraMessageId, fetchType)); } diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerProvider.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerProvider.java index ab3dc5d..42ea282 100644 --- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerProvider.java +++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerProvider.java @@ -107,6 +107,7 @@ public class CassandraMailboxManagerProvider { eventBus.register(quotaUpdater); eventBus.register(new MailboxAnnotationListener(mapperFactory, sessionProvider)); + eventBus.register(mapperFactory.deleteMessageListener()); return manager; } 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 5cd44e3..55eeb7c 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 @@ -18,13 +18,49 @@ ****************************************************************/ package org.apache.james.mailbox.cassandra; +import static org.mockito.Mockito.mock; + +import java.util.Collection; +import java.util.Optional; + +import org.apache.james.backends.cassandra.CassandraCluster; import org.apache.james.backends.cassandra.CassandraClusterExtension; +import org.apache.james.blob.api.BlobStore; +import org.apache.james.blob.api.HashBlobId; +import org.apache.james.core.Username; import org.apache.james.mailbox.MailboxManagerTest; +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.MessageManager; +import org.apache.james.mailbox.cassandra.ids.CassandraId; +import org.apache.james.mailbox.cassandra.ids.CassandraMessageId; +import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAOV2; +import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentOwnerDAO; +import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO; +import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO; +import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO; import org.apache.james.mailbox.cassandra.mail.MailboxAggregateModule; import org.apache.james.mailbox.events.EventBus; +import org.apache.james.mailbox.model.AttachmentId; +import org.apache.james.mailbox.model.ComposedMessageId; +import org.apache.james.mailbox.model.FetchGroup; +import org.apache.james.mailbox.model.MailboxId; +import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.model.MessageAttachment; +import org.apache.james.mailbox.model.MessageRange; +import org.apache.james.mailbox.model.MessageResult; import org.apache.james.mailbox.store.PreDeletionHooks; +import org.apache.james.mailbox.store.mail.MessageMapper; import org.apache.james.metrics.tests.RecordingMetricFactory; +import org.apache.james.util.ClassLoaderUtils; +import org.apache.james.util.streams.Iterators; +import org.assertj.core.api.SoftAssertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.testcontainers.shaded.com.google.common.collect.ImmutableList; + +import com.github.fge.lambdas.Throwing; public class CassandraMailboxManagerTest extends MailboxManagerTest<CassandraMailboxManager> { @RegisterExtension @@ -41,4 +77,223 @@ public class CassandraMailboxManagerTest extends MailboxManagerTest<CassandraMai protected EventBus retrieveEventBus(CassandraMailboxManager mailboxManager) { return mailboxManager.getEventBus(); } + + @Nested + class DeletionTests { + private MailboxSession session; + private MailboxPath inbox; + private MailboxId inboxId; + private MessageManager inboxManager; + private MessageManager otherBoxManager; + private MailboxPath newPath; + + @BeforeEach + void setUp() throws Exception { + session = mailboxManager.createSystemSession(USER_1); + inbox = MailboxPath.inbox(session); + newPath = MailboxPath.forUser(USER_1, "specialMailbox"); + + inboxId = mailboxManager.createMailbox(inbox, session).get(); + inboxManager = mailboxManager.getMailbox(inbox, session); + MailboxId otherId = mailboxManager.createMailbox(newPath, session).get(); + otherBoxManager = mailboxManager.getMailbox(otherId, session); + } + + @Test + void deleteMailboxShouldUnreferenceMessageMetadata(CassandraCluster cassandraCluster) throws Exception { + ComposedMessageId composedMessageId = inboxManager.appendMessage(MessageManager.AppendCommand.builder() + .build(ClassLoaderUtils.getSystemResourceAsByteArray("eml/emailWithOnlyAttachment.eml")), session); + + AttachmentId attachmentId = Iterators.toStream(inboxManager.getMessages(MessageRange.all(), FetchGroup.FULL_CONTENT, session)) + .map(Throwing.function(MessageResult::getLoadedAttachments)) + .flatMap(Collection::stream) + .map(MessageAttachment::getAttachmentId) + .findFirst() + .get(); + + mailboxManager.deleteMailbox(inbox, session); + + SoftAssertions.assertSoftly(softly -> { + CassandraMessageId cassandraMessageId = (CassandraMessageId) composedMessageId.getMessageId(); + CassandraId mailboxId = (CassandraId) composedMessageId.getMailboxId(); + + softly.assertThat(messageDAO(cassandraCluster).retrieveMessage(cassandraMessageId, MessageMapper.FetchType.Metadata) + .blockOptional()).isEmpty(); + + softly.assertThat(imapUidDAO(cassandraCluster).retrieve(cassandraMessageId, Optional.of(mailboxId)).collectList().block()) + .isEmpty(); + + softly.assertThat(messageIdDAO(cassandraCluster).retrieveMessages(mailboxId, MessageRange.all()).collectList().block()) + .isEmpty(); + + softly.assertThat(attachmentDAO(cassandraCluster).getAttachment(attachmentId).blockOptional()) + .isEmpty(); + }); + } + + @Test + void deleteShouldUnreferenceMessageMetadata(CassandraCluster cassandraCluster) throws Exception { + ComposedMessageId composedMessageId = inboxManager.appendMessage(MessageManager.AppendCommand.builder() + .build(ClassLoaderUtils.getSystemResourceAsByteArray("eml/emailWithOnlyAttachment.eml")), session); + + AttachmentId attachmentId = Iterators.toStream(inboxManager.getMessages(MessageRange.all(), FetchGroup.FULL_CONTENT, session)) + .map(Throwing.function(MessageResult::getLoadedAttachments)) + .flatMap(Collection::stream) + .map(MessageAttachment::getAttachmentId) + .findFirst() + .get(); + + inboxManager.delete(ImmutableList.of(composedMessageId.getUid()), session); + + SoftAssertions.assertSoftly(softly -> { + CassandraMessageId cassandraMessageId = (CassandraMessageId) composedMessageId.getMessageId(); + + softly.assertThat(messageDAO(cassandraCluster).retrieveMessage(cassandraMessageId, MessageMapper.FetchType.Metadata) + .blockOptional()).isEmpty(); + + softly.assertThat(attachmentDAO(cassandraCluster).getAttachment(attachmentId).blockOptional()) + .isEmpty(); + }); + } + + @Test + void deleteMailboxShouldNotUnreferenceMessageMetadataWhenOtherReference(CassandraCluster cassandraCluster) throws Exception { + ComposedMessageId composedMessageId = inboxManager.appendMessage(MessageManager.AppendCommand.builder() + .build(ClassLoaderUtils.getSystemResourceAsByteArray("eml/emailWithOnlyAttachment.eml")), session); + + AttachmentId attachmentId = Iterators.toStream(inboxManager.getMessages(MessageRange.all(), FetchGroup.FULL_CONTENT, session)) + .map(Throwing.function(MessageResult::getLoadedAttachments)) + .flatMap(Collection::stream) + .map(MessageAttachment::getAttachmentId) + .findFirst() + .get(); + + mailboxManager.copyMessages(MessageRange.all(), inboxId, otherBoxManager.getId(), session); + + mailboxManager.deleteMailbox(inbox, session); + + SoftAssertions.assertSoftly(softly -> { + CassandraMessageId cassandraMessageId = (CassandraMessageId) composedMessageId.getMessageId(); + CassandraId mailboxId = (CassandraId) composedMessageId.getMailboxId(); + + softly.assertThat(messageDAO(cassandraCluster).retrieveMessage(cassandraMessageId, MessageMapper.FetchType.Metadata) + .blockOptional()).isPresent(); + + softly.assertThat(imapUidDAO(cassandraCluster).retrieve(cassandraMessageId, Optional.of(mailboxId)).collectList().block()) + .isEmpty(); + + softly.assertThat(messageIdDAO(cassandraCluster).retrieveMessages(mailboxId, MessageRange.all()).collectList().block()) + .isEmpty(); + + softly.assertThat(attachmentDAO(cassandraCluster).getAttachment(attachmentId).blockOptional()) + .isPresent(); + }); + } + + @Test + void deleteShouldNotUnreferenceMessageMetadataWhenOtherReference(CassandraCluster cassandraCluster) throws Exception { + ComposedMessageId composedMessageId = inboxManager.appendMessage(MessageManager.AppendCommand.builder() + .build(ClassLoaderUtils.getSystemResourceAsByteArray("eml/emailWithOnlyAttachment.eml")), session); + + AttachmentId attachmentId = Iterators.toStream(inboxManager.getMessages(MessageRange.all(), FetchGroup.FULL_CONTENT, session)) + .map(Throwing.function(MessageResult::getLoadedAttachments)) + .flatMap(Collection::stream) + .map(MessageAttachment::getAttachmentId) + .findFirst() + .get(); + + mailboxManager.copyMessages(MessageRange.all(), inboxId, otherBoxManager.getId(), session); + + inboxManager.delete(ImmutableList.of(composedMessageId.getUid()), session); + + SoftAssertions.assertSoftly(softly -> { + CassandraMessageId cassandraMessageId = (CassandraMessageId) composedMessageId.getMessageId(); + + softly.assertThat(messageDAO(cassandraCluster).retrieveMessage(cassandraMessageId, MessageMapper.FetchType.Metadata) + .blockOptional()).isPresent(); + + softly.assertThat(attachmentDAO(cassandraCluster).getAttachment(attachmentId).blockOptional()) + .isPresent(); + }); + } + + @Test + void deleteMailboxShouldNotUnreferenceAttachmentWhenOtherReference(CassandraCluster cassandraCluster) throws Exception { + ComposedMessageId composedMessageId = inboxManager.appendMessage(MessageManager.AppendCommand.builder() + .build(ClassLoaderUtils.getSystemResourceAsByteArray("eml/emailWithOnlyAttachment.eml")), session); + + AttachmentId attachmentId = Iterators.toStream(inboxManager.getMessages(MessageRange.all(), FetchGroup.FULL_CONTENT, session)) + .map(Throwing.function(MessageResult::getLoadedAttachments)) + .flatMap(Collection::stream) + .map(MessageAttachment::getAttachmentId) + .findFirst() + .get(); + + new CassandraAttachmentOwnerDAO(cassandraCluster.getConf()).addOwner(attachmentId, Username.of("bob")).block(); + + mailboxManager.deleteMailbox(inbox, session); + + SoftAssertions.assertSoftly(softly -> { + CassandraMessageId cassandraMessageId = (CassandraMessageId) composedMessageId.getMessageId(); + CassandraId mailboxId = (CassandraId) composedMessageId.getMailboxId(); + + softly.assertThat(messageDAO(cassandraCluster).retrieveMessage(cassandraMessageId, MessageMapper.FetchType.Metadata) + .blockOptional()).isEmpty(); + + softly.assertThat(imapUidDAO(cassandraCluster).retrieve(cassandraMessageId, Optional.of(mailboxId)).collectList().block()) + .isEmpty(); + + softly.assertThat(messageIdDAO(cassandraCluster).retrieveMessages(mailboxId, MessageRange.all()).collectList().block()) + .isEmpty(); + + softly.assertThat(attachmentDAO(cassandraCluster).getAttachment(attachmentId).blockOptional()) + .isPresent(); + }); + } + + @Test + void deleteShouldNotUnreferenceAttachmentWhenOtherReference(CassandraCluster cassandraCluster) throws Exception { + ComposedMessageId composedMessageId = inboxManager.appendMessage(MessageManager.AppendCommand.builder() + .build(ClassLoaderUtils.getSystemResourceAsByteArray("eml/emailWithOnlyAttachment.eml")), session); + + AttachmentId attachmentId = Iterators.toStream(inboxManager.getMessages(MessageRange.all(), FetchGroup.FULL_CONTENT, session)) + .map(Throwing.function(MessageResult::getLoadedAttachments)) + .flatMap(Collection::stream) + .map(MessageAttachment::getAttachmentId) + .findFirst() + .get(); + + new CassandraAttachmentOwnerDAO(cassandraCluster.getConf()).addOwner(attachmentId, Username.of("bob")).block(); + + inboxManager.delete(ImmutableList.of(composedMessageId.getUid()), session); + + SoftAssertions.assertSoftly(softly -> { + CassandraMessageId cassandraMessageId = (CassandraMessageId) composedMessageId.getMessageId(); + CassandraId mailboxId = (CassandraId) composedMessageId.getMailboxId(); + + softly.assertThat(messageDAO(cassandraCluster).retrieveMessage(cassandraMessageId, MessageMapper.FetchType.Metadata) + .blockOptional()).isEmpty(); + + softly.assertThat(attachmentDAO(cassandraCluster).getAttachment(attachmentId).blockOptional()) + .isPresent(); + }); + } + + private CassandraAttachmentDAOV2 attachmentDAO(CassandraCluster cassandraCluster) { + return new CassandraAttachmentDAOV2(new HashBlobId.Factory(), cassandraCluster.getConf()); + } + + private CassandraMessageIdDAO messageIdDAO(CassandraCluster cassandraCluster) { + return new CassandraMessageIdDAO(cassandraCluster.getConf(), new CassandraMessageId.Factory()); + } + + private CassandraMessageIdToImapUidDAO imapUidDAO(CassandraCluster cassandraCluster) { + return new CassandraMessageIdToImapUidDAO(cassandraCluster.getConf(), new CassandraMessageId.Factory()); + } + + private CassandraMessageDAO messageDAO(CassandraCluster cassandraCluster) { + return new CassandraMessageDAO(cassandraCluster.getConf(), cassandraCluster.getTypesProvider(), + mock(BlobStore.class), new HashBlobId.Factory(), new CassandraMessageId.Factory()); + } + } } 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 6524206..dea017b 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 @@ -80,6 +80,7 @@ public class CassandraTestSystemFixture { eventBus, annotationManager, storeRightManager, quotaComponents, index, MailboxManagerConfiguration.DEFAULT, PreDeletionHooks.NO_PRE_DELETION_HOOK); eventBus.register(new MailboxAnnotationListener(mapperFactory, sessionProvider)); + eventBus.register(mapperFactory.deleteMessageListener()); return cassandraMailboxManager; } 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 7630f5e..a3a0742 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 @@ -38,6 +38,7 @@ import org.apache.james.mailbox.SessionProvider; 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.DeleteMessageListener; import org.apache.james.mailbox.cassandra.ids.CassandraId; import org.apache.james.mailbox.cassandra.ids.CassandraMessageId; import org.apache.james.mailbox.cassandra.mail.CassandraACLMapper; @@ -192,9 +193,9 @@ public class CassandraMailboxModule extends AbstractModule { Multibinder.newSetBinder(binder(), MailboxManagerDefinition.class).addBinding().to(CassandraMailboxManagerDefinition.class); - Multibinder.newSetBinder(binder(), MailboxListener.GroupMailboxListener.class) - .addBinding() - .to(MailboxAnnotationListener.class); + Multibinder<MailboxListener.GroupMailboxListener> mailboxListeners = Multibinder.newSetBinder(binder(), MailboxListener.GroupMailboxListener.class); + mailboxListeners.addBinding().to(MailboxAnnotationListener.class); + mailboxListeners.addBinding().to(DeleteMessageListener.class); bind(MailboxManager.class).annotatedWith(Names.named(MAILBOXMANAGER_NAME)).to(MailboxManager.class); } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
