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 2019/01/17 06:50:31 UTC

[15/27] james-project git commit: JAMES-2641 MailboxManager should no more implement MailboxListener support

JAMES-2641 MailboxManager should no more implement MailboxListener support

It should rather expose proxy method for the event bus.

Note that these proxy method can be temporarily implemented on top of the Delegating Listener


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/c82c1384
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/c82c1384
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/c82c1384

Branch: refs/heads/master
Commit: c82c13844e7ee19ee06a8d8a57cd8c70ed437e6a
Parents: 7e0fdc6
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Jan 10 10:53:15 2019 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Thu Jan 17 10:23:41 2019 +0700

----------------------------------------------------------------------
 .../apache/james/mailbox/MailboxManager.java    |  10 +-
 .../james/mailbox/MailboxManagerStressTest.java |  17 ++-
 .../james/mailbox/MailboxManagerTest.java       |  20 +--
 .../CassandraMessageIdManagerTestSystem.java    |   2 +-
 ...ticSearchQuotaSearchTestSystemExtension.java |   4 +-
 .../mailbox/store/StoreMailboxManager.java      |  62 +++++---
 .../james/imap/processor/IdleProcessor.java     | 144 ++++++++-----------
 .../processor/base/SelectedMailboxImpl.java     |  30 ++--
 .../processor/base/SelectedMailboxImplTest.java |   4 +-
 .../org/apache/james/utils/JmapGuiceProbe.java  |   4 +-
 .../event/PropagateLookupRightListenerTest.java |   2 +-
 .../ElasticSearchQuotaSearchExtension.java      |   4 +-
 12 files changed, 146 insertions(+), 157 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/c82c1384/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxManager.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxManager.java
index 1aedc86..be6c107 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxManager.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxManager.java
@@ -23,6 +23,8 @@ import java.util.EnumSet;
 import java.util.List;
 import java.util.Optional;
 
+import org.apache.james.mailbox.events.Group;
+import org.apache.james.mailbox.events.Registration;
 import org.apache.james.mailbox.exception.BadCredentialsException;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MailboxExistsException;
@@ -68,7 +70,7 @@ import org.apache.james.mailbox.model.search.MailboxQuery;
  * </p>
  */
 
