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 2023/03/16 15:23:50 UTC

[james-project] branch master updated (4e92cdf609 -> 4d9c4cfade)

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git


    from 4e92cdf609 JAMES-3891 Integration test for graceful shutdown
     new 29a253f596 JAMES-3440 Fixbug: Data race issue with JMAP email query view
     new 4d9c4cfade JAMES-3771 OpenSearch index - Add a new test case for checking not indexing the outdated message of add event

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../OpenSearchListeningMessageSearchIndexTest.java | 56 ++++++++++++++++++++++
 .../jmap/event/PopulateEmailQueryViewListener.java | 17 ++++++-
 .../event/PopulateEmailQueryViewListenerTest.java  | 54 ++++++++++++++++++++-
 3 files changed, 124 insertions(+), 3 deletions(-)


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


[james-project] 01/02: JAMES-3440 Fixbug: Data race issue with JMAP email query view

Posted by bt...@apache.org.
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 29a253f596aa3693e2f9b0b46fe51c3a68bc178c
Author: Tung Van TRAN <vt...@linagora.com>
AuthorDate: Sat Mar 11 09:50:56 2023 +0700

    JAMES-3440 Fixbug: Data race issue with JMAP email query view
---
 .../jmap/event/PopulateEmailQueryViewListener.java | 17 ++++++-
 .../event/PopulateEmailQueryViewListenerTest.java  | 54 +++++++++++++++++++++-
 2 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/PopulateEmailQueryViewListener.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/PopulateEmailQueryViewListener.java
index 9df59c69f4..de07c18370 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/PopulateEmailQueryViewListener.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/PopulateEmailQueryViewListener.java
@@ -36,6 +36,7 @@ import org.apache.james.events.Group;
 import org.apache.james.jmap.api.projections.EmailQueryView;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageIdManager;
+import org.apache.james.mailbox.Role;
 import org.apache.james.mailbox.SessionProvider;
 import org.apache.james.mailbox.events.MailboxEvents.Added;
 import org.apache.james.mailbox.events.MailboxEvents.Expunged;
@@ -54,6 +55,7 @@ import org.apache.james.mime4j.dom.field.DateTimeField;
 import org.apache.james.mime4j.field.DateTimeFieldLenientImpl;
 import org.apache.james.mime4j.message.DefaultMessageBuilder;
 import org.apache.james.mime4j.stream.MimeConfig;
+import org.apache.james.util.FunctionalUtils;
 import org.reactivestreams.Publisher;
 
 import com.google.common.collect.ImmutableList;
