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/06/29 10:34:21 UTC

svn commit: r1688129 - in /james/mailbox/trunk: elasticsearch/ elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/ elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ elasticsearch/src/main/java/org/apache/james/m...

Author: btellier
Date: Mon Jun 29 08:34:21 2015
New Revision: 1688129

URL: http://svn.apache.org/r1688129
Log:
MAILBOX-155 Update index content without reading messages in base

Added:
    james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageUpdateJson.java
    james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/EmbeddedElasticSearch.java
Modified:
    james/mailbox/trunk/elasticsearch/pom.xml
    james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIndexer.java
    james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/NodeProvider.java
    james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
    james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJson.java
    james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIndexerTest.java
    james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
    james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJsonTest.java
    james/mailbox/trunk/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
    james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/LazyMessageSearchIndex.java
    james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java

Modified: james/mailbox/trunk/elasticsearch/pom.xml
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/pom.xml?rev=1688129&r1=1688128&r2=1688129&view=diff
==============================================================================
--- james/mailbox/trunk/elasticsearch/pom.xml (original)
+++ james/mailbox/trunk/elasticsearch/pom.xml Mon Jun 29 08:34:21 2015
@@ -139,6 +139,11 @@
             <artifactId>slf4j-simple</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.codehaus.groovy</groupId>
+            <artifactId>groovy-all</artifactId>
+            <version>2.3.2</version>
+        </dependency>
     </dependencies>
 
     <profiles>

Modified: james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIndexer.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIndexer.java?rev=1688129&r1=1688128&r2=1688129&view=diff
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIndexer.java (original)
+++ james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIndexer.java Mon Jun 29 08:34:21 2015
@@ -47,12 +47,12 @@ public class ElasticSearchIndexer {
                 .get();
         }
     }
-    
-    public UpdateResponse updateMessage(String id, String content) {
-        checkArgument(content);
+
+    public UpdateResponse updateMessage(String id, String docUpdated) {
+        checkArgument(docUpdated);
         try (Client client = node.client()) {
             return client.prepareUpdate(MAILBOX_INDEX, MESSAGE_TYPE, id)
-                .setDoc(content)
+                .setDoc(docUpdated)
                 .get();
         }
     }

Modified: james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/NodeProvider.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/NodeProvider.java?rev=1688129&r1=1688128&r2=1688129&view=diff
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/NodeProvider.java (original)
+++ james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/NodeProvider.java Mon Jun 29 08:34:21 2015
@@ -33,7 +33,7 @@ public class NodeProvider {
                 .clusterName(clusterName)
                 .settings(ImmutableSettings.builder()
                         .put(GLOBAL_NETWORK_HOST_SETTING, masterHost)
-                        .put(SCRIPT_DISABLE_DYNAMIC, false))
+                        .put(SCRIPT_DISABLE_DYNAMIC, true))
                 .client(true)
                 .node()
                 .start();

Modified: james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java?rev=1688129&r1=1688128&r2=1688129&view=diff
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java (original)
+++ james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java Mon Jun 29 08:34:21 2015
@@ -30,7 +30,6 @@ import org.apache.james.mailbox.exceptio
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.MessageRange.Type;
 import org.apache.james.mailbox.model.SearchQuery;
-import org.apache.james.mailbox.store.mail.MessageMapper.FetchType;
 import org.apache.james.mailbox.store.mail.MessageMapperFactory;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
 import org.apache.james.mailbox.store.mail.model.MailboxId;
@@ -86,17 +85,17 @@ public class ElasticSearchListeningMessa
     }
 
     @Override
