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:33:09 UTC
svn commit: r1688127 - in /james/mailbox/trunk/elasticsearch: ./
src/main/java/org/apache/james/mailbox/elasticsearch/
src/main/java/org/apache/james/mailbox/elasticsearch/events/
src/main/resources/META-INF/spring/ src/test/java/org/apache/james/mailb...
Author: btellier
Date: Mon Jun 29 08:33:09 2015
New Revision: 1688127
URL: http://svn.apache.org/r1688127
Log:
MAILBOX-242 Add event listener on messages - patch contributed by Antoine Duprat
Added:
james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/
james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/
james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
Modified:
james/mailbox/trunk/elasticsearch/pom.xml
james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/NodeProvider.java
james/mailbox/trunk/elasticsearch/src/main/resources/META-INF/spring/mailbox-elasticsearch.xml
Modified: james/mailbox/trunk/elasticsearch/pom.xml
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/pom.xml?rev=1688127&r1=1688126&r2=1688127&view=diff
==============================================================================
--- james/mailbox/trunk/elasticsearch/pom.xml (original)
+++ james/mailbox/trunk/elasticsearch/pom.xml Mon Jun 29 08:33:09 2015
@@ -97,6 +97,10 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.apache.james</groupId>
+ <artifactId>apache-james-mailbox-store</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>4.10.4</version>
@@ -109,6 +113,12 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <version>3.3.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>1.5.2</version>
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=1688127&r1=1688126&r2=1688127&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:33:09 2015
@@ -33,7 +33,7 @@ public class NodeProvider {
.clusterName(clusterName)
.settings(ImmutableSettings.builder()
.put(GLOBAL_NETWORK_HOST_SETTING, masterHost)
- .put(SCRIPT_DISABLE_DYNAMIC, true))
+ .put(SCRIPT_DISABLE_DYNAMIC, false))
.client(true)
.node()
.start();
Added: 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=1688127&view=auto
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java (added)
+++ james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java Mon Jun 29 08:33:09 2015
@@ -0,0 +1,106 @@
+/****************************************************************
+ * 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.events;
+
+import java.util.Iterator;
+
+import javax.mail.Flags;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.elasticsearch.ElasticSearchIndexer;
+import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson;
+import org.apache.james.mailbox.exception.MailboxException;
+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;
+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;
+
+
+public class ElasticSearchListeningMessageSearchIndex<Id extends MailboxId> extends ListeningMessageSearchIndex<Id> {
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(ElasticSearchListeningMessageSearchIndex.class);
+ private final static int NO_LIMIT = -1;
+ private final static String ID_SEPARATOR = ":";
+
+ private final ElasticSearchIndexer indexer;
+ private final MessageToElasticSearchJson messageToElasticSearchJson;
+
+ public ElasticSearchListeningMessageSearchIndex(MessageMapperFactory<Id> factory,
+ ElasticSearchIndexer indexer, MessageToElasticSearchJson messageToElasticSearchJson) {
+ super(factory);
+ this.indexer = indexer;
+ this.messageToElasticSearchJson = messageToElasticSearchJson;
+ }
+
+ @Override
+ public Iterator<Long> search(MailboxSession session, Mailbox<Id> mailbox, SearchQuery searchQuery) throws MailboxException {
+ throw new NotImplementedException();
+ }
+
+ @Override
+ public void add(MailboxSession session, Mailbox<Id> mailbox, Message<Id> message) throws MailboxException {
+ try {
+ indexer.indexMessage(indexIdFor(mailbox, message.getUid()), messageToElasticSearchJson.convertToJson(message));
+ } catch (Exception e) {
+ LOGGER.error("Error when indexing message " + message.getUid(), e);
+ }
+ }
+
+ @Override
+ public void delete(MailboxSession session, Mailbox<Id> mailbox, MessageRange range) throws MailboxException {
+ if (range.getType() == Type.ALL) {
+ indexer.deleteAllWithIdStarting(mailbox.getMailboxId() + ID_SEPARATOR);
+ } else {
+ range.forEach(messageId -> {
+ try {
+ indexer.deleteMessage(indexIdFor(mailbox, messageId));
+ } catch (Exception e) {
+ LOGGER.error("Error when deleting index for message " + messageId, e);
+ }
+ });
+ }
+ }
+
+ @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);
+ }
+ });
+ }
+
+ private String indexIdFor(Mailbox<Id> mailbox, long messageId) {
+ return String.join(ID_SEPARATOR, mailbox.getMailboxId().serialize(), String.valueOf(messageId));
+ }
+
+}
Modified: james/mailbox/trunk/elasticsearch/src/main/resources/META-INF/spring/mailbox-elasticsearch.xml
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/src/main/resources/META-INF/spring/mailbox-elasticsearch.xml?rev=1688127&r1=1688126&r2=1688127&view=diff
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/main/resources/META-INF/spring/mailbox-elasticsearch.xml (original)
+++ james/mailbox/trunk/elasticsearch/src/main/resources/META-INF/spring/mailbox-elasticsearch.xml Mon Jun 29 08:33:09 2015
@@ -22,14 +22,28 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+ <property name="ignoreUnresolvablePlaceholders" value="true"/>
+ <property name ="location" value="classpath:elasticsearch.properties"/>
+ </bean>
+
+ <bean id="elasticsearch-listener" class="org.apache.james.mailbox.elasticsearch.events.ElasticSearchListeningMessageSearchIndex">
+ <constructor-arg index="0" ref="elasticsearch-node"/>
+ <constructor-arg index="1" ref="elasticsearch-indexer"/>
+ <constructor-arg index="2" ref="elasticsearch-json"/>
+ </bean>
<bean id="elasticsearch-indexer" class="org.apache.james.mailbox.elasticsearch.ElasticSearchIndexer">
<constructor-arg index="0" ref="elasticsearch-node"/>
</bean>
- <bean id="elasticsearch-node" class="org.apache.james.mailbox.cassandra.elasticsearch.NodeProvider" factory-method="createNodeForClusterName">
- <constructor-arg index="0" ref="${elasticsearch.clusterName}"/>
- <constructor-arg index="1" ref="${elasticsearch.masterHost}"/>
+ <bean id="elasticsearch-node" class="org.apache.james.mailbox.elasticsearch.NodeProvider" factory-method="createNodeForClusterName">
+ <constructor-arg index="0" value="${elasticsearch.clusterName}"/>
+ <constructor-arg index="1" value="${elasticsearch.masterHost}"/>
+ </bean>
+
+ <bean id="elasticsearch-json" class="org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson">
</bean>
</beans>
Added: 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=1688127&view=auto
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java (added)
+++ james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java Mon Jun 29 08:33:09 2015
@@ -0,0 +1,307 @@
+/****************************************************************
+ * 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.events;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyString;
+import static org.easymock.EasyMock.createControl;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.LongStream;
+
+import javax.mail.Flags;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.elasticsearch.ElasticSearchIndexer;
+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;
+import org.easymock.IMocksControl;
+import org.elasticsearch.ElasticsearchException;
+import org.elasticsearch.action.delete.DeleteResponse;
+import org.elasticsearch.action.index.IndexResponse;
+import org.elasticsearch.action.update.UpdateResponse;
+import org.junit.Before;
+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 {
+
+ private IMocksControl control;
+
+ private MessageMapperFactory<TestId> mapperFactory;
+ private ElasticSearchIndexer indexer;
+ private MessageToElasticSearchJson messageToElasticSearchJson;
+
+ private ElasticSearchListeningMessageSearchIndex<TestId> testee;
+
+ @Before
+ @SuppressWarnings("unchecked")
+ public void setup() throws JsonProcessingException {
+ control = createControl();
+
+ mapperFactory = control.createMock(MessageMapperFactory.class);
+ 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);
+ }
+
+ @Test(expected=NotImplementedException.class)
+ public void searchShouldThrow() throws Exception {
+ control.replay();
+ testee.search(null, null, null);
+ control.verify();
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void addShouldIndex() throws Exception {
+ MailboxSession session = control.createMock(MailboxSession.class);
+ Mailbox<TestId> mailbox = control.createMock(Mailbox.class);
+
+ long messageId = 1;
+ TestId mailboxId = TestId.of(12);
+ expect(mailbox.getMailboxId()).andReturn(mailboxId);
+ Message<TestId> message = mockedMessage(messageId, mailboxId);
+
+ IndexResponse expectedIndexResponse = control.createMock(IndexResponse.class);
+ expect(indexer.indexMessage(eq(mailboxId.serialize() + ":" + messageId), anyString()))
+ .andReturn(expectedIndexResponse);
+
+ control.replay();
+ testee.add(session, mailbox, message);
+ control.verify();
+ }
+
+ @SuppressWarnings("unchecked")
+ private Message<TestId> mockedMessage(long messageId, TestId mailboxId) throws IOException {
+ Message<TestId> message = control.createMock(Message.class);
+ expect(message.getUid()).andReturn(messageId).anyTimes();
+ return message;
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void addShouldNotPropagateExceptionWhenExceptionOccurs() throws Exception {
+ MailboxSession session = control.createMock(MailboxSession.class);
+ Mailbox<TestId> mailbox = control.createMock(Mailbox.class);
+
+ long messageId = 1;
+ TestId mailboxId = TestId.of(12);
+ Message<TestId> message = mockedMessage(messageId, mailboxId);
+ expect(mailbox.getMailboxId()).andReturn(mailboxId);
+
+ expect(indexer.indexMessage(eq(mailboxId.serialize() + ":" + messageId), anyString()))
+ .andThrow(new ElasticsearchException(""));
+
+ control.replay();
+ testee.add(session, mailbox, message);
+ control.verify();
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void deleteShouldWork() throws Exception {
+ MailboxSession session = control.createMock(MailboxSession.class);
+ Mailbox<TestId> mailbox = control.createMock(Mailbox.class);
+ long messageId = 1;
+ MessageRange messageRange = MessageRange.one(messageId);
+ TestId mailboxId = TestId.of(12);
+ expect(mailbox.getMailboxId()).andReturn(mailboxId);
+
+ DeleteResponse expectedDeleteResponse = control.createMock(DeleteResponse.class);
+ expect(indexer.deleteMessage(mailboxId.serialize() + ":" + messageId))
+ .andReturn(expectedDeleteResponse);
+
+ control.replay();
+ testee.delete(session, mailbox, messageRange);
+ control.verify();
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void deleteShouldWorkWhenMultipleMessageIds() throws Exception {
+ MailboxSession session = control.createMock(MailboxSession.class);
+ Mailbox<TestId> mailbox = control.createMock(Mailbox.class);
+ long firstMessageId = 1;
+ long lastMessageId = 10;
+ MessageRange messageRange = MessageRange.range(firstMessageId, lastMessageId);
+ TestId mailboxId = TestId.of(12);
+ expect(mailbox.getMailboxId()).andReturn(mailboxId).times(10);
+
+ LongStream.rangeClosed(firstMessageId, lastMessageId)
+ .forEach(messageId -> {
+ DeleteResponse expectedDeleteResponse = control.createMock(DeleteResponse.class);
+ expect(indexer.deleteMessage(mailboxId.serialize() + ":" + messageId))
+ .andReturn(expectedDeleteResponse);
+ });
+
+ control.replay();
+ testee.delete(session, mailbox, messageRange);
+ control.verify();
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void deleteShouldNotPropagateExceptionWhenExceptionOccurs() throws Exception {
+ MailboxSession session = control.createMock(MailboxSession.class);
+ Mailbox<TestId> mailbox = control.createMock(Mailbox.class);
+ long messageId = 1;
+ MessageRange messageRange = MessageRange.one(messageId);
+ TestId mailboxId = TestId.of(12);
+ expect(mailbox.getMailboxId()).andReturn(mailboxId);
+
+ expect(indexer.deleteMessage(mailboxId.serialize() + ":" + messageId))
+ .andThrow(new ElasticsearchException(""));
+
+ control.replay();
+ 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);
+ 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);
+
+ UpdateResponse expectedUpdateResponse = control.createMock(UpdateResponse.class);
+ expect(indexer.updateMessage(eq(mailboxId.serialize() + ":" + messageId), anyString()))
+ .andReturn(expectedUpdateResponse);
+
+ control.replay();
+ testee.update(session, mailbox, messageRange, flags);
+ 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);
+ 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 -> {
+ 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()))
+ .andReturn(expectedUpdateResponse);
+ } catch (Exception e) {
+ Throwables.propagate(e);
+ } finally {
+ }
+ });
+
+
+ control.replay();
+ testee.update(session, mailbox, messageRange, flags);
+ 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);
+ 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);
+
+ expect(indexer.updateMessage(eq(mailboxId.serialize() + ":" + messageId), anyString()))
+ .andThrow(new ElasticsearchException(""));
+
+ control.replay();
+ testee.update(session, mailbox, messageRange, flags);
+ control.verify();
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org