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 1b5a9c75039dd236153e26e6c22fa1ef61d26a60
Author: Rene Cordier <[email protected]>
AuthorDate: Wed Jun 10 17:43:28 2020 +0700

    JAMES-3202 implement `retrieveIndexedFlags` in 
LuceneMailboxMessageSearchIndexTest
---
 .../lucene/search/LuceneMessageSearchIndex.java    |  58 +++++++--
 .../LuceneMailboxMessageSearchIndexTest.java       | 137 +++++++++++++++++++++
 2 files changed, 186 insertions(+), 9 deletions(-)

diff --git 
a/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
 
b/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
index 7337a4f..9a8e480 100644
--- 
a/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
+++ 
b/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
@@ -1209,13 +1209,10 @@ public class LuceneMessageSearchIndex extends 
ListeningMessageSearchIndex {
             for (ScoreDoc sDoc : sDocs) {
                 Document doc = searcher.doc(sDoc.doc);
 
-                if (doc.getFieldable(FLAGS_FIELD) == null) {
-                    doc.removeFields(FLAGS_FIELD);
-                    indexFlags(doc, f);
+                doc.removeFields(FLAGS_FIELD);
+                indexFlags(doc, f);
 
-                    writer.updateDocument(new Term(ID_FIELD, 
doc.get(ID_FIELD)), doc);
-
-                }
+                writer.updateDocument(new Term(ID_FIELD, doc.get(ID_FIELD)), 
doc);
             }
         }
     }