-    public void update(MailboxSession session, Mailbox<Id> mailbox, MessageRange range, Flags flags) throws MailboxException {
-        getFactory().getMessageMapper(session)
-            .findInMailbox(mailbox, range, FetchType.Full, NO_LIMIT)
-            .forEachRemaining(message -> {
-                try {
-                    message.setFlags(flags);
-                    indexer.updateMessage(indexIdFor(mailbox, message.getUid()), messageToElasticSearchJson.convertToJson(message));
-                } catch (Exception e) {
-                    LOGGER.error("Error when updating index for message " + message.getUid(), e);
-                }
-            });
+    public void update(MailboxSession session, Mailbox<Id> mailbox, MessageRange range, Flags flags, long modseq) throws MailboxException {
+        range.forEach(messageId -> {
+            try {
+                indexer.updateMessage(
+                    indexIdFor(mailbox, messageId),
+                    messageToElasticSearchJson.getUpdatedJsonMessagePart(flags, modseq));
+            } catch (Exception e) {
+                LOGGER.error("Error when updating index for message " + messageId, e);
+            }
+        });
+
     }
     
     private String indexIdFor(Mailbox<Id> mailbox, long messageId) {

Modified: james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJson.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJson.java?rev=1688129&r1=1688128&r2=1688129&view=diff
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJson.java (original)
+++ james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJson.java Mon Jun 29 08:34:21 2015
@@ -19,6 +19,8 @@
 
 package org.apache.james.mailbox.elasticsearch.json;
 
+import javax.mail.Flags;
+
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.datatype.guava.GuavaModule;
@@ -41,4 +43,9 @@ public class MessageToElasticSearchJson
         return mapper.writeValueAsString(IndexableMessage.from(message));
     }
 
+    public String getUpdatedJsonMessagePart(Flags flags, long modSeq) throws JsonProcessingException {
+        Preconditions.checkNotNull(flags);
+        return mapper.writeValueAsString(new MessageUpdateJson(flags, modSeq));
+    }
+
 }

Added: james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageUpdateJson.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageUpdateJson.java?rev=1688129&view=auto
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageUpdateJson.java (added)
+++ james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageUpdateJson.java Mon Jun 29 08:34:21 2015
@@ -0,0 +1,59 @@
+
+
+package org.apache.james.mailbox.elasticsearch.json;
+
+import javax.mail.Flags;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class MessageUpdateJson {
+
+    private final Flags flags;
+    private final long modSeq;
+
+    public MessageUpdateJson(Flags flags, long modSeq) {
+        this.flags = flags;
+        this.modSeq = modSeq;
+    }
+
+    @JsonProperty(JsonMessageConstants.IS_ANSWERED)
+    public boolean isAnswered() {
+        return flags.contains(Flags.Flag.ANSWERED);
+    }
+
+    @JsonProperty(JsonMessageConstants.IS_DELETED)
+    public boolean isDeleted() {
+        return flags.contains(Flags.Flag.DELETED);
+    }
+
+    @JsonProperty(JsonMessageConstants.IS_DRAFT)
+    public boolean isDraft() {
+        return flags.contains(Flags.Flag.DRAFT);
+    }
+
+    @JsonProperty(JsonMessageConstants.IS_FLAGGED)
+    public boolean isFlagged() {
+        return flags.contains(Flags.Flag.FLAGGED);
+    }
+
+    @JsonProperty(JsonMessageConstants.IS_RECENT)
+    public boolean isRecent() {
+        return flags.contains(Flags.Flag.RECENT);
+    }
+
+    @JsonProperty(JsonMessageConstants.IS_UNREAD)
+    public boolean isUnRead() {
+        return ! flags.contains(Flags.Flag.SEEN);
+    }
+
+
+    @JsonProperty(JsonMessageConstants.USER_FLAGS)
+    public String[] getUserFlags() {
+        return flags.getUserFlags();
+    }
+
+    @JsonProperty(JsonMessageConstants.MODSEQ)
+    public long getModSeq() {
+        return modSeq;
+    }
+
+}

