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 13aa41353edd230713034be68df2d81e3ee23491
Author: quanth <[email protected]>
AuthorDate: Mon Jul 5 17:41:47 2021 +0700

    JAMES-3516 Implement SearchThreadIdGuessingAlgorithm
    
    Experiment guessing threadId by doing search
---
 .../SearchThreadIdGuessingAlgorithmTest.java       | 51 ++++++++++++
 .../mail/SearchThreadIdGuessingAlgorithm.java      | 96 ++++++++++++++++++++++
 .../james/modules/mailbox/MemoryMailboxModule.java |  4 +-
 3 files changed, 149 insertions(+), 2 deletions(-)

diff --git 
a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SearchThreadIdGuessingAlgorithmTest.java
 
b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SearchThreadIdGuessingAlgorithmTest.java
new file mode 100644
index 0000000..83ab8c1
--- /dev/null
+++ 
b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SearchThreadIdGuessingAlgorithmTest.java
@@ -0,0 +1,51 @@
+/******************************************************************
+ * 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.store.search;
+
+import org.apache.james.mailbox.inmemory.InMemoryCombinationManagerTestSystem;
+import org.apache.james.mailbox.inmemory.InMemoryMessageId;
+import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
+import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.store.CombinationManagerTestSystem;
+import org.apache.james.mailbox.store.ThreadIdGuessingAlgorithmContract;
+import org.apache.james.mailbox.store.mail.SearchThreadIdGuessingAlgorithm;
+import org.apache.james.mailbox.store.mail.ThreadIdGuessingAlgorithm;
+
+public class SearchThreadIdGuessingAlgorithmTest extends 
ThreadIdGuessingAlgorithmContract {
+
+    @Override
+    protected CombinationManagerTestSystem createTestingData() {
+        InMemoryIntegrationResources resources = 
InMemoryIntegrationResources.defaultResources();
+
+        return new InMemoryCombinationManagerTestSystem(
+            resources.getMailboxManager(),
+            resources.getMessageIdManager());
+    }
+
+    @Override
+    protected ThreadIdGuessingAlgorithm 
initThreadIdGuessingAlgorithm(CombinationManagerTestSystem testingData) {
+        return new 
SearchThreadIdGuessingAlgorithm(testingData.getMailboxManager(), 
testingData.getMessageIdManager());
+    }
+
+    @Override
+    protected MessageId initNewBasedMessageId() {
+        return InMemoryMessageId.of(100);
+    }
+}
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/SearchThreadIdGuessingAlgorithm.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/SearchThreadIdGuessingAlgorithm.java
new file mode 100644
index 0000000..a229fee
--- /dev/null
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/SearchThreadIdGuessingAlgorithm.java
@@ -0,0 +1,96 @@
+/******************************************************************
+ * 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.store.mail;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageIdManager;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.FetchGroup;
+import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.MessageResult;
+import org.apache.james.mailbox.model.MultimailboxesSearchQuery;
+import org.apache.james.mailbox.model.SearchQuery;
+import org.apache.james.mailbox.model.ThreadId;
+import org.apache.james.mailbox.store.mail.model.MimeMessageId;
+import org.apache.james.mailbox.store.mail.model.Subject;
+import org.apache.james.mailbox.store.search.SearchUtil;
+
+import com.google.common.collect.ImmutableList;
+
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+public class SearchThreadIdGuessingAlgorithm implements 
ThreadIdGuessingAlgorithm {
+    private final MailboxManager mailboxManager;
+    private final MessageIdManager messageIdManager;
+
+    @Inject
+    public SearchThreadIdGuessingAlgorithm(MailboxManager mailboxManager, 
MessageIdManager messageIdManager) {
+        this.mailboxManager = mailboxManager;
+        this.messageIdManager = messageIdManager;
+    }
+
+    @Override
+    public Mono<ThreadId> guessThreadIdReactive(MessageId messageId, 
Optional<MimeMessageId> mimeMessageId, Optional<MimeMessageId> inReplyTo, 
Optional<List<MimeMessageId>> references, Optional<Subject> subject, 
MailboxSession session) throws MailboxException {
+        MultimailboxesSearchQuery expression = buildSearchQuery(mimeMessageId, 
inReplyTo, references, subject);
+
+        return Flux.from(mailboxManager.search(expression, session, 1))
+            .collectList()
+            .flatMapMany(messageIds -> 
messageIdManager.getMessagesReactive(messageIds, FetchGroup.MINIMAL, session))
+            .map(MessageResult::getThreadId)
+            .next()
+            .switchIfEmpty(Mono.just(ThreadId.fromBaseMessageId(messageId)));
+    }
+
+    private MultimailboxesSearchQuery buildSearchQuery(Optional<MimeMessageId> 
mimeMessageId, Optional<MimeMessageId> inReplyTo, Optional<List<MimeMessageId>> 
references, Optional<Subject> subject) {
+        Set<MimeMessageId> mimeMessageIds = 
buildMimeMessageIdSet(mimeMessageId, inReplyTo, references);
+
+        ImmutableList.Builder<SearchQuery.Criterion> 
mimeMessageIdCriteriaBuilder = ImmutableList.builder();
+        mimeMessageIds.forEach(value -> {
+            
mimeMessageIdCriteriaBuilder.add(SearchQuery.mimeMessageID(value.getValue()));
+            
mimeMessageIdCriteriaBuilder.add(SearchQuery.headerContains("In-Reply-To", 
value.getValue()));
+            
mimeMessageIdCriteriaBuilder.add(SearchQuery.headerContains("References", 
value.getValue()));
+        });
+        SearchQuery.Criterion mimeMessageIdCriterion = 
SearchQuery.or(mimeMessageIdCriteriaBuilder.build());
+
+        SearchQuery.Criterion finalCriterion = subject.map(value -> 
SearchQuery.and(mimeMessageIdCriterion, SearchQuery.headerContains("Subject", 
SearchUtil.getBaseSubject(value.getValue()))))
+            .orElse(mimeMessageIdCriterion);
+
+        return MultimailboxesSearchQuery
+            .from(SearchQuery.of(finalCriterion))
+            .build();
+    }
+
+    private Set<MimeMessageId> buildMimeMessageIdSet(Optional<MimeMessageId> 
mimeMessageId, Optional<MimeMessageId> inReplyTo, Optional<List<MimeMessageId>> 
references) {
+        Set<MimeMessageId> mimeMessageIds = new HashSet<>();
+        mimeMessageId.ifPresent(mimeMessageIds::add);
+        inReplyTo.ifPresent(mimeMessageIds::add);
+        references.ifPresent(mimeMessageIds::addAll);
+        return mimeMessageIds;
+    }
+}
diff --git 
a/server/container/guice/memory/src/main/java/org/apache/james/modules/mailbox/MemoryMailboxModule.java
 
b/server/container/guice/memory/src/main/java/org/apache/james/modules/mailbox/MemoryMailboxModule.java
index fb2a4b9..44940b7 100644
--- 
a/server/container/guice/memory/src/main/java/org/apache/james/modules/mailbox/MemoryMailboxModule.java
+++ 
b/server/container/guice/memory/src/main/java/org/apache/james/modules/mailbox/MemoryMailboxModule.java
@@ -68,7 +68,7 @@ import 
org.apache.james.mailbox.store.mail.AttachmentMapperFactory;
 import org.apache.james.mailbox.store.mail.MailboxMapperFactory;
 import org.apache.james.mailbox.store.mail.MessageMapperFactory;
 import org.apache.james.mailbox.store.mail.ModSeqProvider;
-import org.apache.james.mailbox.store.mail.NaiveThreadIdGuessingAlgorithm;
+import org.apache.james.mailbox.store.mail.SearchThreadIdGuessingAlgorithm;
 import org.apache.james.mailbox.store.mail.ThreadIdGuessingAlgorithm;
 import org.apache.james.mailbox.store.mail.UidProvider;
 import org.apache.james.mailbox.store.search.MessageSearchIndex;
@@ -101,7 +101,7 @@ public class MemoryMailboxModule extends AbstractModule {
         bind(UidProvider.class).to(InMemoryUidProvider.class);
         bind(MailboxId.Factory.class).to(InMemoryId.Factory.class);
         bind(MessageId.Factory.class).to(InMemoryMessageId.Factory.class);
-        
bind(ThreadIdGuessingAlgorithm.class).to(NaiveThreadIdGuessingAlgorithm.class);
+        
bind(ThreadIdGuessingAlgorithm.class).to(SearchThreadIdGuessingAlgorithm.class);
         bind(State.Factory.class).to(State.DefaultFactory.class);
 
         bind(BlobManager.class).to(StoreBlobManager.class);

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

Reply via email to