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]