Modified: james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIndexerTest.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIndexerTest.java?rev=1688129&r1=1688128&r2=1688129&view=diff
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIndexerTest.java (original)
+++ james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIndexerTest.java Mon Jun 29 08:34:21 2015
@@ -49,6 +49,7 @@ public class ElasticSearchIndexerTest {
         node = nodeBuilder().local(true)
                 .settings(ImmutableSettings.builder()
                         .put("path.data", temporaryFolder.newFolder().getAbsolutePath())
+                        .put("script.disable_dynamic",false)
                         .build())
                 .node();
         node.start();
@@ -87,20 +88,27 @@ public class ElasticSearchIndexerTest {
     @Test
     public void updateMessage() throws Exception {
         String messageId = "1";
-        String content = "{\"message\": \"trying out Elasticsearch\"}";
-        
+        String content = "{\"message\": \"trying out Elasticsearch\",\"field\":\"Should be unchanged\"}";
+
         testee.indexMessage(messageId, content);
         awaitForElasticSearch();
-        
-        String updatedContent = "{\"message\": \"mastering out Elasticsearch\"}";
-        testee.updateMessage(messageId, updatedContent);
-        awaitForElasticSearch();
-        
+
+        testee.updateMessage(messageId, "{\"message\": \"mastering out Elasticsearch\"}");
+        EmbeddedElasticSearch.awaitForElasticSearch(node);
+
         try (Client client = node.client()) {
             SearchResponse searchResponse = client.prepareSearch(ElasticSearchIndexer.MAILBOX_INDEX)
-                    .setTypes(ElasticSearchIndexer.MESSAGE_TYPE)
-                    .setQuery(QueryBuilders.matchQuery("message", "mastering"))
-                    .get();
+                .setTypes(ElasticSearchIndexer.MESSAGE_TYPE)
+                .setQuery(QueryBuilders.matchQuery("message", "mastering"))
+                .get();
+            assertThat(searchResponse.getHits().getTotalHits()).isEqualTo(1);
+        }
+
+        try (Client client = node.client()) {
+            SearchResponse searchResponse = client.prepareSearch(ElasticSearchIndexer.MAILBOX_INDEX)
+                .setTypes(ElasticSearchIndexer.MESSAGE_TYPE)
+                .setQuery(QueryBuilders.matchQuery("field", "unchanged"))
+                .get();
             assertThat(searchResponse.getHits().getTotalHits()).isEqualTo(1);
         }
     }

Added: james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/EmbeddedElasticSearch.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/EmbeddedElasticSearch.java?rev=1688129&view=auto
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/EmbeddedElasticSearch.java (added)
+++ james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/EmbeddedElasticSearch.java Mon Jun 29 08:34:21 2015
@@ -0,0 +1,87 @@
+/****************************************************************
+ * 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.elasticsearch;
+
+
+
+import java.io.IOException;
+
+import com.jayway.awaitility.Duration;
+import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
+import org.elasticsearch.action.admin.indices.flush.FlushRequestBuilder;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.settings.ImmutableSettings;
+import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.node.Node;
+import org.junit.rules.TemporaryFolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.jayway.awaitility.Awaitility.await;
+import static org.elasticsearch.node.NodeBuilder.nodeBuilder;
+
+public class EmbeddedElasticSearch {
+
+    private static Logger LOGGER = LoggerFactory.getLogger(EmbeddedElasticSearch.class);
+
+    public static Node provideNode(TemporaryFolder temporaryFolder) throws IOException {
+        Node node = nodeBuilder().local(true)
+            .settings(ImmutableSettings.builder()
+                .put("path.data", temporaryFolder.newFolder().getAbsolutePath())
+                .put("script.disable_dynamic",true)
+                .build())
+            .node();
+        node.start();
+        awaitForElasticSearch(node);
+        return node;
+    }
+
+    public static void shutDown(Node node) {
+        EmbeddedElasticSearch.awaitForElasticSearch(node);
+        try (Client client = node.client()) {
+            node.client()
+                .admin()
+                .indices()
+                .delete(new DeleteIndexRequest(ElasticSearchIndexer.MAILBOX_INDEX))
+                .actionGet();
+        } catch (Exception e) {
+            LOGGER.warn("Error while closing ES connection", e);
+        }
+        node.close();
+    }
+
+    /**
+     * Sometimes, tests are too fast.
+     * This method ensure that ElasticSearch service is up and indices are updated
+     */
+    public static void awaitForElasticSearch(Node node) {
+        await().atMost(Duration.TEN_SECONDS).until(() -> flush(node));
+    }
+
+    private static boolean flush(Node node) {
+        try (Client client = node.client()) {
+            new FlushRequestBuilder(client.admin().indices()).setForce(true).get();
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+}

Modified: james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java?rev=1688129&r1=1688128&r2=1688129&view=diff
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java (original)
+++ james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java Mon Jun 29 08:34:21 2015
@@ -18,6 +18,7 @@
  ****************************************************************/
 package org.apache.james.mailbox.elasticsearch.events;
 
+import static org.easymock.EasyMock.anyLong;
 import static org.easymock.EasyMock.anyObject;
 import static org.easymock.EasyMock.anyString;
 import static org.easymock.EasyMock.createControl;
@@ -26,8 +27,7 @@ import static org.easymock.EasyMock.expe
 import static org.easymock.EasyMock.expectLastCall;
 
 import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.IntStream;
 import java.util.stream.LongStream;
 
 import javax.mail.Flags;
@@ -38,8 +38,6 @@ import org.apache.james.mailbox.elastics
 import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.store.TestId;
-import org.apache.james.mailbox.store.mail.MessageMapper;
-import org.apache.james.mailbox.store.mail.MessageMapper.FetchType;
 import org.apache.james.mailbox.store.mail.MessageMapperFactory;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
 import org.apache.james.mailbox.store.mail.model.Message;
@@ -53,10 +51,10 @@ import org.junit.Test;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
 
 public class ElasticSearchListeningMessageSearchIndexTest {
 
+    public static final long MODSEQ = 18L;
     private IMocksControl control;
     
     private MessageMapperFactory<TestId> mapperFactory;
@@ -74,8 +72,9 @@ public class ElasticSearchListeningMessa
         indexer = control.createMock(ElasticSearchIndexer.class);
         messageToElasticSearchJson = control.createMock(MessageToElasticSearchJson.class);
         expect(messageToElasticSearchJson.convertToJson(anyObject(Message.class))).andReturn("json content").anyTimes();
-        
-        testee = new ElasticSearchListeningMessageSearchIndex<TestId>(mapperFactory, indexer, messageToElasticSearchJson);
+        expect(messageToElasticSearchJson.getUpdatedJsonMessagePart(anyObject(Flags.class), anyLong())).andReturn("json updated content").anyTimes();
+
+        testee = new ElasticSearchListeningMessageSearchIndex<>(mapperFactory, indexer, messageToElasticSearchJson);
     }
     
     @Test(expected=NotImplementedException.class)
@@ -190,25 +189,19 @@ public class ElasticSearchListeningMessa
         testee.delete(session, mailbox, messageRange);
         control.verify();
     }
-    
+
     @Test
     @SuppressWarnings("unchecked")
     public void updateShouldWork() throws Exception {
         MailboxSession session = control.createMock(MailboxSession.class);
+
         Mailbox<TestId> mailbox = control.createMock(Mailbox.class);
-        Flags flags = control.createMock(Flags.class);
+        Flags flags = new Flags();
+
         long messageId = 1;
         TestId mailboxId = TestId.of(12);
         MessageRange messageRange = MessageRange.one(messageId);
-        Message<TestId> message = mockedMessage(messageId, mailboxId);
-        
-        MessageMapper<TestId> messageMapper = control.createMock(MessageMapper.class);
-        expect(mapperFactory.getMessageMapper(session))
-            .andReturn(messageMapper);
-        expect(messageMapper.findInMailbox(mailbox, messageRange, FetchType.Full, -1))
-            .andReturn(ImmutableList.of(message).iterator());
-        
-        message.setFlags(flags);
+
         expectLastCall();
         expect(mailbox.getMailboxId()).andReturn(mailboxId);
         
@@ -217,83 +210,60 @@ public class ElasticSearchListeningMessa
             .andReturn(expectedUpdateResponse);
         
         control.replay();
-        testee.update(session, mailbox, messageRange, flags);
+        testee.update(session, mailbox, messageRange, flags, MODSEQ);
         control.verify();
     }
-    
+
     @Test
     @SuppressWarnings("unchecked")
     public void updateShouldWorkWhenMultipleMessageIds() throws Exception {
         MailboxSession session = control.createMock(MailboxSession.class);
+
         Mailbox<TestId> mailbox = control.createMock(Mailbox.class);
-        Flags flags = control.createMock(Flags.class);
+        Flags flags = new Flags();
+
         long firstMessageId = 1;
         long lastMessageId = 10;
         MessageRange messageRange = MessageRange.range(firstMessageId, lastMessageId);
         
-        MessageMapper<TestId> messageMapper = control.createMock(MessageMapper.class);
-        expect(mapperFactory.getMessageMapper(session))
-            .andReturn(messageMapper);
-        
         TestId mailboxId = TestId.of(12);
-        Message<TestId> message1 = mockedMessage(1, mailboxId);
-        Message<TestId> message2 = mockedMessage(2, mailboxId);
-        Message<TestId> message3 = mockedMessage(3, mailboxId);
-        Message<TestId> message4 = mockedMessage(4, mailboxId);
-        Message<TestId> message5 = mockedMessage(5, mailboxId);
-        Message<TestId> message6 = mockedMessage(6, mailboxId);
-        Message<TestId> message7 = mockedMessage(7, mailboxId);
-        Message<TestId> message8 = mockedMessage(8, mailboxId);
-        Message<TestId> message9 = mockedMessage(9, mailboxId);
-        Message<TestId> message10 = mockedMessage(10, mailboxId);
-        
-        List<Message<TestId>> messages = ImmutableList.of(message1, message2, message3, message4, message5, message6, message7, message8, message9, message10);
-        expect(messageMapper.findInMailbox(mailbox, messageRange, FetchType.Full, -1))
-            .andReturn(messages.iterator());
-        
-        AtomicLong messageId = new AtomicLong(0);
-        messages
-            .forEach(message -> {
+
+        IntStream.range(1, 11).forEach(
+            (uid) -> {
                 try {
-                    message.setFlags(flags);
+
                     expectLastCall();
-                    
-                    long messageIdAsLong = messageId.incrementAndGet();
+
                     expect(mailbox.getMailboxId()).andReturn(mailboxId);
-                    
+
                     UpdateResponse expectedUpdateResponse = control.createMock(UpdateResponse.class);
-                    expect(indexer.updateMessage(eq(mailboxId.serialize() + ":" + messageIdAsLong), anyString()))
+                    expect(indexer.updateMessage(eq(mailboxId.serialize() + ":" + uid), anyString()))
+
                         .andReturn(expectedUpdateResponse);
                 } catch (Exception e) {
                     Throwables.propagate(e);
-                } finally {
                 }
-            });
+            }
+        );
         
         
         control.replay();
-        testee.update(session, mailbox, messageRange, flags);
+        testee.update(session, mailbox, messageRange, flags, MODSEQ);
         control.verify();
     }
-    
+
     @Test
     @SuppressWarnings("unchecked")
     public void updateShouldNotPropagateExceptionWhenExceptionOccurs() throws Exception {
         MailboxSession session = control.createMock(MailboxSession.class);
+
         Mailbox<TestId> mailbox = control.createMock(Mailbox.class);
-        Flags flags = control.createMock(Flags.class);
+        Flags flags = new Flags();
+
         long messageId = 1;
         TestId mailboxId = TestId.of(12);
         MessageRange messageRange = MessageRange.one(messageId);
-        Message<TestId> message = mockedMessage(messageId, mailboxId);
-        
-        MessageMapper<TestId> messageMapper = control.createMock(MessageMapper.class);
-        expect(mapperFactory.getMessageMapper(session))
-            .andReturn(messageMapper);
-        expect(messageMapper.findInMailbox(mailbox, messageRange, FetchType.Full, -1))
-            .andReturn(ImmutableList.of(message).iterator());
-        
-        message.setFlags(flags);
+
         expectLastCall();
         expect(mailbox.getMailboxId()).andReturn(mailboxId);
 
@@ -301,7 +271,7 @@ public class ElasticSearchListeningMessa
             .andThrow(new ElasticsearchException(""));
         
         control.replay();
-        testee.update(session, mailbox, messageRange, flags);
+        testee.update(session, mailbox, messageRange, flags, MODSEQ);
         control.verify();
     }
 }

Modified: james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJsonTest.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJsonTest.java?rev=1688129&r1=1688128&r2=1688129&view=diff
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJsonTest.java (original)
+++ james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJsonTest.java Mon Jun 29 08:34:21 2015
@@ -181,4 +181,21 @@ public class MessageToElasticSearchJsonT
         messageToElasticSearchJson.convertToJson(mailWithNoMailboxId);
     }
 
