http://git-wip-us.apache.org/repos/asf/james-project/blob/0c652ab7/mailbox/tools/indexer/src/main/resources/META-INF/spring/mailbox-tools.xml ---------------------------------------------------------------------- diff --git a/mailbox/tools/indexer/src/main/resources/META-INF/spring/mailbox-tools.xml b/mailbox/tools/indexer/src/main/resources/META-INF/spring/mailbox-tools.xml new file mode 100644 index 0000000..4abb97e --- /dev/null +++ b/mailbox/tools/indexer/src/main/resources/META-INF/spring/mailbox-tools.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> + + <bean id ="reindexer-impl" class="org.apache.mailbox.tools.indexer.ReIndexerImpl" lazy-init="true"> + <constructor-arg index="0" ref="mailboxmanager"/> + <constructor-arg index="1" ref="indexer"/> + <constructor-arg index="2" ref="messageMapperFactory"/> + </bean> + + <bean id ="fake-reindexer" class="org.apache.mailbox.tools.indexer.ThrowsReIndexer" lazy-init="true"/> + +</beans>
http://git-wip-us.apache.org/repos/asf/james-project/blob/0c652ab7/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/ReIndexerImplTest.java ---------------------------------------------------------------------- diff --git a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/ReIndexerImplTest.java b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/ReIndexerImplTest.java new file mode 100644 index 0000000..b7c583c --- /dev/null +++ b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/ReIndexerImplTest.java @@ -0,0 +1,138 @@ +/**************************************************************** + * 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.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import org.apache.james.mailbox.MailboxListener; +import org.apache.james.mailbox.MailboxManager; +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.MessageUid; +import org.apache.james.mailbox.indexer.ReIndexer; +import org.apache.james.mailbox.mock.MockMailboxSession; +import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.model.MessageRange; +import org.apache.james.mailbox.store.MailboxSessionMapperFactory; +import org.apache.james.mailbox.store.MessageBuilder; +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.mail.model.impl.SimpleMailbox; +import org.apache.james.mailbox.store.search.ListeningMessageSearchIndex; +import org.assertj.core.util.Lists; +import org.junit.Before; +import org.junit.Test; + +import com.google.common.collect.ImmutableList; + +public class ReIndexerImplTest { + + public static final MailboxPath INBOX = MailboxPath.forUser("[email protected]", "INBOX"); + public static final int LIMIT = 0; + private MailboxManager mailboxManager; + private MailboxSessionMapperFactory mailboxSessionMapperFactory; + private ListeningMessageSearchIndex messageSearchIndex; + + private ReIndexer reIndexer; + + @Before + public void setUp() { + mailboxManager = mock(MailboxManager.class); + mailboxSessionMapperFactory = mock(MailboxSessionMapperFactory.class); + messageSearchIndex = mock(ListeningMessageSearchIndex.class); + reIndexer = new ReIndexerImpl(mailboxManager, messageSearchIndex, mailboxSessionMapperFactory); + } + + @Test + public void test() throws Exception { + final MockMailboxSession mockMailboxSession = new MockMailboxSession("re-indexing"); + when(mailboxManager.createSystemSession(any(String.class))) + .thenReturn(mockMailboxSession); + final MessageMapper messageMapper = mock(MessageMapper.class); + final MailboxMapper mailboxMapper = mock(MailboxMapper.class); + when(mailboxSessionMapperFactory.getMessageMapper(any(MailboxSession.class))) + .thenReturn(messageMapper); + when(mailboxSessionMapperFactory.getMailboxMapper(any(MailboxSession.class))) + .thenReturn(mailboxMapper); + final MailboxMessage message = new MessageBuilder().build(); + final SimpleMailbox mailbox = new SimpleMailbox(INBOX, 42); + mailbox.setMailboxId(message.getMailboxId()); + when(mailboxMapper.findMailboxByPath(INBOX)).thenReturn(mailbox); + when(messageMapper.findInMailbox(mailbox, MessageRange.all(), MessageMapper.FetchType.Full, LIMIT)) + .thenReturn(Lists.newArrayList(message).iterator()); + + reIndexer.reIndex(INBOX); + + verify(mailboxManager).createSystemSession(any(String.class)); + verify(mailboxSessionMapperFactory).getMailboxMapper(mockMailboxSession); + verify(mailboxSessionMapperFactory).getMessageMapper(mockMailboxSession); + verify(mailboxMapper).findMailboxByPath(INBOX); + verify(messageMapper).findInMailbox(mailbox, MessageRange.all(), MessageMapper.FetchType.Full, LIMIT); + verify(mailboxManager).addListener(eq(INBOX), any(MailboxListener.class), any(MailboxSession.class)); + verify(mailboxManager).removeListener(eq(INBOX), any(MailboxListener.class), any(MailboxSession.class)); + verify(messageSearchIndex).add(any(MailboxSession.class), eq(mailbox), eq(message)); + verify(messageSearchIndex).deleteAll(any(MailboxSession.class), eq(mailbox)); + verifyNoMoreInteractions(mailboxMapper, mailboxSessionMapperFactory, messageSearchIndex, messageMapper, mailboxMapper); + } + + @Test + public void mailboxPathUserShouldBeUsedWhenReIndexing() throws Exception { + MockMailboxSession systemMailboxSession = new MockMailboxSession("re-indexing"); + when(mailboxManager.createSystemSession("re-indexing")) + .thenReturn(systemMailboxSession); + MailboxMapper mailboxMapper = mock(MailboxMapper.class); + when(mailboxSessionMapperFactory.getMailboxMapper(systemMailboxSession)) + .thenReturn(mailboxMapper); + + String user1 = "[email protected]"; + MailboxPath user1MailboxPath = MailboxPath.forUser(user1, "Inbox"); + MockMailboxSession user1MailboxSession = new MockMailboxSession(user1); + when(mailboxManager.createSystemSession(user1)) + .thenReturn(user1MailboxSession); + MailboxMapper user1MailboxMapper = mock(MailboxMapper.class); + when(mailboxSessionMapperFactory.getMailboxMapper(user1MailboxSession)) + .thenReturn(user1MailboxMapper); + Mailbox user1Mailbox = mock(Mailbox.class); + when(user1MailboxMapper.findMailboxByPath(user1MailboxPath)) + .thenReturn(user1Mailbox); + MessageMapper user1MessageMapper = mock(MessageMapper.class); + when(mailboxSessionMapperFactory.getMessageMapper(user1MailboxSession)) + .thenReturn(user1MessageMapper); + MailboxMessage user1MailboxMessage = mock(MailboxMessage.class); + when(user1MessageMapper.findInMailbox(user1Mailbox, MessageRange.all(), MessageMapper.FetchType.Full, ReIndexerImpl.NO_LIMIT)) + .thenReturn(ImmutableList.of(user1MailboxMessage).iterator()); + when(user1MailboxMessage.getUid()) + .thenReturn(MessageUid.of(1)); + + when(mailboxManager.list(systemMailboxSession)) + .thenReturn(ImmutableList.of(user1MailboxPath)); + + reIndexer.reIndex(); + + verify(messageSearchIndex).deleteAll(user1MailboxSession, user1Mailbox); + verify(messageSearchIndex).add(user1MailboxSession, user1Mailbox, user1MailboxMessage); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/0c652ab7/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/registrations/GlobalRegistrationTest.java ---------------------------------------------------------------------- diff --git a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/registrations/GlobalRegistrationTest.java b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/registrations/GlobalRegistrationTest.java new file mode 100644 index 0000000..7ebd5d3 --- /dev/null +++ b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/registrations/GlobalRegistrationTest.java @@ -0,0 +1,85 @@ +/**************************************************************** + * 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.registrations; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Optional; + +import org.apache.james.core.quota.QuotaCount; +import org.apache.james.core.quota.QuotaSize; +import org.apache.james.mailbox.MailboxListener; +import org.apache.james.mailbox.mock.MockMailboxSession; +import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.model.QuotaRoot; +import org.apache.james.mailbox.store.event.EventFactory; +import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox; +import org.junit.Before; +import org.junit.Test; + +public class GlobalRegistrationTest { + public static final MailboxPath INBOX = MailboxPath.forUser("[email protected]", "INBOX"); + public static final MailboxPath NEW_PATH = MailboxPath.forUser("[email protected]", "INBOX.new"); + public static final int UID_VALIDITY = 45; + public static final SimpleMailbox MAILBOX = new SimpleMailbox(INBOX, UID_VALIDITY); + public static final SimpleMailbox NEW_MAILBOX = new SimpleMailbox(NEW_PATH, UID_VALIDITY); + + private GlobalRegistration globalRegistration; + private EventFactory eventFactory; + private MockMailboxSession session; + + @Before + public void setUp() { + eventFactory = new EventFactory(); + session = new MockMailboxSession("test"); + globalRegistration = new GlobalRegistration(); + } + + @Test + public void pathToIndexShouldNotBeChangedByDefault() { + assertThat(globalRegistration.getPathToIndex(INBOX).get()).isEqualTo(INBOX); + } + + @Test + public void pathToIndexShouldNotBeChangedByAddedEvents() { + MailboxListener.MailboxEvent event = eventFactory.mailboxAdded(session, MAILBOX); + globalRegistration.event(event); + assertThat(globalRegistration.getPathToIndex(INBOX).get()).isEqualTo(INBOX); + } + + @Test + public void pathToIndexShouldBeNullifiedByDeletedEvents() { + QuotaRoot quotaRoot = QuotaRoot.quotaRoot("root", Optional.empty()); + QuotaCount quotaCount = QuotaCount.count(123); + QuotaSize quotaSize = QuotaSize.size(456); + MailboxListener.MailboxEvent event = eventFactory.mailboxDeleted(session, MAILBOX, quotaRoot, quotaCount, quotaSize); + globalRegistration.event(event); + assertThat(globalRegistration.getPathToIndex(INBOX)).isEqualTo(Optional.empty()); + } + + @Test + public void pathToIndexShouldBeModifiedByRenamedEvents() { + MailboxListener.MailboxEvent event = eventFactory.mailboxRenamed(session, INBOX, NEW_MAILBOX); + globalRegistration.event(event); + assertThat(globalRegistration.getPathToIndex(INBOX).get()).isEqualTo(NEW_PATH); + } + + +} http://git-wip-us.apache.org/repos/asf/james-project/blob/0c652ab7/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/registrations/MailboxRegistrationTest.java ---------------------------------------------------------------------- diff --git a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/registrations/MailboxRegistrationTest.java b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/registrations/MailboxRegistrationTest.java new file mode 100644 index 0000000..743c1f8 --- /dev/null +++ b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/registrations/MailboxRegistrationTest.java @@ -0,0 +1,107 @@ +/**************************************************************** + * 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.registrations; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Date; +import java.util.TreeMap; + +import javax.mail.Flags; + +import org.apache.james.mailbox.MailboxListener; +import org.apache.james.mailbox.MessageUid; +import org.apache.james.mailbox.mock.MockMailboxSession; +import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.model.MessageMetaData; +import org.apache.james.mailbox.model.UpdatedFlags; +import org.apache.james.mailbox.store.SimpleMessageMetaData; +import org.apache.james.mailbox.store.event.EventFactory; +import org.apache.james.mailbox.store.mail.model.DefaultMessageId; +import org.apache.james.mailbox.store.mail.model.MailboxMessage; +import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox; +import org.apache.mailbox.tools.indexer.events.FlagsMessageEvent; +import org.apache.mailbox.tools.indexer.events.MessageDeletedEvent; +import org.junit.Before; +import org.junit.Test; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; + +public class MailboxRegistrationTest { + + public static final MailboxPath INBOX = MailboxPath.forUser("[email protected]", "INBOX"); + public static final MessageUid UID = MessageUid.of(18); + public static final int UID_VALIDITY = 45; + public static final SimpleMailbox MAILBOX = new SimpleMailbox(INBOX, UID_VALIDITY); + public static final int MOD_SEQ = 21; + public static final int SIZE = 41; + public static final Flags NEW_FLAGS = new Flags(Flags.Flag.ANSWERED); + private MailboxRegistration mailboxRegistration; + private EventFactory eventFactory; + private MockMailboxSession session; + + @Before + public void setUp() { + session = new MockMailboxSession("test"); + eventFactory = new EventFactory(); + mailboxRegistration = new MailboxRegistration(INBOX); + } + + @Test + public void reportedEventsShouldBeInitiallyEmpty() { + assertThat(mailboxRegistration.getImpactingEvents(UID)).isEmpty(); + } + + + @Test + public void addedEventsShouldNotBeReported() { + TreeMap<MessageUid, MessageMetaData> treeMap = new TreeMap<>(); + treeMap.put(UID, new SimpleMessageMetaData(UID, MOD_SEQ, new Flags(), SIZE, new Date(), new DefaultMessageId())); + MailboxListener.MailboxEvent event = eventFactory.added(session, treeMap, MAILBOX, ImmutableMap.<MessageUid, MailboxMessage>of()); + mailboxRegistration.event(event); + assertThat(mailboxRegistration.getImpactingEvents(UID)).isEmpty(); + } + + @Test + public void expungedEventsShouldBeReported() { + TreeMap<MessageUid, MessageMetaData> treeMap = new TreeMap<>(); + treeMap.put(UID, new SimpleMessageMetaData(UID, MOD_SEQ, new Flags(), SIZE, new Date(), new DefaultMessageId())); + MailboxListener.MailboxEvent event = eventFactory.expunged(session, treeMap, MAILBOX); + mailboxRegistration.event(event); + assertThat(mailboxRegistration.getImpactingEvents(UID)).containsExactly(new MessageDeletedEvent(INBOX, UID)); + } + + @Test + public void flagsEventsShouldBeReported() { + MailboxListener.MailboxEvent event = eventFactory.flagsUpdated(session, + Lists.newArrayList(UID), + MAILBOX, + Lists.newArrayList(UpdatedFlags.builder() + .uid(UID) + .modSeq(MOD_SEQ) + .oldFlags(new Flags()) + .newFlags(NEW_FLAGS) + .build())); + mailboxRegistration.event(event); + assertThat(mailboxRegistration.getImpactingEvents(UID)).containsExactly(new FlagsMessageEvent(INBOX, UID, NEW_FLAGS)); + } + +} http://git-wip-us.apache.org/repos/asf/james-project/blob/0c652ab7/mailbox/tools/pom.xml ---------------------------------------------------------------------- diff --git a/mailbox/tools/pom.xml b/mailbox/tools/pom.xml index 978e9a3..342fe84 100644 --- a/mailbox/tools/pom.xml +++ b/mailbox/tools/pom.xml @@ -32,6 +32,7 @@ <name>Apache James :: Mailbox :: Tools</name> <modules> + <module>indexer</module> <module>jpa-migrator</module> <module>maildir-utils</module> </modules> http://git-wip-us.apache.org/repos/asf/james-project/blob/0c652ab7/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 6672d97..929fece 100644 --- a/pom.xml +++ b/pom.xml @@ -879,6 +879,11 @@ </dependency> <dependency> <groupId>${james.groupId}</groupId> + <artifactId>apache-james-mailbox-tools-indexer</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${james.groupId}</groupId> <artifactId>apache-james-mpt-antlib</artifactId> <version>${project.version}</version> </dependency> http://git-wip-us.apache.org/repos/asf/james-project/blob/0c652ab7/server/container/guice/jmx/pom.xml ---------------------------------------------------------------------- diff --git a/server/container/guice/jmx/pom.xml b/server/container/guice/jmx/pom.xml index 5487e34..6d76d07 100644 --- a/server/container/guice/jmx/pom.xml +++ b/server/container/guice/jmx/pom.xml @@ -34,6 +34,10 @@ <dependencies> <dependency> <groupId>${james.groupId}</groupId> + <artifactId>apache-james-mailbox-tools-indexer</artifactId> + </dependency> + <dependency> + <groupId>${james.groupId}</groupId> <artifactId>james-server-data-api</artifactId> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/james-project/blob/0c652ab7/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServerModule.java ---------------------------------------------------------------------- diff --git a/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServerModule.java b/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServerModule.java index 92105a5..1a6fae0 100644 --- a/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServerModule.java +++ b/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServerModule.java @@ -38,7 +38,6 @@ import org.apache.james.lifecycle.api.Configurable; import org.apache.james.mailbox.copier.MailboxCopier; import org.apache.james.mailbox.copier.MailboxCopierImpl; import org.apache.james.mailbox.indexer.ReIndexer; -import org.apache.james.mailbox.indexer.ReIndexerImpl; import org.apache.james.mailetcontainer.api.jmx.MailSpoolerMBean; import org.apache.james.mailetcontainer.impl.JamesMailSpooler; import org.apache.james.rrt.api.RecipientRewriteTableManagementMBean; @@ -50,6 +49,7 @@ import org.apache.james.user.lib.UsersRepositoryManagement; import org.apache.james.utils.ConfigurationPerformer; import org.apache.james.utils.GuiceMailboxManagerResolver; import org.apache.james.utils.PropertiesProvider; +import org.apache.mailbox.tools.indexer.ReIndexerImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
