You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2021/03/11 05:05:29 UTC

[james-project] 12/15: JAMES-3513 Wrong UID dispatched on the EventBus for StoreMessageIdManager::setInMailboxes

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 87470268c5d44ec208643ad2fa7553d4259bb636
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Mar 8 13:40:51 2021 +0700

    JAMES-3513 Wrong UID dispatched on the EventBus for StoreMessageIdManager::setInMailboxes
    
    ```
    Given msg1 in mbx1 with uid 12 and in mbx2 with uid 58
    When I set it in mbx3
    Then two deletion events are dispatched, one in mbx1 with uid 12 ok, one in mbx2 and uid 12.
    ```
---
 .../james/mailbox/store/StoreMessageIdManager.java | 35 ++++++++++++++--------
 .../AbstractMessageIdManagerSideEffectTest.java    | 23 ++++++++++++++
 2 files changed, 45 insertions(+), 13 deletions(-)

diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
index a8f867d..e40d42d 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
@@ -34,6 +34,7 @@ import java.util.stream.Stream;
 import javax.inject.Inject;
 import javax.mail.Flags;
 
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageIdManager;
@@ -54,7 +55,6 @@ import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxACL.Right;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.MessageMoves;
 import org.apache.james.mailbox.model.MessageResult;
 import org.apache.james.mailbox.model.QuotaRoot;
@@ -334,11 +334,17 @@ public class StoreMessageIdManager implements MessageIdManager {
         if (mailboxMessage.isEmpty()) {
             return Mono.error(new MailboxNotFoundException("can't load message"));
         }
+        List<Pair<MailboxMessage, Mailbox>> messagesToRemove = currentMailboxMessages.stream()
+            .flatMap(message -> messageMoves.removedMailboxes()
+                .stream()
+                .filter(mailbox -> mailbox.getMailboxId().equals(message.getMailboxId()))
+                .map(mailbox -> Pair.of(message, mailbox)))
+            .collect(Guavate.toImmutableList());
 
         return Mono.fromRunnable(Throwing.runnable(() -> validateQuota(messageMoves, mailboxMessage.get())).sneakyThrow())
             .then(Mono.fromRunnable(Throwing.runnable(() ->
                 addMessageToMailboxes(mailboxMessage.get(), messageMoves.addedMailboxes(), mailboxSession)).sneakyThrow()))
-            .then(removeMessageFromMailboxes(mailboxMessage.get(), messageMoves.removedMailboxes(), mailboxSession))
+            .then(removeMessageFromMailboxes(mailboxMessage.get().getMessageId(), messagesToRemove, mailboxSession))
             .then(eventBus.dispatch(EventFactory.moved()
                     .session(mailboxSession)
                     .messageMoves(messageMoves.asMessageMoves())
@@ -350,23 +356,26 @@ public class StoreMessageIdManager implements MessageIdManager {
                     .collect(Guavate.toImmutableSet())));
     }
 
-    private Mono<Void> removeMessageFromMailboxes(MailboxMessage message, Set<Mailbox> mailboxesToRemove, MailboxSession mailboxSession) {
+    private Mono<Void> removeMessageFromMailboxes(MessageId messageId, List<Pair<MailboxMessage, Mailbox>> messages, MailboxSession mailboxSession) {
+        if (messages.isEmpty()) {
+            return Mono.empty();
+        }
+
         MessageIdMapper messageIdMapper = mailboxSessionMapperFactory.getMessageIdMapper(mailboxSession);
-        MessageMetaData eventPayload = message.metaData();
 
-        ImmutableSet<MailboxId> mailboxIds = mailboxesToRemove.stream()
-            .map(Mailbox::getMailboxId)
-            .collect(Guavate.toImmutableSet());
+        ImmutableList<MailboxId> mailboxIds = messages.stream()
+            .map(pair -> pair.getRight().getMailboxId())
+            .collect(Guavate.toImmutableList());
 
-        return Mono.from(messageIdMapper.deleteReactive(message.getMessageId(), mailboxIds))
-            .then(Flux.fromIterable(mailboxesToRemove)
-                .flatMap(mailbox -> eventBus.dispatch(EventFactory.expunged()
+        return Mono.from(messageIdMapper.deleteReactive(messageId, mailboxIds))
+            .then(Flux.fromIterable(messages)
+                .flatMap(message -> eventBus.dispatch(EventFactory.expunged()
                         .randomEventId()
                         .mailboxSession(mailboxSession)
-                        .mailbox(mailbox)
-                        .addMetaData(eventPayload)
+                        .mailbox(message.getRight())
+                        .addMetaData(message.getLeft().metaData())
                         .build(),
-                    new MailboxIdRegistrationKey(mailbox.getMailboxId())), DEFAULT_CONCURRENCY)
+                    new MailboxIdRegistrationKey(message.getRight().getMailboxId())), DEFAULT_CONCURRENCY)
                 .then());
     }
     
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
index 63ec65e..7a1d087 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
@@ -34,6 +34,7 @@ import java.util.concurrent.CountDownLatch;
 
 import javax.mail.Flags;
 
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.james.core.quota.QuotaCountLimit;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeLimit;
@@ -340,6 +341,28 @@ public abstract class AbstractMessageIdManagerSideEffectTest {
     }
 
     @Test
+    void setInMailboxesShouldUseTheRightMessageUidsInExpunged() throws Exception {
+        givenUnlimitedQuota();
+        MessageId messageId = testingData.persist(mailbox2.getMailboxId(), messageUid1, FLAGS, session);
+        testingData.persist(mailbox1.getMailboxId(), messageUid1, FLAGS, session);
+        testingData.persist(mailbox1.getMailboxId(), messageUid2, FLAGS, session);
+        messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId(), mailbox3.getMailboxId()), session);
+        List<MessageResult> messages = messageIdManager.getMessage(messageId, FetchGroup.MINIMAL, session);
+        MessageUid uidMailbox1 = messages.stream().filter(message -> message.getMailboxId().equals(mailbox1.getMailboxId())).map(MessageResult::getUid).findFirst().get();
+        MessageUid uidMailbox3 = messages.stream().filter(message -> message.getMailboxId().equals(mailbox3.getMailboxId())).map(MessageResult::getUid).findFirst().get();
+
+
+        eventBus.register(eventCollector);
+        messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox2.getMailboxId()), session);
+
+        assertThat(eventCollector.getEvents()).filteredOn(event -> event instanceof MessageMoveEvent).hasSize(1);
+        assertThat(eventCollector.getEvents()).filteredOn(event -> event instanceof Expunged).hasSize(2)
+            .extracting(event -> (Expunged) event)
+            .extracting(event -> Pair.of(event.getMailboxId(), ImmutableList.copyOf(event.getUids())))
+            .containsOnly(Pair.of(mailbox1.getMailboxId(), ImmutableList.of(uidMailbox1)), Pair.of(mailbox3.getMailboxId(), ImmutableList.of(uidMailbox3)));
+    }
+
+    @Test
     void setInMailboxesShouldCallDispatcherWithMultipleMailboxes() throws Exception {
         givenUnlimitedQuota();
         MessageId messageId = testingData.persist(mailbox2.getMailboxId(), messageUid1, FLAGS, session);


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org