+    @Test
+    public void getUpdatedJsonMessagePartShouldBehaveWellOnEmptyFlags() throws Exception {
+        assertThatJson(messageToElasticSearchJson.getUpdatedJsonMessagePart(new Flags(), MOD_SEQ))
+            .isEqualTo("{\"modSeq\":42,\"isAnswered\":false,\"isDeleted\":false,\"isDraft\":false,\"isFlagged\":false,\"isRecent\":false,\"userFlags\":[],\"isUnread\":true}");
+    }
+
+    @Test
+    public void getUpdatedJsonMessagePartShouldBehaveWellOnNonEmptyFlags() throws Exception {
+        assertThatJson(messageToElasticSearchJson.getUpdatedJsonMessagePart(new FlagsBuilder().add(Flags.Flag.DELETED, Flags.Flag.FLAGGED).add("user").build(), MOD_SEQ))
+            .isEqualTo("{\"modSeq\":42,\"isAnswered\":false,\"isDeleted\":true,\"isDraft\":false,\"isFlagged\":true,\"isRecent\":false,\"userFlags\":[\"user\"],\"isUnread\":true}");
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void getUpdatedJsonMessagePartShouldThrowIfFlagsIsNull() throws Exception {
+        messageToElasticSearchJson.getUpdatedJsonMessagePart(null, MOD_SEQ);
+    }
+
 }