-public interface MailboxManager extends RequestAware, MailboxListenerSupport, RightManager, MailboxAnnotationManager {
+public interface MailboxManager extends RequestAware, RightManager, MailboxAnnotationManager {
 
     int MAX_MAILBOX_NAME_LENGTH = 200;
 
@@ -344,4 +346,10 @@ public interface MailboxManager extends RequestAware, MailboxListenerSupport, Ri
     List<MailboxPath> list(MailboxSession session) throws MailboxException;
 
     boolean hasChildren(MailboxPath mailboxPath, MailboxSession session) throws MailboxException;
+
+    Registration register(MailboxListener listener, MailboxId registrationKey);
+
+    Registration register(MailboxListener listener, Group group);
+
+    Registration register(MailboxListener.GroupMailboxListener groupMailboxListener);
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/c82c1384/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressTest.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressTest.java
index 41819a9..ce1f83c 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressTest.java
@@ -22,7 +22,6 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 import java.nio.charset.StandardCharsets;
 import java.util.Collection;
-import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedDeque;
 import java.util.concurrent.CountDownLatch;
@@ -59,15 +58,15 @@ public abstract class MailboxManagerStressTest {
     public void testStressTest() throws InterruptedException, MailboxException {
         ThreadFactory threadFactory = NamedThreadFactory.withClassName(getClass());
 
-        final CountDownLatch latch = new CountDownLatch(APPEND_OPERATIONS);
-        final ExecutorService pool = Executors.newFixedThreadPool(APPEND_OPERATIONS / 20, threadFactory);
-        final Collection<MessageUid> uList = new ConcurrentLinkedDeque<>();
-        final String username = "username";
+        CountDownLatch latch = new CountDownLatch(APPEND_OPERATIONS);
+        ExecutorService pool = Executors.newFixedThreadPool(APPEND_OPERATIONS / 20, threadFactory);
+        Collection<MessageUid> uList = new ConcurrentLinkedDeque<>();
+        String username = "username";
         MailboxSession session = mailboxManager.createSystemSession(username);
         mailboxManager.startProcessingRequest(session);
-        final MailboxPath path = MailboxPath.forUser(username, "INBOX");
-        Optional<MailboxId> mailboxId = mailboxManager.createMailbox(path, session);
-        mailboxManager.addListener(mailboxId.get(), new MailboxListener() {
+        MailboxPath path = MailboxPath.forUser(username, "INBOX");
+        MailboxId mailboxId = mailboxManager.createMailbox(path, session).get();
+        mailboxManager.register(new MailboxListener() {
             @Override
             public ListenerType getType() {
                 return ListenerType.MAILBOX;
@@ -78,7 +77,7 @@ public abstract class MailboxManagerStressTest {
                 MessageUid u = ((Added) event).getUids().iterator().next();
                 uList.add(u);
             }
-        }, session);
+        }, mailboxId);
         mailboxManager.endProcessingRequest(session);
         mailboxManager.logout(session, false);
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/c82c1384/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
index e8dd5a3..0172ac7 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
@@ -382,7 +382,7 @@ public abstract class MailboxManagerTest {
         @Test
         void deleteMailboxShouldFireMailboxDeletionEvent() throws Exception {
             assumeTrue(mailboxManager.hasCapability(MailboxCapabilities.Quota));
-            mailboxManager.addGlobalListener(listener, session);
+            mailboxManager.register(listener);
 
             mailboxManager.deleteMailbox(inbox, session);
 
@@ -400,7 +400,7 @@ public abstract class MailboxManagerTest {
         @Test
         void createMailboxShouldFireMailboxAddedEvent() throws Exception {
             assumeTrue(mailboxManager.hasCapability(MailboxCapabilities.Quota));
-            mailboxManager.addGlobalListener(listener, session);
+            mailboxManager.register(listener);
 
             Optional<MailboxId> newId = mailboxManager.createMailbox(newPath, session);
 
@@ -415,7 +415,7 @@ public abstract class MailboxManagerTest {
         @Test
         void addingMessageShouldFireQuotaUpdateEvent() throws Exception {
             assumeTrue(mailboxManager.hasCapability(MailboxCapabilities.Quota));
-            mailboxManager.addGlobalListener(listener, session);
+            mailboxManager.register(listener);
 
             inboxManager.appendMessage(MessageManager.AppendCommand.builder()
                     .build(message), session);
@@ -438,7 +438,7 @@ public abstract class MailboxManagerTest {
 
         @Test
         void addingMessageShouldFireAddedEvent() throws Exception {
-            mailboxManager.addGlobalListener(listener, session);
+            mailboxManager.register(listener);
             inboxManager.appendMessage(MessageManager.AppendCommand.builder()
                     .build(message), session);
 
@@ -456,7 +456,7 @@ public abstract class MailboxManagerTest {
             inboxManager.appendMessage(MessageManager.AppendCommand.builder().build(message), session);
             inboxManager.setFlags(new Flags(Flags.Flag.DELETED), MessageManager.FlagsUpdateMode.ADD, MessageRange.all(), session);
 
-            mailboxManager.addGlobalListener(listener, session);
+            mailboxManager.register(listener);
             inboxManager.expunge(MessageRange.all(), session);
 
             assertThat(listener.getEvents())
@@ -472,7 +472,7 @@ public abstract class MailboxManagerTest {
         void setFlagsShouldFireFlagsUpdatedEvent() throws Exception {
             inboxManager.appendMessage(MessageManager.AppendCommand.builder().build(message), session);
 
-            mailboxManager.addGlobalListener(listener, session);
+            mailboxManager.register(listener);
             inboxManager.setFlags(new Flags(Flags.Flag.FLAGGED), MessageManager.FlagsUpdateMode.ADD, MessageRange.all(), session);
 
             assertThat(listener.getEvents())
@@ -490,7 +490,7 @@ public abstract class MailboxManagerTest {
             Optional<MailboxId> targetMailboxId = mailboxManager.createMailbox(newPath, session);
             inboxManager.appendMessage(AppendCommand.builder().build(message), session);
 
-            mailboxManager.addGlobalListener(listener, session);
+            mailboxManager.register(listener);
             mailboxManager.moveMessages(MessageRange.all(), inbox, newPath, session);
 
             assertThat(listener.getEvents())
@@ -508,7 +508,7 @@ public abstract class MailboxManagerTest {
             mailboxManager.createMailbox(newPath, session);
             inboxManager.appendMessage(AppendCommand.builder().build(message), session);
 
-            mailboxManager.addGlobalListener(listener, session);
+            mailboxManager.register(listener);
             mailboxManager.moveMessages(MessageRange.all(), inbox, newPath, session);
 
             assertThat(listener.getEvents())
@@ -525,7 +525,7 @@ public abstract class MailboxManagerTest {
             Optional<MailboxId> targetMailboxId = mailboxManager.createMailbox(newPath, session);
             inboxManager.appendMessage(AppendCommand.builder().build(message), session);
 
-            mailboxManager.addGlobalListener(listener, session);
+            mailboxManager.register(listener);
             mailboxManager.copyMessages(MessageRange.all(), inbox, newPath, session);
 
             assertThat(listener.getEvents())
@@ -542,7 +542,7 @@ public abstract class MailboxManagerTest {
             mailboxManager.createMailbox(newPath, session);
             inboxManager.appendMessage(AppendCommand.builder().build(message), session);
 
-            mailboxManager.addGlobalListener(listener, session);
+            mailboxManager.register(listener);
             mailboxManager.copyMessages(MessageRange.all(), inbox, newPath, session);
 
             assertThat(listener.getEvents())

http://git-wip-us.apache.org/repos/asf/james-project/blob/c82c1384/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerTestSystem.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerTestSystem.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerTestSystem.java
index ede1fe2..d09d540 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerTestSystem.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerTestSystem.java
@@ -47,7 +47,7 @@ public class CassandraMessageIdManagerTestSystem {
         ListeningCurrentQuotaUpdater listeningCurrentQuotaUpdater = new ListeningCurrentQuotaUpdater(
             (StoreCurrentQuotaManager) currentQuotaManager,
             mailboxManager.getQuotaComponents().getQuotaRootResolver(), mailboxManager.getDelegationListener(), quotaManager);
-        mailboxManager.addGlobalListener(listeningCurrentQuotaUpdater, mailboxManager.createSystemSession("System"));
+        mailboxManager.register(listeningCurrentQuotaUpdater);
         return new MessageIdManagerTestSystem(CassandraTestSystemFixture.createMessageIdManager(mapperFactory, quotaManager, mailboxManager.getDelegationListener()),
             new CassandraMessageId.Factory(),
             mapperFactory,

http://git-wip-us.apache.org/repos/asf/james-project/blob/c82c1384/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java
index ae50774..4cc91e0 100644
--- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java
+++ b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java
@@ -30,7 +30,6 @@ import org.apache.james.backends.es.EmbeddedElasticSearch;
 import org.apache.james.backends.es.utils.TestingClientProvider;
 import org.apache.james.dnsservice.api.DNSService;
 import org.apache.james.domainlist.memory.MemoryDomainList;
-import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
 import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
 import org.apache.james.mailbox.store.quota.QuotaComponents;
@@ -79,8 +78,7 @@ public class ElasticSearchQuotaSearchTestSystemExtension implements ParameterRes
                     QuotaRatioElasticSearchConstants.QUOTA_RATIO_TYPE),
                 new QuotaRatioToElasticSearchJson());
 
-            resources.getMailboxManager()
-                .addGlobalListener(listener, MailboxSessionUtil.create("ANY"));
+            resources.getMailboxManager().register(listener);
 
             QuotaComponents quotaComponents = resources.getMailboxManager().getQuotaComponents();
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/c82c1384/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
index c097f99..2145f1f 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
@@ -39,6 +39,8 @@ import org.apache.james.mailbox.MailboxPathLocker.LockAwareExecution;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.StandardMailboxMetaDataComparator;
+import org.apache.james.mailbox.events.Group;
+import org.apache.james.mailbox.events.Registration;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MailboxExistsException;
 import org.apache.james.mailbox.exception.MailboxNotFoundException;
@@ -605,11 +607,6 @@ public class StoreMailboxManager implements MailboxManager {
 
     }
 
-    @Override
-    public void addListener(MailboxId mailboxId, MailboxListener listener, MailboxSession session) throws MailboxException {
-        delegatingListener.addListener(mailboxId, listener, session);
-    }
-
     /**
      * End processing of Request for session
      */
@@ -636,22 +633,6 @@ public class StoreMailboxManager implements MailboxManager {
     }
 
     @Override
-    public void addGlobalListener(MailboxListener listener, MailboxSession session) throws MailboxException {
-        delegatingListener.addGlobalListener(listener, session);
-    }
-
-    @Override
-    public void removeListener(MailboxId mailboxId, MailboxListener listener, MailboxSession session) throws MailboxException {
-        delegatingListener.removeListener(mailboxId, listener, session);
-
-    }
-
-    @Override
-    public void removeGlobalListener(MailboxListener listener, MailboxSession session) throws MailboxException {
-        delegatingListener.removeGlobalListener(listener, session);
-    }
-
-    @Override
     public boolean hasRight(MailboxPath mailboxPath, Right right, MailboxSession session) throws MailboxException {
         return storeRightManager.hasRight(mailboxPath, right, session);
     }
@@ -737,4 +718,43 @@ public class StoreMailboxManager implements MailboxManager {
         Mailbox mailbox = mapper.findMailboxByPath(mailboxPath);
         return mapper.hasChildren(mailbox, session.getPathDelimiter());
     }
+
+    @Override
+    public Registration register(MailboxListener listener, MailboxId registrationKey) {
+        MailboxSession session = createSystemSession("admin");
+        try {
+            delegatingListener.addListener(registrationKey, listener, session);
+        } catch (MailboxException e) {
+            throw new RuntimeException(e);
+        }
+        return () -> {
+            try {
+                delegatingListener.removeListener(registrationKey, listener, session);
+            } catch (MailboxException e) {
+                throw new RuntimeException(e);
+            }
+        };
+    }
+
+    @Override
+    public Registration register(MailboxListener listener, Group group) {
+        MailboxSession session = createSystemSession("admin");
+        try {
+            delegatingListener.addGlobalListener(listener, session);
+        } catch (MailboxException e) {
+            throw new RuntimeException(e);
+        }
+        return () -> {
+            try {
+                delegatingListener.removeGlobalListener(listener, session);
+            } catch (MailboxException e) {
+                throw new RuntimeException(e);
+            }
+        };
+    }
+
+    @Override
+    public Registration register(MailboxListener.GroupMailboxListener groupMailboxListener) {
+        return register(groupMailboxListener, groupMailboxListener.getGroup());
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/c82c1384/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
index 7700d28..ce886e5 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
@@ -33,7 +33,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import org.apache.james.imap.api.ImapCommand;
 import org.apache.james.imap.api.ImapConfiguration;
 import org.apache.james.imap.api.ImapSessionState;
-import org.apache.james.imap.api.ImapSessionUtils;
 import org.apache.james.imap.api.display.HumanReadableText;
 import org.apache.james.imap.api.message.response.StatusResponse;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
@@ -46,22 +45,18 @@ import org.apache.james.imap.message.response.ContinuationResponse;
 import org.apache.james.mailbox.Event;
 import org.apache.james.mailbox.MailboxListener;
 import org.apache.james.mailbox.MailboxManager;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.events.Registration;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.util.MDCBuilder;
 import org.apache.james.util.concurrent.NamedThreadFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.ImmutableList;
 
 public class IdleProcessor extends AbstractMailboxProcessor<IdleRequest> implements CapabilityImplementingProcessor {
-    private static final Logger LOGGER = LoggerFactory.getLogger(IdleProcessor.class);
-
     private static final List<String> CAPS = ImmutableList.of(SUPPORTS_IDLE);
     public static final int DEFAULT_SCHEDULED_POOL_CORE_SIZE = 5;
     private static final String DONE = "DONE";
+
     private TimeUnit heartbeatIntervalUnit;
     private long heartbeatInterval;
     private boolean enableIdle;
@@ -86,89 +81,74 @@ public class IdleProcessor extends AbstractMailboxProcessor<IdleRequest> impleme
     }
 
     @Override
-    protected void doProcess(IdleRequest message, final ImapSession session, final String tag, final ImapCommand command, final Responder responder) {
-
-        try {
-          
-            final MailboxManager mailboxManager = getMailboxManager();
-            final MailboxSession mailboxSession = ImapSessionUtils.getMailboxSession(session);
-            final SelectedMailbox sm = session.getSelected();
-            final IdleMailboxListener idleListener;
-            if (sm != null) {
-                idleListener = new IdleMailboxListener(session, responder);
-                mailboxManager.addListener(sm.getMailboxId(), idleListener, mailboxSession);
-            } else {
-                idleListener = null;
-            }
+    protected void doProcess(IdleRequest message, ImapSession session, String tag, ImapCommand command, Responder responder) {
+        MailboxManager mailboxManager = getMailboxManager();
+        SelectedMailbox sm = session.getSelected();
+        Registration registration;
+        if (sm != null) {
+            registration = mailboxManager.register(new IdleMailboxListener(session, responder), sm.getMailboxId());
+        } else {
+            registration = null;
+        }
 
-            final AtomicBoolean idleActive = new AtomicBoolean(true);
-            
-            session.pushLineHandler(new ImapLineHandler() {
-                @Override
-                public void onLine(ImapSession session, byte[] data) {
-                    String line;
-                    if (data.length > 2) {
-                        line = new String(data, 0, data.length - 2);
-                    } else {
-                        line = "";
-                    }
+        final AtomicBoolean idleActive = new AtomicBoolean(true);
 
-                    if (idleListener != null) {
-                        try {
-                            mailboxManager.removeListener(sm.getMailboxId(), idleListener, mailboxSession);
-                        } catch (MailboxException e) {
-                                LOGGER.error("Unable to remove idle listener for mailbox {}", sm.getMailboxId(), e);
-                        }
-                    }
-                    session.popLineHandler();
-                    if (!DONE.equals(line.toUpperCase(Locale.US))) {
-                        StatusResponse response = getStatusResponseFactory().taggedBad(tag, command, HumanReadableText.INVALID_COMMAND);
-                        responder.respond(response);
-                    } else {
-                        okComplete(command, tag, responder);
+        session.pushLineHandler(new ImapLineHandler() {
+            @Override
+            public void onLine(ImapSession session, byte[] data) {
+                String line;
+                if (data.length > 2) {
+                    line = new String(data, 0, data.length - 2);
+                } else {
+                    line = "";
+                }
 
-                    }
-                    idleActive.set(false);
+                if (registration != null) {
+                    registration.unregister();
                 }
-            });
-
-            // Check if we should send heartbeats
-            if (enableIdle) {
-                heartbeatExecutor.schedule(new Runnable() {
-
-                    @Override
-                    public void run() {
-                        // check if we need to cancel the Runnable
-                        // See IMAP-275
-                        if (session.getState() != ImapSessionState.LOGOUT && idleActive.get()) {
-                            // Send a heartbeat to the client to make sure we
-                            // reset the idle timeout. This is kind of the same
-                            // workaround as dovecot use.
-                            //
-                            // This is mostly needed because of the broken
-                            // outlook client, but can't harm for other clients
-                            // too.
-                            // See IMAP-272
-                            StatusResponse response = getStatusResponseFactory().untaggedOk(HumanReadableText.HEARTBEAT);
-                            responder.respond(response);
-                            
-                            // schedule the heartbeat again for the next interval
-                            heartbeatExecutor.schedule(this, heartbeatInterval, heartbeatIntervalUnit);
-                        }
-                    }
-                }, heartbeatInterval, heartbeatIntervalUnit);
+                session.popLineHandler();
+                if (!DONE.equals(line.toUpperCase(Locale.US))) {
+                    StatusResponse response = getStatusResponseFactory().taggedBad(tag, command, HumanReadableText.INVALID_COMMAND);
+                    responder.respond(response);
+                } else {
+                    okComplete(command, tag, responder);
+
+                }
+                idleActive.set(false);
             }
-            
-            // Write the response after the listener was add
-            // IMAP-341
-            responder.respond(new ContinuationResponse(HumanReadableText.IDLING));
-            unsolicitedResponses(session, responder, false);
+        });
+
+        // Check if we should send heartbeats
+        if (enableIdle) {
+            heartbeatExecutor.schedule(new Runnable() {
 
+                @Override
+                public void run() {
+                    // check if we need to cancel the Runnable
+                    // See IMAP-275
+                    if (session.getState() != ImapSessionState.LOGOUT && idleActive.get()) {
+                        // Send a heartbeat to the client to make sure we
+                        // reset the idle timeout. This is kind of the same
+                        // workaround as dovecot use.
+                        //
+                        // This is mostly needed because of the broken
+                        // outlook client, but can't harm for other clients
+                        // too.
+                        // See IMAP-272
+                        StatusResponse response = getStatusResponseFactory().untaggedOk(HumanReadableText.HEARTBEAT);
+                        responder.respond(response);
 
-        } catch (MailboxException e) {
-            LOGGER.error("Enable idle for {} failed", session.getSelected().getMailboxId(), e);
-            no(command, tag, responder, HumanReadableText.GENERIC_FAILURE_DURING_PROCESSING);
+                        // schedule the heartbeat again for the next interval
+                        heartbeatExecutor.schedule(this, heartbeatInterval, heartbeatIntervalUnit);
+                    }
+                }
+            }, heartbeatInterval, heartbeatIntervalUnit);
         }
+
+        // Write the response after the listener was add
+        // IMAP-341
+        responder.respond(new ContinuationResponse(HumanReadableText.IDLING));
+        unsolicitedResponses(session, responder, false);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/c82c1384/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java
index 67da6dd..7adacec 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java
@@ -40,13 +40,12 @@ import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.events.Registration;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.model.UpdatedFlags;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.ImmutableList;
 
@@ -54,31 +53,24 @@ import com.google.common.collect.ImmutableList;
  * Default implementation of {@link SelectedMailbox}
  */
 public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener {
-    private static final Logger LOGGER = LoggerFactory.getLogger(SelectedMailboxImpl.class);
-
-    private final Set<MessageUid> recentUids = new TreeSet<>();
-
-    private boolean recentUidRemoved = false;
-
+    private final Registration registration;
     private final MailboxManager mailboxManager;
-
     private final MailboxId mailboxId;
-
     private final ImapSession session;
-
     private final MailboxSession.SessionId sessionId;
+    private final MailboxSession mailboxSession;
+    private final UidMsnConverter uidMsnConverter;
+    private final Set<MessageUid> recentUids = new TreeSet<>();
     private final Set<MessageUid> flagUpdateUids = new TreeSet<>();
     private final Flags.Flag uninterestingFlag = Flags.Flag.RECENT;
     private final Set<MessageUid> expungedUids = new TreeSet<>();
-    private final UidMsnConverter uidMsnConverter;
 
+    private boolean recentUidRemoved = false;
     private boolean isDeletedByOtherSession = false;
     private boolean sizeChanged = false;
     private boolean silentFlagChanges = false;
     private final Flags applicableFlags;
-
     private boolean applicableFlagsChanged;
-    private final MailboxSession mailboxSession;
 
     public SelectedMailboxImpl(MailboxManager mailboxManager, ImapSession session, MailboxPath path) throws MailboxException {
         this.session = session;
@@ -95,7 +87,7 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener {
         MessageManager messageManager = mailboxManager.getMailbox(path, mailboxSession);
         mailboxId = messageManager.getId();
 
-        mailboxManager.addListener(mailboxId, this, mailboxSession);
+        registration = mailboxManager.register(this, mailboxId);
 
         applicableFlags = messageManager.getApplicableFlags(mailboxSession);
         uidMsnConverter.addAll(ImmutableList.copyOf(
@@ -119,13 +111,7 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener {
 
     @Override
     public synchronized void deselect() {
-        MailboxSession mailboxSession = ImapSessionUtils.getMailboxSession(session);
-
-        try {
-            mailboxManager.removeListener(mailboxId, this, mailboxSession);
-        } catch (MailboxException e) {
-            LOGGER.error("Unable to remove listener {} from mailbox while closing it", this, e);
-        }
+        registration.unregister();
         
         uidMsnConverter.clear();
         flagUpdateUids.clear();

http://git-wip-us.apache.org/repos/asf/james-project/blob/c82c1384/protocols/imap/src/test/java/org/apache/james/imap/processor/base/SelectedMailboxImplTest.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/processor/base/SelectedMailboxImplTest.java b/protocols/imap/src/test/java/org/apache/james/imap/processor/base/SelectedMailboxImplTest.java
index 0b4a0a8..073528f 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/processor/base/SelectedMailboxImplTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/processor/base/SelectedMailboxImplTest.java
@@ -112,7 +112,7 @@ public class SelectedMailboxImplTest {
         final AtomicInteger successCount = new AtomicInteger(0);
         doAnswer(generateEmitEventAnswer(successCount))
             .when(mailboxManager)
-            .addListener(eq(mailboxId), any(MailboxListener.class), any(MailboxSession.class));
+            .register(any(MailboxListener.class), eq(mailboxId));
 
         SelectedMailboxImpl selectedMailbox = new SelectedMailboxImpl(
             mailboxManager,
@@ -127,7 +127,7 @@ public class SelectedMailboxImplTest {
         final AtomicInteger successCount = new AtomicInteger(0);
         doAnswer(generateEmitEventAnswer(successCount))
             .when(mailboxManager)
-            .addListener(eq(mailboxId), any(MailboxListener.class), any(MailboxSession.class));
+            .register(any(MailboxListener.class), eq(mailboxId));
 
         new SelectedMailboxImpl(
             mailboxManager,

http://git-wip-us.apache.org/repos/asf/james-project/blob/c82c1384/server/container/guice/protocols/jmap/src/main/java/org/apache/james/utils/JmapGuiceProbe.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/utils/JmapGuiceProbe.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/utils/JmapGuiceProbe.java
index 854d590..4c82971 100644
--- a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/utils/JmapGuiceProbe.java
+++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/utils/JmapGuiceProbe.java
@@ -55,8 +55,8 @@ public class JmapGuiceProbe implements GuiceProbe {
         return jmapServer.getPort();
     }
 
-    public void addMailboxListener(MailboxListener listener) throws MailboxException {
-        mailboxManager.addGlobalListener(listener, mailboxManager.createSystemSession("jmap"));
+    public void addMailboxListener(MailboxListener.GroupMailboxListener listener) {
+        mailboxManager.register(listener);
     }
 
     public void modifyVacation(AccountId accountId, VacationPatch vacationPatch) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/c82c1384/server/protocols/jmap/src/test/java/org/apache/james/jmap/event/PropagateLookupRightListenerTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/event/PropagateLookupRightListenerTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/event/PropagateLookupRightListenerTest.java
index e3ddb29..7ebeaa8 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/event/PropagateLookupRightListenerTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/event/PropagateLookupRightListenerTest.java
@@ -81,7 +81,7 @@ public class PropagateLookupRightListenerTest {
         mailboxMapper = storeMailboxManager.getMapperFactory();
 
         testee = new PropagateLookupRightListener(storeRightManager, storeMailboxManager);
-        storeMailboxManager.addGlobalListener(testee, mailboxSession);
+        storeMailboxManager.register(testee);
 
         parentMailboxId = storeMailboxManager.createMailbox(PARENT_MAILBOX, mailboxSession).get();
         parentMailboxId1 = storeMailboxManager.createMailbox(PARENT_MAILBOX1, mailboxSession).get();

http://git-wip-us.apache.org/repos/asf/james-project/blob/c82c1384/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/ElasticSearchQuotaSearchExtension.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/ElasticSearchQuotaSearchExtension.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/ElasticSearchQuotaSearchExtension.java
index 4db355b..59677e8 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/ElasticSearchQuotaSearchExtension.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/ElasticSearchQuotaSearchExtension.java
@@ -30,7 +30,6 @@ import org.apache.james.backends.es.EmbeddedElasticSearch;
 import org.apache.james.backends.es.utils.TestingClientProvider;
 import org.apache.james.dnsservice.api.DNSService;
 import org.apache.james.domainlist.memory.MemoryDomainList;
-import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
 import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
 import org.apache.james.mailbox.store.quota.QuotaComponents;
@@ -82,8 +81,7 @@ public class ElasticSearchQuotaSearchExtension implements ParameterResolver, Bef
                     QuotaRatioElasticSearchConstants.QUOTA_RATIO_TYPE),
                 new QuotaRatioToElasticSearchJson());
 
-            resources.getMailboxManager()
-                .addGlobalListener(listener, MailboxSessionUtil.create("ANY"));
+            resources.getMailboxManager().register(listener);
 
             QuotaComponents quotaComponents = resources.getMailboxManager().getQuotaComponents();
 


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