Author: btellier Date: Sat Nov 28 17:04:19 2015 New Revision: 1716998 URL: http://svn.apache.org/viewvc?rev=1716998&view=rev Log: MAILBOX-259 Re indexing documents in Message search indexes
Added: james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/ james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/ReIndexer.java james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/ReIndexerImpl.java james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/ james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/FlagsMessageEvent.java james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/ImpactingEvent.java james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/ImpactingEventType.java james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/ImpactingMessageEvent.java james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/MessageDeletedEvent.java james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/registrations/ james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/registrations/GlobalRegistration.java james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/registrations/MailboxRegistration.java james/project/trunk/mailbox/tool/src/test/java/org/apache/james/mailbox/indexer/ james/project/trunk/mailbox/tool/src/test/java/org/apache/james/mailbox/indexer/ReIndexerImplTest.java Modified: james/project/trunk/mailbox/tool/pom.xml Modified: james/project/trunk/mailbox/tool/pom.xml URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/tool/pom.xml?rev=1716998&r1=1716997&r2=1716998&view=diff ============================================================================== --- james/project/trunk/mailbox/tool/pom.xml (original) +++ james/project/trunk/mailbox/tool/pom.xml Sat Nov 28 17:04:19 2015 @@ -53,12 +53,6 @@ <artifactId>slf4j-simple</artifactId> </dependency> <dependency> - <groupId>org.apache.james</groupId> - <artifactId>apache-james-mailbox-api</artifactId> - <scope>test</scope> - <type>test-jar</type> - </dependency> - <dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-annotation_1.0_spec</artifactId> </dependency> @@ -71,6 +65,23 @@ <artifactId>junit</artifactId> </dependency> <dependency> + <groupId>org.apache.james</groupId> + <artifactId>apache-james-mailbox-api</artifactId> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>apache-james-mailbox-store</artifactId> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <scope>test</scope> Added: james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/ReIndexer.java URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/ReIndexer.java?rev=1716998&view=auto ============================================================================== --- james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/ReIndexer.java (added) +++ james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/ReIndexer.java Sat Nov 28 17:04:19 2015 @@ -0,0 +1,31 @@ +/**************************************************************** + * 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.exception.MailboxException; +import org.apache.james.mailbox.model.MailboxPath; + +public interface ReIndexer { + + void reIndex(MailboxPath path) throws MailboxException; + + void reIndex() throws MailboxException; + +} Added: james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/ReIndexerImpl.java URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/ReIndexerImpl.java?rev=1716998&view=auto ============================================================================== --- james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/ReIndexerImpl.java (added) +++ james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/ReIndexerImpl.java Sat Nov 28 17:04:19 2015 @@ -0,0 +1,140 @@ +/**************************************************************** + * 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 com.google.common.collect.Iterables; +import org.apache.james.mailbox.MailboxManager; +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.exception.MailboxException; +import org.apache.james.mailbox.indexer.events.FlagsMessageEvent; +import org.apache.james.mailbox.indexer.events.ImpactingEventType; +import org.apache.james.mailbox.indexer.events.ImpactingMessageEvent; +import org.apache.james.mailbox.indexer.registrations.GlobalRegistration; +import org.apache.james.mailbox.indexer.registrations.MailboxRegistration; +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.mail.MessageMapper; +import org.apache.james.mailbox.store.mail.model.Mailbox; +import org.apache.james.mailbox.store.mail.model.MailboxId; +import org.apache.james.mailbox.store.mail.model.Message; +import org.apache.james.mailbox.store.search.ListeningMessageSearchIndex; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * Note about live re-indexation handling : + * + * - Data races may arise... If you modify the stored value between the received event check and the index operation, + * you have an inconsistent behavior. + * + * This class is more about supporting changes in real time for future indexed values. If you change a flags / delete + * mails for instance, you will see it in the indexed value ! + * + * Why only care about updates and deletions ? Additions are already handled by the indexer that behaves normaly. We + * should just "adapt" our indexed value to the latest value, if any. The normal indexer will take care of new stuff. + */ +public class ReIndexerImpl<Id extends MailboxId> implements ReIndexer { + + private static final Logger LOGGER = LoggerFactory.getLogger(ReIndexerImpl.class); + public static final int NO_LIMIT = 0; + + private final MailboxManager mailboxManager; + private final ListeningMessageSearchIndex<Id> messageSearchIndex; + private final MailboxSessionMapperFactory<Id> mailboxSessionMapperFactory; + + public ReIndexerImpl(MailboxManager mailboxManager, + ListeningMessageSearchIndex<Id> messageSearchIndex, + MailboxSessionMapperFactory<Id> mailboxSessionMapperFactory) { + this.mailboxManager = mailboxManager; + this.messageSearchIndex = messageSearchIndex; + this.mailboxSessionMapperFactory = mailboxSessionMapperFactory; + } + + public void reIndex(MailboxPath path) throws MailboxException { + MailboxSession mailboxSession = mailboxManager.createSystemSession("re-indexing", LOGGER); + reIndex(path, mailboxSession); + } + + + public void reIndex() throws MailboxException { + MailboxSession mailboxSession = mailboxManager.createSystemSession("re-indexing", LOGGER); + List<MailboxPath> mailboxPaths = mailboxManager.list(mailboxSession); + GlobalRegistration globalRegistration = new GlobalRegistration(); + mailboxManager.addGlobalListener(globalRegistration, mailboxSession); + try { + for (MailboxPath mailboxPath : mailboxPaths) { + if (globalRegistration.pathNeedsIndexing(mailboxPath)) { + reIndex(mailboxPath, mailboxSession); + } + } + } finally { + mailboxManager.removeGlobalListener(globalRegistration, mailboxSession); + } + } + + private void reIndex(MailboxPath path, MailboxSession mailboxSession) throws MailboxException { + MailboxRegistration mailboxRegistration = new MailboxRegistration(path); + LOGGER.info("Intend to reindex {}",path); + Mailbox<Id> mailbox = mailboxSessionMapperFactory.getMailboxMapper(mailboxSession).findMailboxByPath(path); + messageSearchIndex.delete(mailboxSession, mailbox, MessageRange.all()); + mailboxManager.addListener(path, mailboxRegistration, mailboxSession); + try { + handleIterations(mailboxSession, + mailboxRegistration, + mailbox, + mailboxSessionMapperFactory.getMessageMapper(mailboxSession) + .findInMailbox(mailbox, + MessageRange.all(), + MessageMapper.FetchType.Full, + NO_LIMIT)); + LOGGER.info("Finish to reindex " + path); + } finally { + mailboxManager.removeListener(path, mailboxRegistration, mailboxSession); + } + } + + private void handleIterations(MailboxSession mailboxSession, MailboxRegistration mailboxRegistration, Mailbox<Id> mailbox, Iterator<Message<Id>> iterator) throws MailboxException { + while (iterator.hasNext()) { + Message<Id> message = iterator.next(); + ImpactingMessageEvent impactingMessageEvent = findMostRelevant(mailboxRegistration.getImpactingEvents(message.getUid())); + if (impactingMessageEvent == null) { + messageSearchIndex.add(mailboxSession, mailbox, message); + } else if (impactingMessageEvent instanceof FlagsMessageEvent) { + message.setFlags(((FlagsMessageEvent) impactingMessageEvent).getFlags()); + messageSearchIndex.add(mailboxSession, mailbox, message); + } + } + } + + private ImpactingMessageEvent findMostRelevant(Collection<ImpactingMessageEvent> messageEvents) { + for (ImpactingMessageEvent impactingMessageEvent : messageEvents) { + if (impactingMessageEvent.getType().equals(ImpactingEventType.Deletion)) { + return impactingMessageEvent; + } + } + return Iterables.getLast(messageEvents, null); + } + +} Added: james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/FlagsMessageEvent.java URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/FlagsMessageEvent.java?rev=1716998&view=auto ============================================================================== --- james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/FlagsMessageEvent.java (added) +++ james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/FlagsMessageEvent.java Sat Nov 28 17:04:19 2015 @@ -0,0 +1,56 @@ +/**************************************************************** + * 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.events; + +import org.apache.james.mailbox.model.MailboxPath; + +import javax.mail.Flags; + +public class FlagsMessageEvent implements ImpactingMessageEvent { + + private final MailboxPath mailboxPath; + private final long uid; + private final Flags flags; + + public FlagsMessageEvent(MailboxPath mailboxPath, long uid, Flags flags) { + this.mailboxPath = mailboxPath; + this.uid = uid; + this.flags = flags; + } + + @Override + public long getUid() { + return uid; + } + + @Override + public MailboxPath getMailboxPath() { + return mailboxPath; + } + + @Override + public ImpactingEventType getType() { + return ImpactingEventType.FlagsUpdate; + } + + public Flags getFlags() { + return flags; + } +} Added: james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/ImpactingEvent.java URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/ImpactingEvent.java?rev=1716998&view=auto ============================================================================== --- james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/ImpactingEvent.java (added) +++ james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/ImpactingEvent.java Sat Nov 28 17:04:19 2015 @@ -0,0 +1,30 @@ +/**************************************************************** + * 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.events; + +import org.apache.james.mailbox.model.MailboxPath; + +public interface ImpactingEvent { + + MailboxPath getMailboxPath(); + + ImpactingEventType getType(); + +} Added: james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/ImpactingEventType.java URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/ImpactingEventType.java?rev=1716998&view=auto ============================================================================== --- james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/ImpactingEventType.java (added) +++ james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/ImpactingEventType.java Sat Nov 28 17:04:19 2015 @@ -0,0 +1,31 @@ +/**************************************************************** + * 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.events; + +public enum ImpactingEventType { + Deletion, + FlagsUpdate, + MailboxDeletion, + MailboxRename + + /* + Note : additions are never impacting as it is well handled in real time by the existing indexer + */ +} Added: james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/ImpactingMessageEvent.java URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/ImpactingMessageEvent.java?rev=1716998&view=auto ============================================================================== --- james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/ImpactingMessageEvent.java (added) +++ james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/ImpactingMessageEvent.java Sat Nov 28 17:04:19 2015 @@ -0,0 +1,26 @@ +/**************************************************************** + * 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.events; + +public interface ImpactingMessageEvent extends ImpactingEvent { + + long getUid(); + +} Added: james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/MessageDeletedEvent.java URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/MessageDeletedEvent.java?rev=1716998&view=auto ============================================================================== --- james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/MessageDeletedEvent.java (added) +++ james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/events/MessageDeletedEvent.java Sat Nov 28 17:04:19 2015 @@ -0,0 +1,48 @@ +/**************************************************************** + * 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.events; + +import org.apache.james.mailbox.model.MailboxPath; + +public class MessageDeletedEvent implements ImpactingMessageEvent { + + private final MailboxPath mailboxPath; + private final long uid; + + public MessageDeletedEvent(MailboxPath mailboxPath, long uid) { + this.mailboxPath = mailboxPath; + this.uid = uid; + } + + @Override + public long getUid() { + return uid; + } + + @Override + public MailboxPath getMailboxPath() { + return mailboxPath; + } + + @Override + public ImpactingEventType getType() { + return ImpactingEventType.Deletion; + } +} Added: james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/registrations/GlobalRegistration.java URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/registrations/GlobalRegistration.java?rev=1716998&view=auto ============================================================================== --- james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/registrations/GlobalRegistration.java (added) +++ james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/registrations/GlobalRegistration.java Sat Nov 28 17:04:19 2015 @@ -0,0 +1,57 @@ +/**************************************************************** + * 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.registrations; + +import org.apache.james.mailbox.MailboxListener; +import org.apache.james.mailbox.model.MailboxPath; + +import java.util.concurrent.ConcurrentHashMap; + +public class GlobalRegistration implements MailboxListener { + + private final ConcurrentHashMap<MailboxPath, Boolean> impactingEvents; + + public GlobalRegistration() { + this.impactingEvents = new ConcurrentHashMap<MailboxPath, Boolean>(); + } + + public boolean pathNeedsIndexing(MailboxPath mailboxPath) { + return impactingEvents.get(mailboxPath) != null; + } + + @Override + public ListenerType getType() { + return ListenerType.EACH_NODE; + } + + @Override + public ExecutionMode getExecutionMode() { + return ExecutionMode.SYNCHRONOUS; + } + + @Override + public void event(Event event) { + if (event instanceof MailboxDeletion) { + impactingEvents.put(event.getMailboxPath(), true); + } else if (event instanceof Expunged) { + impactingEvents.put(event.getMailboxPath(), true); + } + } +} Added: james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/registrations/MailboxRegistration.java URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/registrations/MailboxRegistration.java?rev=1716998&view=auto ============================================================================== --- james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/registrations/MailboxRegistration.java (added) +++ james/project/trunk/mailbox/tool/src/main/java/org/apache/james/mailbox/indexer/registrations/MailboxRegistration.java Sat Nov 28 17:04:19 2015 @@ -0,0 +1,73 @@ +/**************************************************************** + * 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.registrations; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; +import org.apache.james.mailbox.MailboxListener; +import org.apache.james.mailbox.indexer.events.FlagsMessageEvent; +import org.apache.james.mailbox.indexer.events.ImpactingMessageEvent; +import org.apache.james.mailbox.indexer.events.MessageDeletedEvent; +import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.model.UpdatedFlags; + +import java.util.Collection; +import java.util.List; + +public class MailboxRegistration implements MailboxListener { + + private final Multimap<Long, ImpactingMessageEvent> impactingMessageEvents; + private final MailboxPath mailboxPath; + + public MailboxRegistration(MailboxPath mailboxPath) { + this.impactingMessageEvents = Multimaps.synchronizedMultimap(ArrayListMultimap.<Long, ImpactingMessageEvent>create()); + this.mailboxPath = mailboxPath; + } + + @Override + public ListenerType getType() { + return ListenerType.MAILBOX; + } + + @Override + public ExecutionMode getExecutionMode() { + return ExecutionMode.SYNCHRONOUS; + } + + public List<ImpactingMessageEvent> getImpactingEvents(long uid) { + return ImmutableList.copyOf(impactingMessageEvents.get(uid)); + } + + @Override + public void event(Event event) { + if (event instanceof FlagsUpdated) { + for (UpdatedFlags updatedFlags : ((FlagsUpdated) event).getUpdatedFlags()) { + impactingMessageEvents.put(updatedFlags.getUid(), new FlagsMessageEvent(mailboxPath, updatedFlags.getUid(), updatedFlags.getNewFlags())); + } + } else if (event instanceof Expunged) { + for (Long uid: ((Expunged) event).getUids()) { + impactingMessageEvents.put(uid, new MessageDeletedEvent(mailboxPath, uid)); + } + } + } + +} Added: james/project/trunk/mailbox/tool/src/test/java/org/apache/james/mailbox/indexer/ReIndexerImplTest.java URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/tool/src/test/java/org/apache/james/mailbox/indexer/ReIndexerImplTest.java?rev=1716998&view=auto ============================================================================== --- james/project/trunk/mailbox/tool/src/test/java/org/apache/james/mailbox/indexer/ReIndexerImplTest.java (added) +++ james/project/trunk/mailbox/tool/src/test/java/org/apache/james/mailbox/indexer/ReIndexerImplTest.java Sat Nov 28 17:04:19 2015 @@ -0,0 +1,123 @@ +/**************************************************************** + * 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 static org.mockito.Matchers.any; +import static org.mockito.Matchers.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.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.TestId; +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.Message; +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 org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.slf4j.Logger; + +import java.util.Iterator; + +public class ReIndexerImplTest { + + public static final MailboxPath INBOX = new MailboxPath("#private", "be...@apache.org", "INBOX"); + public static final int LIMIT = 0; + private MailboxManager mailboxManager; + private MailboxSessionMapperFactory<TestId> mailboxSessionMapperFactory; + private ListeningMessageSearchIndex<TestId> messageSearchIndex; + + private ReIndexer reIndexer; + + @SuppressWarnings("unchecked") + @Before + public void setUp() { + mailboxManager = mock(MailboxManager.class); + mailboxSessionMapperFactory = mock(MailboxSessionMapperFactory.class); + messageSearchIndex = mock(ListeningMessageSearchIndex.class); + reIndexer = new ReIndexerImpl<TestId>(mailboxManager, messageSearchIndex, mailboxSessionMapperFactory); + } + + @SuppressWarnings("unchecked") + @Test + public void test() throws Exception { + final MockMailboxSession mockMailboxSession = new MockMailboxSession("re-indexing"); + when(mailboxManager.createSystemSession(any(String.class), any(Logger.class))).thenAnswer(new Answer<MailboxSession>() { + @Override + public MailboxSession answer(InvocationOnMock invocationOnMock) throws Throwable { + return mockMailboxSession; + } + }); + final MessageMapper<TestId> messageMapper = mock(MessageMapper.class); + final MailboxMapper<TestId> mailboxMapper = mock(MailboxMapper.class); + when(mailboxSessionMapperFactory.getMessageMapper(any(MailboxSession.class))).thenAnswer(new Answer<MessageMapper<TestId>>() { + @Override + public MessageMapper<TestId> answer(InvocationOnMock invocationOnMock) throws Throwable { + return messageMapper; + } + }); + when(mailboxSessionMapperFactory.getMailboxMapper(any(MailboxSession.class))).thenAnswer(new Answer<MailboxMapper<TestId>>() { + @Override + public MailboxMapper<TestId> answer(InvocationOnMock invocationOnMock) throws Throwable { + return mailboxMapper; + } + }); + final Message<TestId> message = new MessageBuilder().build(); + final SimpleMailbox<TestId> mailbox = new SimpleMailbox<TestId>(INBOX, 42); + mailbox.setMailboxId(message.getMailboxId()); + when(mailboxMapper.findMailboxByPath(INBOX)).thenAnswer(new Answer<Mailbox<TestId>>() { + @Override + public Mailbox<TestId> answer(InvocationOnMock invocationOnMock) throws Throwable { + return mailbox; + } + }); + when(messageMapper.findInMailbox(mailbox, MessageRange.all(), MessageMapper.FetchType.Full, LIMIT)).thenAnswer(new Answer<Iterator<Message<TestId>>>() { + @Override + public Iterator<Message<TestId>> answer(InvocationOnMock invocationOnMock) throws Throwable { + return Lists.newArrayList(message).iterator(); + } + }); + reIndexer.reIndex(INBOX); + verify(mailboxManager).createSystemSession(any(String.class), any(Logger.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).delete(any(MailboxSession.class), eq(mailbox), eq(MessageRange.all())); + verifyNoMoreInteractions(mailboxMapper, mailboxSessionMapperFactory, messageSearchIndex, messageMapper, mailboxMapper); + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org