Modified: james/mailbox/trunk/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java?rev=1688129&r1=1688128&r2=1688129&view=diff
==============================================================================
--- james/mailbox/trunk/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java (original)
+++ james/mailbox/trunk/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java Mon Jun 29 08:34:21 2015
@@ -1202,7 +1202,7 @@ public class LuceneMessageSearchIndex<Id
     /**
      * @see org.apache.james.mailbox.store.search.ListeningMessageSearchIndex#update(org.apache.james.mailbox.MailboxSession, org.apache.james.mailbox.store.mail.model.Mailbox, org.apache.james.mailbox.model.MessageRange, javax.mail.Flags)
      */
-    public void update(MailboxSession session, Mailbox<Id> mailbox, MessageRange range, Flags f) throws MailboxException {
+    public void update(MailboxSession session, Mailbox<Id> mailbox, MessageRange range, Flags f, long modSeq) throws MailboxException {
         try {
             IndexSearcher searcher = new IndexSearcher(IndexReader.open(writer, true));
             BooleanQuery query = new BooleanQuery();

Modified: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/LazyMessageSearchIndex.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/LazyMessageSearchIndex.java?rev=1688129&r1=1688128&r2=1688129&view=diff
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/LazyMessageSearchIndex.java (original)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/LazyMessageSearchIndex.java Mon Jun 29 08:34:21 2015
@@ -101,8 +101,8 @@ public class LazyMessageSearchIndex<Id e
 
 
     @Override
-    public void update(MailboxSession session, Mailbox<Id> mailbox, MessageRange range, Flags flags) throws MailboxException {
-        index.update(session, mailbox, range, flags);
+    public void update(MailboxSession session, Mailbox<Id> mailbox, MessageRange range, Flags flags, long modSeq) throws MailboxException {
+        index.update(session, mailbox, range, flags, modSeq);
     }
 
 }

Modified: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java?rev=1688129&r1=1688128&r2=1688129&view=diff
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java (original)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java Mon Jun 29 08:34:21 2015
@@ -114,7 +114,7 @@ public abstract class ListeningMessageSe
                     while(flags.hasNext()) {
                         UpdatedFlags uFlags = flags.next();
                         try {
-                            update(session, mailbox, MessageRange.one(uFlags.getUid()), uFlags.getNewFlags());
+                            update(session, mailbox, MessageRange.one(uFlags.getUid()), uFlags.getNewFlags(), uFlags.getModSeq());
                         } catch (MailboxException e) {
                             session.getLog().debug("Unable to update flags for message " + uFlags.getUid() + " in index for mailbox " + mailbox, e);
                         }
@@ -167,5 +167,5 @@ public abstract class ListeningMessageSe
      * @param flags
      * @throws MailboxException
      */
-    public abstract void update(MailboxSession session, Mailbox<Id> mailbox, MessageRange range, Flags flags) throws MailboxException;
+    public abstract void update(MailboxSession session, Mailbox<Id> mailbox, MessageRange range, Flags flags, long modseq) throws MailboxException;
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org