@@ -1241,12 +1238,12 @@ public class LuceneMessageSearchIndex extends 
ListeningMessageSearchIndex {
         Flag[] flags = f.getSystemFlags();
         for (Flag flag : flags) {
             fString.add(toString(flag));
-            doc.add(new Field(FLAGS_FIELD, toString(flag), Store.NO, 
Index.NOT_ANALYZED));
+            doc.add(new Field(FLAGS_FIELD, toString(flag), Store.YES, 
Index.NOT_ANALYZED));
         }
         
         String[] userFlags = f.getUserFlags();
         for (String userFlag : userFlags) {
-            doc.add(new Field(FLAGS_FIELD, userFlag, Store.NO, 
Index.NOT_ANALYZED));
+            doc.add(new Field(FLAGS_FIELD, userFlag, Store.YES, 
Index.NOT_ANALYZED));
         }
         
         // if no flags are there we just use a empty field
@@ -1300,6 +1297,49 @@ public class LuceneMessageSearchIndex extends 
ListeningMessageSearchIndex {
 
     @Override
     public Mono<Flags> retrieveIndexedFlags(Mailbox mailbox, MessageUid uid) {
-        return Mono.empty();
+        return Mono.fromCallable(() -> retrieveFlags(mailbox, uid));
+    }
+
+    private Flags retrieveFlags(Mailbox mailbox, MessageUid uid) throws 
IOException {
+        try (IndexSearcher searcher = new 
IndexSearcher(IndexReader.open(writer, true))) {
+            Flags retrievedFlags = new Flags();
+
+            BooleanQuery query = new BooleanQuery();
+            query.add(new TermQuery(new Term(MAILBOX_ID_FIELD, 
mailbox.getMailboxId().serialize())), BooleanClause.Occur.MUST);
+            query.add(createQuery(MessageRange.one(uid)), 
BooleanClause.Occur.MUST);
+            query.add(new PrefixQuery(new Term(FLAGS_FIELD, "")), 
BooleanClause.Occur.MUST);
+
+            TopDocs docs = searcher.search(query, 100000);
+            ScoreDoc[] sDocs = docs.scoreDocs;
+            for (ScoreDoc sDoc : sDocs) {
+                Document doc = searcher.doc(sDoc.doc);
+
+                Stream.of(doc.getValues(FLAGS_FIELD))
+                    .forEach(flag -> 
fromString(flag).ifPresentOrElse(retrievedFlags::add, () -> 
retrievedFlags.add(flag)));
+            }
+            return retrievedFlags;
+        }
+    }
+
+    /**
+     * Convert the given {@link Flag} to a String
+     */
+    private Optional<Flag> fromString(String flag) {
+        switch (flag) {
+            case "\\ANSWERED":
+                return Optional.of(Flag.ANSWERED);
+            case "\\DELETED":
+                return Optional.of(Flag.DELETED);
+            case "\\DRAFT":
+                return Optional.of(Flag.DRAFT);
+            case "\\FLAGGED":
+                return Optional.of(Flag.FLAGGED);
+            case "\\RECENT":
+                return Optional.of(Flag.RECENT);
+            case "\\FLAG":
+                return Optional.of(Flag.SEEN);
+            default:
+                return Optional.empty();
+        }
     }
 }
\ No newline at end of file
diff --git 
a/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMailboxMessageSearchIndexTest.java
 
b/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMailboxMessageSearchIndexTest.java
index be30a35..15ac2a3 100644
--- 
a/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMailboxMessageSearchIndexTest.java
+++ 
b/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMailboxMessageSearchIndexTest.java
@@ -19,6 +19,7 @@
 package org.apache.james.mailbox.lucene.search;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
+import static 
org.apache.james.mailbox.store.MessageIdManagerTestSystem.MOD_SEQ;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.nio.charset.StandardCharsets;
@@ -34,6 +35,7 @@ import javax.mail.Flags;
 import javax.mail.Flags.Flag;
 
 import org.apache.james.core.Username;
+import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageUid;
@@ -49,12 +51,14 @@ import 
org.apache.james.mailbox.model.SearchQuery.Sort.SortClause;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.mailbox.model.UidValidity;
+import org.apache.james.mailbox.model.UpdatedFlags;
 import org.apache.james.mailbox.store.MessageBuilder;
 import org.apache.lucene.store.RAMDirectory;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
 
 class LuceneMailboxMessageSearchIndexTest {
     static final long LIMIT = 100L;
@@ -614,4 +618,137 @@ class LuceneMailboxMessageSearchIndexTest {
         Stream<MessageUid> result = index.search(session, mailbox, query);
         assertThat(result).containsExactly(uid3, uid4);
     }
+
+    @Test
+    void updateShouldUpdateFlags() throws Exception {
+        Flags newFlags = new Flags(Flags.Flag.DRAFT);
+        UpdatedFlags updatedFlags = UpdatedFlags.builder()
+            .uid(uid2)
+            .modSeq(MOD_SEQ)
+            .oldFlags(new Flags(Flag.ANSWERED))
+            .newFlags(newFlags)
+            .build();
+
+        index.update(session, mailbox, 
Lists.newArrayList(updatedFlags)).block();
+
+        SearchQuery query = 
SearchQuery.of(SearchQuery.flagIsSet(Flags.Flag.DRAFT));
+        assertThat(index.search(session, mailbox, query))
+            .containsExactly(uid2);
+    }
+
+    @Test
+    void updateShouldNotUpdateNorThrowOnUnknownMessageUid() throws Exception {
+        Flags newFlags = new Flags(Flags.Flag.DRAFT);
+        UpdatedFlags updatedFlags = UpdatedFlags.builder()
+            .uid(MessageUid.of(42))
+            .modSeq(MOD_SEQ)
+            .oldFlags(new Flags())
+            .newFlags(newFlags)
+            .build();
+
+        index.update(session, mailbox, 
Lists.newArrayList(updatedFlags)).block();
+
+        SearchQuery query = 
SearchQuery.of(SearchQuery.flagIsSet(Flags.Flag.DRAFT));
+        assertThat(index.search(session, mailbox, query))
+            .isEmpty();
+    }
+
+    @Test
+    void updateShouldBeIdempotent() throws Exception {
+        Flags newFlags = new Flags(Flags.Flag.DRAFT);
+        UpdatedFlags updatedFlags = UpdatedFlags.builder()
+            .uid(uid2)
+            .modSeq(MOD_SEQ)
+            .oldFlags(new Flags())
+            .newFlags(newFlags)
+            .build();
+
+        index.update(session, mailbox, 
Lists.newArrayList(updatedFlags)).block();
+        index.update(session, mailbox, 
Lists.newArrayList(updatedFlags)).block();
+
+        SearchQuery query = 
SearchQuery.of(SearchQuery.flagIsSet(Flags.Flag.DRAFT));
+        assertThat(index.search(session, mailbox, query))
+            .containsExactly(uid2);
+    }
+
+    @Test
+    void retrieveIndexedFlagsShouldRetrieveSystemFlags() {
+        Flags expectedFlags = new Flags(Flag.ANSWERED);
+
+        assertThat(index.retrieveIndexedFlags(mailbox, uid1).block())
+            .isEqualTo(expectedFlags);
+    }
+
+    @Test
+    void retrieveIndexedFlagsShouldReturnEmptyFlagsWhenNoFlags() {
+        Flags expectedFlags = new Flags();
+
+        assertThat(index.retrieveIndexedFlags(mailbox, uid5).block())
+            .isEqualTo(expectedFlags);
+    }
+
+    @Test
+    void retrieveIndexedFlagsShouldReturnAllSystemFlagsWhenAllFlagsSet() {
+        Flags newFlags = FlagsBuilder.builder()
+            .add(Flags.Flag.ANSWERED)
+            .add(Flags.Flag.DELETED)
+            .add(Flags.Flag.RECENT)
+            .add(Flags.Flag.DRAFT)
+            .add(Flags.Flag.FLAGGED)
+            .add(Flags.Flag.SEEN)
+            .build();
+
+        UpdatedFlags updatedFlags = UpdatedFlags.builder()
+            .uid(uid2)
+            .modSeq(MOD_SEQ)
+            .oldFlags(new Flags(Flag.ANSWERED))
+            .newFlags(newFlags)
+            .build();
+
+        index.update(session, mailbox, 
Lists.newArrayList(updatedFlags)).block();
+
+        assertThat(index.retrieveIndexedFlags(mailbox, uid2).block())
+            .isEqualTo(newFlags);
+    }
+
+    @Test
+    void retrieveIndexedFlagsShouldReturnUserFlags() {
+        Flags newFlags = FlagsBuilder.builder()
+            .add("flag1")
+            .add("flag2")
+            .build();
+
+        UpdatedFlags updatedFlags = UpdatedFlags.builder()
+            .uid(uid2)
+            .modSeq(MOD_SEQ)
+            .oldFlags(new Flags(Flag.ANSWERED))
+            .newFlags(newFlags)
+            .build();
+
+        index.update(session, mailbox, 
Lists.newArrayList(updatedFlags)).block();
+
+        assertThat(index.retrieveIndexedFlags(mailbox, uid2).block())
+            .isEqualTo(newFlags);
+    }
+
+    @Test
+    void retrieveIndexedFlagsShouldReturnUserAndSystemFlags() {
+        Flags newFlags = FlagsBuilder.builder()
+            .add("flag1")
+            .add("flag2")
+            .add(Flag.DRAFT)
+            .build();
+
+        UpdatedFlags updatedFlags = UpdatedFlags.builder()
+            .uid(uid2)
+            .modSeq(MOD_SEQ)
+            .oldFlags(new Flags(Flag.ANSWERED))
+            .newFlags(newFlags)
+            .build();
+
+        index.update(session, mailbox, 
Lists.newArrayList(updatedFlags)).block();
+
+        assertThat(index.retrieveIndexedFlags(mailbox, uid2).block())
+            .isEqualTo(newFlags);
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to