You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2015/11/28 18:04:19 UTC

svn commit: r1716998 - in /james/project/trunk/mailbox/tool: ./ src/main/java/org/apache/james/mailbox/indexer/ src/main/java/org/apache/james/mailbox/indexer/events/ src/main/java/org/apache/james/mailbox/indexer/registrations/ src/test/java/org/apach...

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", "benwa@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-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org