@@ -156,11 +158,24 @@ public class PopulateEmailQueryViewListener implements ReactiveGroupEventListene
 
     private Mono<Void> handleAdded(Added added, MessageMetaData messageMetaData, MailboxSession session) {
         MessageId messageId = messageMetaData.getMessageId();
+        MailboxId mailboxId = added.getMailboxId();
 
-        return Flux.from(messageIdManager.getMessagesReactive(ImmutableList.of(messageId), FetchGroup.HEADERS, session))
+        Mono<Void> doHandleAdded = Flux.from(messageIdManager.getMessagesReactive(ImmutableList.of(messageId), FetchGroup.HEADERS, session))
             .next()
             .filter(message -> !message.getFlags().contains(DELETED))
             .flatMap(messageResult -> handleAdded(added.getMailboxId(), messageResult));
+        if (Role.from(added.getMailboxPath().getName()).equals(Optional.of(Role.OUTBOX))) {
+            return checkMessageStillInOriginMailbox(messageId, session, mailboxId)
+                .filter(FunctionalUtils.identityPredicate())
+                .flatMap(stillInOriginMailbox -> doHandleAdded);
+        }
+        return doHandleAdded;
+    }
+
+    private Mono<Boolean> checkMessageStillInOriginMailbox(MessageId messageId, MailboxSession session, MailboxId targetMailboxId) {
+        return Flux.from(messageIdManager.messageMetadata(messageId, session))
+            .filter(composedMessageIdWithMetaData -> composedMessageIdWithMetaData.getComposedMessageId().getMailboxId().equals(targetMailboxId))
+            .hasElements();
     }
 
     public Mono<Void> handleAdded(MailboxId mailboxId, MessageResult messageResult) {
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/event/PopulateEmailQueryViewListenerTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/event/PopulateEmailQueryViewListenerTest.java
index 2f62f4414a..66de6a59ad 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/event/PopulateEmailQueryViewListenerTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/event/PopulateEmailQueryViewListenerTest.java
@@ -20,16 +20,19 @@
 package org.apache.james.jmap.event;
 
 import static javax.mail.Flags.Flag.DELETED;
+import static org.apache.james.mailbox.events.MailboxEvents.Added.IS_DELIVERY;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.nio.charset.StandardCharsets;
 import java.time.Duration;
 import java.time.ZonedDateTime;
 import java.util.Date;
+import java.util.Optional;
 
 import javax.mail.Flags;
 
 import org.apache.james.core.Username;
+import org.apache.james.events.Event;
 import org.apache.james.events.Group;
 import org.apache.james.events.InVMEventBus;
 import org.apache.james.events.MemoryEventDeadLetters;
@@ -40,11 +43,16 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
+import org.apache.james.mailbox.events.MailboxEvents;
 import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.MessageRange;
+import org.apache.james.mailbox.model.ThreadId;
 import org.apache.james.mailbox.store.FakeAuthenticator;
 import org.apache.james.mailbox.store.FakeAuthorizator;
 import org.apache.james.mailbox.store.SessionProviderImpl;
@@ -56,6 +64,9 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSortedMap;
+
+import reactor.core.publisher.Mono;
 
 public class PopulateEmailQueryViewListenerTest {
     private static final Username BOB = Username.of("bob");
@@ -69,6 +80,7 @@ public class PopulateEmailQueryViewListenerTest {
     MessageManager otherBoxMessageManager;
     PopulateEmailQueryViewListener listener;
     MessageIdManager messageIdManager;
+    SessionProviderImpl sessionProvider;
     private MemoryEmailQueryView view;
     private MailboxId inboxId;
 
@@ -97,7 +109,7 @@ public class PopulateEmailQueryViewListenerTest {
 
         FakeAuthenticator authenticator = new FakeAuthenticator();
         authenticator.addUser(BOB, "12345");
-        SessionProviderImpl sessionProvider = new SessionProviderImpl(authenticator, FakeAuthorizator.defaultReject());
+        sessionProvider = new SessionProviderImpl(authenticator, FakeAuthorizator.defaultReject());
 
         view = new MemoryEmailQueryView();
         listener = new PopulateEmailQueryViewListener(messageIdManager, view, sessionProvider);
@@ -133,7 +145,7 @@ public class PopulateEmailQueryViewListenerTest {
     }
 
     @Test
-    void appendingADeletedMessageSHouldNotAddItToTheView() throws Exception {
+    void appendingADeletedMessageShouldNotAddItToTheView() throws Exception {
         inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .withInternalDate(Date.from(ZonedDateTime.parse("2014-10-30T15:12:00Z").toInstant()))
@@ -145,6 +157,44 @@ public class PopulateEmailQueryViewListenerTest {
             .isEmpty();
     }
 
+    @Test
+    void appendingAOutdatedMessageInOutBoxShouldNotAddItToTheView() throws Exception {
+        MemoryEmailQueryView emailQueryView = new MemoryEmailQueryView();
+        PopulateEmailQueryViewListener queryViewListener = new PopulateEmailQueryViewListener(messageIdManager, emailQueryView, sessionProvider);
+        MailboxPath outboxPath = MailboxPath.forUser(BOB, "Outbox");
+        MailboxId outboxId = mailboxManager.createMailbox(outboxPath, mailboxSession).orElseThrow();
+
+        // given: save a message in Inbox
+        ComposedMessageId composedId = inboxMessageManager.appendMessage(
+            MessageManager.AppendCommand.builder()
+                .withInternalDate(Date.from(ZonedDateTime.parse("2014-10-30T15:12:00Z").toInstant()))
+                .build(emptyMessage(Date.from(ZonedDateTime.parse("2014-10-30T14:12:00Z").toInstant()))),
+            mailboxSession).getId();
+
+        // mock an outDated message by assigning above message in OutBox
+        MessageMetaData outdatedMessageMetaData = new MessageMetaData(MessageUid.of(1),
+            ModSeq.of(35), new Flags(), 12,
+            new Date(),
+            Optional.empty(),
+            composedId.getMessageId(),
+            ThreadId.fromBaseMessageId(composedId.getMessageId()));
+
+        // the latest mailboxId should be `composedId.getMailboxId()`, not `outboxId`
+        MailboxEvents.Added addedOutDatedEvent = new MailboxEvents.Added(MailboxSession.SessionId.of(42),
+            BOB,
+            outboxPath,
+            outboxId,
+            ImmutableSortedMap.of(MessageUid.of(1), outdatedMessageMetaData),
+            Event.EventId.random(),
+            !IS_DELIVERY);
+
+        Mono.from(queryViewListener.reactiveEvent(addedOutDatedEvent)).block();
+
+        assertThat(emailQueryView.listMailboxContentSortedBySentAt(outboxId, Limit.limit(12)).collectList().block())
+            .isEmpty();
+    }
+
+
     @Test
     void removingDeletedFlagsShouldAddItToTheView() throws Exception {
         ComposedMessageId composedId = inboxMessageManager.appendMessage(


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


[james-project] 02/02: JAMES-3771 OpenSearch index - Add a new test case for checking not indexing the outdated message of add event

Posted by bt...@apache.org.
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 4d9c4cfade150293fd3fc00b008627cef059035a
Author: Tung Van TRAN <vt...@linagora.com>
AuthorDate: Mon Mar 13 09:22:11 2023 +0700

    JAMES-3771 OpenSearch index - Add a new test case for checking not indexing the outdated message of add event
---
 .../OpenSearchListeningMessageSearchIndexTest.java | 56 ++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/events/OpenSearchListeningMessageSearchIndexTest.java b/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/events/OpenSearchListeningMessageSearchIndexTest.java
index bf3025cbf2..c50e447cb6 100644
--- a/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/events/OpenSearchListeningMessageSearchIndexTest.java
+++ b/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/events/OpenSearchListeningMessageSearchIndexTest.java
@@ -18,6 +18,8 @@
  ****************************************************************/
 package org.apache.james.mailbox.opensearch.events;
 
+import static org.apache.james.jmap.JMAPTestingConstants.BOB;
+import static org.apache.james.mailbox.events.MailboxEvents.Added.IS_DELIVERY;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -36,12 +38,14 @@ import org.apache.james.backends.opensearch.DockerOpenSearchExtension;
 import org.apache.james.backends.opensearch.OpenSearchIndexer;
 import org.apache.james.backends.opensearch.ReactorOpenSearchClient;
 import org.apache.james.core.Username;
+import org.apache.james.events.Event;
 import org.apache.james.events.Group;
 import org.apache.james.mailbox.Authorizator;
 import org.apache.james.mailbox.DefaultMailboxes;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
+import org.apache.james.mailbox.events.MailboxEvents;
 import org.apache.james.mailbox.extractor.ParsedContent;
 import org.apache.james.mailbox.extractor.TextExtractor;
 import org.apache.james.mailbox.inmemory.InMemoryMailboxSessionMapperFactory;
@@ -55,6 +59,7 @@ import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
@@ -93,8 +98,11 @@ import org.opensearch.client.opensearch.core.SearchRequest;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSortedMap;
 import com.google.common.collect.Lists;
 
+import reactor.core.publisher.Mono;
+
 class OpenSearchListeningMessageSearchIndexTest {
 
     private static final ConditionFactory CALMLY_AWAIT = Awaitility
@@ -289,6 +297,54 @@ class OpenSearchListeningMessageSearchIndexTest {
         openSearch.getDockerOpenSearch().unpause();
     }
 
+    @Test
+    void addAOutdatedMessageInOutBoxShouldNotIndex() throws Exception {
+        // given
+        MailboxPath outboxPath = MailboxPath.forUser(USERNAME, DefaultMailboxes.OUTBOX);
+        Mailbox outbox = mapperFactory.getMailboxMapper(session).create(outboxPath, UidValidity.generate()).block();
+        assert outbox != null;
+        Mailbox inbox = mailbox;
+        SimpleMailboxMessage outDatedMessage = SimpleMailboxMessage.builder()
+            .mailboxId(inbox.getMailboxId())
+            .flags(new Flags())
+            .bodyStartOctet(BODY_START_OCTET)
+            .internalDate(new Date(1433628000000L))
+            .size(SIZE)
+            .content(new ByteContent("message".getBytes(StandardCharsets.UTF_8)))
+            .properties(new PropertyBuilder())
+            .modseq(MOD_SEQ)
+            .messageId(MESSAGE_ID_1)
+            .threadId(ThreadId.fromBaseMessageId(MESSAGE_ID_1))
+            .uid(MESSAGE_UID_1)
+            .build();
+        mapperFactory.getMessageMapper(session).add(inbox, outDatedMessage);
+
+        // when
+        MessageMetaData outdatedMessageMetaData = new MessageMetaData(MESSAGE_UID_1,
+            outDatedMessage.getModSeq(),
+            outDatedMessage.metaData().getFlags(),
+            SIZE,
+            outDatedMessage.getInternalDate(),
+            outDatedMessage.getSaveDate(),
+            MESSAGE_ID_1,
+            outDatedMessage.getThreadId());
+
+        MailboxEvents.Added addedOutDatedEvent = new MailboxEvents.Added(MailboxSession.SessionId.of(42),
+            BOB,
+            outboxPath,
+            outbox.getMailboxId(),
+            ImmutableSortedMap.of(MESSAGE_UID_1, outdatedMessageMetaData),
+            Event.EventId.random(),
+            !IS_DELIVERY);
+
+        Mono.from(testee.reactiveEvent(addedOutDatedEvent)).block();
+
+        // then
+        Thread.sleep(1000);
+        assertThat(testee.search(session, outbox, SearchQuery.of(SearchQuery.all())).collectList().block())
+            .isEmpty();
+    }
+
     @Test
     void deleteShouldRemoveIndex() throws Exception {
         testee.add(session, mailbox, MESSAGE_1).block();


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