JAMES-2555 mailbox API support for MessageId reIndexing Due to Spring injection reasons for MessageIdManager we need to use a separated API
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/dead91fe Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/dead91fe Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/dead91fe Branch: refs/heads/master Commit: dead91fe998067c90814703448390eb472c0e58a Parents: 468eda5 Author: Benoit Tellier <btell...@linagora.com> Authored: Mon Oct 15 11:18:33 2018 +0700 Committer: Benoit Tellier <btell...@linagora.com> Committed: Tue Oct 23 08:43:46 2018 +0700 ---------------------------------------------------------------------- .../mailbox/indexer/MessageIdReIndexer.java | 27 ++++ .../tools/indexer/MessageIdReIndexerImpl.java | 130 +++++++++++++++++++ .../indexer/MessageIdReIndexerImplTest.java | 84 ++++++++++++ 3 files changed, 241 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/dead91fe/mailbox/api/src/main/java/org/apache/james/mailbox/indexer/MessageIdReIndexer.java ---------------------------------------------------------------------- diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/indexer/MessageIdReIndexer.java b/mailbox/api/src/main/java/org/apache/james/mailbox/indexer/MessageIdReIndexer.java new file mode 100644 index 0000000..3cc50ea --- /dev/null +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/indexer/MessageIdReIndexer.java @@ -0,0 +1,27 @@ +/**************************************************************** + * 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.indexer; + +import org.apache.james.mailbox.model.MessageId; +import org.apache.james.task.Task; + +public interface MessageIdReIndexer { + Task reIndex(MessageId messageId); +} http://git-wip-us.apache.org/repos/asf/james-project/blob/dead91fe/mailbox/tools/indexer/src/main/java/org/apache/mailbox/tools/indexer/MessageIdReIndexerImpl.java ---------------------------------------------------------------------- diff --git a/mailbox/tools/indexer/src/main/java/org/apache/mailbox/tools/indexer/MessageIdReIndexerImpl.java b/mailbox/tools/indexer/src/main/java/org/apache/mailbox/tools/indexer/MessageIdReIndexerImpl.java new file mode 100644 index 0000000..e18c239 --- /dev/null +++ b/mailbox/tools/indexer/src/main/java/org/apache/mailbox/tools/indexer/MessageIdReIndexerImpl.java @@ -0,0 +1,130 @@ +/**************************************************************** + * 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.mailbox.tools.indexer; + +import java.util.Optional; + +import javax.inject.Inject; + +import org.apache.james.mailbox.MailboxManager; +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.indexer.MessageIdReIndexer; +import org.apache.james.mailbox.model.MessageId; +import org.apache.james.mailbox.store.MailboxSessionMapperFactory; +import org.apache.james.mailbox.store.mail.MailboxMapper; +import org.apache.james.mailbox.store.mail.MessageMapper; +import org.apache.james.mailbox.store.mail.model.Mailbox; +import org.apache.james.mailbox.store.mail.model.MailboxMessage; +import org.apache.james.mailbox.store.search.ListeningMessageSearchIndex; +import org.apache.james.task.Task; +import org.apache.james.task.TaskExecutionDetails; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.ImmutableList; + +public class MessageIdReIndexerImpl implements MessageIdReIndexer { + public static class MessageIdReIndexingTask implements Task { + private static final Logger LOGGER = LoggerFactory.getLogger(MessageIdReIndexingTask.class); + + public static final String TYPE = "MessageIdReIndexingTask"; + + public final class AdditionalInformation implements TaskExecutionDetails.AdditionalInformation { + private final MessageId messageId; + + AdditionalInformation(MessageId messageId) { + this.messageId = messageId; + } + + public String getMessageId() { + return messageId.serialize(); + } + } + + private final MailboxManager mailboxManager; + private final MailboxSessionMapperFactory mailboxSessionMapperFactory; + private final ListeningMessageSearchIndex index; + private final MessageId messageId; + private final AdditionalInformation additionalInformation; + + MessageIdReIndexingTask(MailboxManager mailboxManager, MailboxSessionMapperFactory mailboxSessionMapperFactory, ListeningMessageSearchIndex index, MessageId messageId) { + this.mailboxManager = mailboxManager; + this.mailboxSessionMapperFactory = mailboxSessionMapperFactory; + this.index = index; + this.messageId = messageId; + this.additionalInformation = new AdditionalInformation(messageId); + } + + @Override + public Result run() { + try { + MailboxSession session = mailboxManager.createSystemSession("MessageIdReIndexerImpl"); + + return mailboxSessionMapperFactory.getMessageIdMapper(session) + .find(ImmutableList.of(messageId), MessageMapper.FetchType.Full) + .stream() + .map(mailboxMessage -> reIndex(mailboxMessage, session)) + .reduce(Task::combine) + .orElse(Result.COMPLETED); + } catch (Exception e) { + LOGGER.warn("Failed to re-index {}", messageId, e); + return Result.PARTIAL; + } + } + + public Result reIndex(MailboxMessage mailboxMessage, MailboxSession session) { + try { + MailboxMapper mailboxMapper = mailboxSessionMapperFactory.getMailboxMapper(session); + Mailbox mailbox = mailboxMapper.findMailboxById(mailboxMessage.getMailboxId()); + index.add(session, mailbox, mailboxMessage); + return Result.COMPLETED; + } catch (Exception e) { + LOGGER.warn("Failed to re-index {} in {}", messageId, mailboxMessage.getMailboxId(), e); + return Result.PARTIAL; + } + } + + @Override + public String type() { + return TYPE; + } + + @Override + public Optional<TaskExecutionDetails.AdditionalInformation> details() { + return Optional.of(additionalInformation); + } + } + + private final MailboxManager mailboxManager; + private final MailboxSessionMapperFactory mailboxSessionMapperFactory; + private final ListeningMessageSearchIndex index; + + @Inject + public MessageIdReIndexerImpl(MailboxManager mailboxManager, MailboxSessionMapperFactory mailboxSessionMapperFactory, ListeningMessageSearchIndex index) { + this.mailboxManager = mailboxManager; + this.mailboxSessionMapperFactory = mailboxSessionMapperFactory; + this.index = index; + } + + @Override + public Task reIndex(MessageId messageId) { + return new MessageIdReIndexingTask(mailboxManager, mailboxSessionMapperFactory, index, messageId); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/dead91fe/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/MessageIdReIndexerImplTest.java ---------------------------------------------------------------------- diff --git a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/MessageIdReIndexerImplTest.java b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/MessageIdReIndexerImplTest.java new file mode 100644 index 0000000..ff25d44 --- /dev/null +++ b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/MessageIdReIndexerImplTest.java @@ -0,0 +1,84 @@ +/**************************************************************** + * 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.mailbox.tools.indexer; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.MessageManager; +import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver; +import org.apache.james.mailbox.exception.MailboxException; +import org.apache.james.mailbox.inmemory.InMemoryMailboxManager; +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.store.MailboxSessionMapperFactory; +import org.apache.james.mailbox.store.mail.model.Mailbox; +import org.apache.james.mailbox.store.mail.model.MailboxMessage; +import org.apache.james.mailbox.store.search.ListeningMessageSearchIndex; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; + +public class MessageIdReIndexerImplTest { + private static final String USERNAME = "be...@apache.org"; + public static final MailboxPath INBOX = MailboxPath.forUser(USERNAME, "INBOX"); + + private InMemoryMailboxManager mailboxManager; + private ListeningMessageSearchIndex messageSearchIndex; + + private MessageIdReIndexerImpl reIndexer; + + @BeforeEach + void setUp() throws MailboxException { + mailboxManager = new InMemoryIntegrationResources().createMailboxManager(new SimpleGroupMembershipResolver()); + MailboxSessionMapperFactory mailboxSessionMapperFactory = mailboxManager.getMapperFactory(); + messageSearchIndex = mock(ListeningMessageSearchIndex.class); + reIndexer = new MessageIdReIndexerImpl(mailboxManager, mailboxSessionMapperFactory, messageSearchIndex); + } + + @Test + void reIndexShouldBeWellPerformed() throws Exception { + MailboxSession systemSession = mailboxManager.createSystemSession(USERNAME); + MailboxId mailboxId = mailboxManager.createMailbox(INBOX, systemSession).get(); + ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession) + .appendMessage( + MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"), + systemSession); + + reIndexer.reIndex(createdMessage.getMessageId()).run(); + + ArgumentCaptor<MailboxMessage> messageCaptor = ArgumentCaptor.forClass(MailboxMessage.class); + ArgumentCaptor<Mailbox> mailboxCaptor = ArgumentCaptor.forClass(Mailbox.class); + + verify(messageSearchIndex).add(any(MailboxSession.class), mailboxCaptor.capture(), messageCaptor.capture()); + verifyNoMoreInteractions(messageSearchIndex); + + assertThat(mailboxCaptor.getValue()).matches(mailbox -> mailbox.getMailboxId().equals(mailboxId)); + assertThat(messageCaptor.getValue()).matches(message -> message.getComposedMessageIdWithMetaData().getComposedMessageId().getMessageId() + .equals(createdMessage.getMessageId())); + } + +} \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org