JAMES-2368 Introduce GlobalMailboxListeners

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

Branch: refs/heads/master
Commit: a1cdcf506962dcc2096f6c899c15ae18b1342018
Parents: dcac68a
Author: Antoine Duprat <adup...@linagora.com>
Authored: Wed Apr 25 11:59:20 2018 +0200
Committer: benwa <btell...@linagora.com>
Committed: Fri May 4 13:38:02 2018 +0700

----------------------------------------------------------------------
 server/container/guice/mailbox/pom.xml          |  10 ++
 .../modules/mailbox/GlobalMailboxListeners.java |  77 ++++++++++++
 .../modules/mailbox/NoopMailboxListener.java    |  41 +++++++
 .../mailbox/GlobalMailboxListenersTest.java     | 121 +++++++++++++++++++
 4 files changed, 249 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/a1cdcf50/server/container/guice/mailbox/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/mailbox/pom.xml 
b/server/container/guice/mailbox/pom.xml
index e64a86a..1e8415e 100644
--- a/server/container/guice/mailbox/pom.xml
+++ b/server/container/guice/mailbox/pom.xml
@@ -52,6 +52,16 @@
             <groupId>com.google.inject.extensions</groupId>
             <artifactId>guice-multibindings</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>

http://git-wip-us.apache.org/repos/asf/james-project/blob/a1cdcf50/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/GlobalMailboxListeners.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/GlobalMailboxListeners.java
 
b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/GlobalMailboxListeners.java
new file mode 100644
index 0000000..4028383
--- /dev/null
+++ 
b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/GlobalMailboxListeners.java
@@ -0,0 +1,77 @@
+/****************************************************************
+ * 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.modules.mailbox;
+
+import java.util.List;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.james.lifecycle.api.Configurable;
+import org.apache.james.mailbox.MailboxListener;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.store.event.MailboxListenerRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.base.Throwables;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+
+public class GlobalMailboxListeners implements Configurable {
+
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(GlobalMailboxListeners.class);
+
+    private final Injector injector;
+    private final MailboxListenerRegistry registry;
+
+    @Inject
+    public GlobalMailboxListeners(Injector injector, MailboxListenerRegistry 
registry) {
+        this.injector = injector;
+        this.registry = registry;
+    }
+
+    @Override
+    public void configure(HierarchicalConfiguration configuration) throws 
ConfigurationException {
+        LOGGER.info("Loading mailbox listeners");
+        List<HierarchicalConfiguration> listenersConfiguration = 
configuration.configurationsAt("listener");
+        listenersConfiguration.stream()
+            .forEach(listenerConfiguration -> 
configureListener(listenerConfiguration));
+    }
+
+    @VisibleForTesting void configureListener(HierarchicalConfiguration 
configuration) {
+        String listenerClass = configuration.getString("class");
+        Preconditions.checkState(!Strings.isNullOrEmpty(listenerClass), "class 
name is mandatory");
+        try {
+            LOGGER.info("Loading mailbox listener {}", listenerClass);
+            
registry.addGlobalListener(injector.getInstance(loadMailboxListener(listenerClass)));
+        } catch (ClassNotFoundException | InstantiationException | 
IllegalAccessException | MailboxException e) {
+            LOGGER.error("Error while loading global listener {}", 
listenerClass, e);
+            Throwables.propagate(e);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private Class<MailboxListener> loadMailboxListener(String listenerClass) 
throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+        Class<?> clazz = 
ClassLoader.getSystemClassLoader().loadClass(listenerClass);
+        return (Class<MailboxListener>) clazz;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/a1cdcf50/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/NoopMailboxListener.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/NoopMailboxListener.java
 
b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/NoopMailboxListener.java
new file mode 100644
index 0000000..ee08297
--- /dev/null
+++ 
b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/NoopMailboxListener.java
@@ -0,0 +1,41 @@
+/****************************************************************
+ * 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.modules.mailbox;
+
+import org.apache.james.mailbox.Event;
+import org.apache.james.mailbox.MailboxListener;
+import org.apache.james.mailbox.MailboxListener.ExecutionMode;
+import org.apache.james.mailbox.MailboxListener.ListenerType;
+
+public class NoopMailboxListener implements MailboxListener {
+
+    @Override
+    public ListenerType getType() {
+        return ListenerType.ONCE;
+    }
+
+    @Override
+    public ExecutionMode getExecutionMode() {
+        return ExecutionMode.SYNCHRONOUS;
+    }
+
+    @Override
+    public void event(Event event) {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/a1cdcf50/server/container/guice/mailbox/src/test/java/org/apache/james/modules/mailbox/GlobalMailboxListenersTest.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/mailbox/src/test/java/org/apache/james/modules/mailbox/GlobalMailboxListenersTest.java
 
b/server/container/guice/mailbox/src/test/java/org/apache/james/modules/mailbox/GlobalMailboxListenersTest.java
new file mode 100644
index 0000000..4076aac
--- /dev/null
+++ 
b/server/container/guice/mailbox/src/test/java/org/apache/james/modules/mailbox/GlobalMailboxListenersTest.java
@@ -0,0 +1,121 @@
+/****************************************************************
+ * 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.modules.mailbox;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.DefaultConfigurationBuilder;
+import org.apache.james.mailbox.store.event.MailboxListenerRegistry;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.inject.Guice;
+
+public class GlobalMailboxListenersTest {
+
+    private MailboxListenerRegistry registry;
+    private GlobalMailboxListeners testee;
+
+    @Before
+    public void setup() {
+        registry = new MailboxListenerRegistry();
+        testee = new GlobalMailboxListeners(Guice.createInjector(), registry);
+    }
+
+    @Test
+    public void configureListenerShouldThrowWhenClassIsNotInTheConfiguration() 
{
+        DefaultConfigurationBuilder configuration = new 
DefaultConfigurationBuilder();
+
+        assertThatThrownBy(() -> testee.configureListener(configuration))
+            .isInstanceOf(IllegalStateException.class);
+    }
+
+    @Test
+    public void configureListenerShouldThrowWhenClassIsEmpty() {
+        DefaultConfigurationBuilder configuration = new 
DefaultConfigurationBuilder();
+        configuration.addProperty("class", "");
+
+        assertThatThrownBy(() -> testee.configureListener(configuration))
+            .isInstanceOf(IllegalStateException.class);
+    }
+
+    @Test
+    public void configureListenerShouldThrowWhenClassCantBeLoaded() {
+        DefaultConfigurationBuilder configuration = new 
DefaultConfigurationBuilder();
+        configuration.addProperty("class", "MyUnknownClass");
+
+        assertThatThrownBy(() -> testee.configureListener(configuration))
+            .isInstanceOf(RuntimeException.class);
+    }
+
+    @Test
+    public void 
configureListenerShouldThrowWhenClassCantBeCastToMailboxListener() {
+        DefaultConfigurationBuilder configuration = new 
DefaultConfigurationBuilder();
+        configuration.addProperty("class", "java.lang.String");
+
+        assertThatThrownBy(() -> testee.configureListener(configuration))
+            .isInstanceOf(RuntimeException.class);
+    }
+
+    @Test
+    public void configureListenerShouldThrowWhenNotFullClassName() {
+        DefaultConfigurationBuilder configuration = new 
DefaultConfigurationBuilder();
+        configuration.addProperty("class", "NoopMailboxListener");
+
+        assertThatThrownBy(() -> testee.configureListener(configuration))
+            .isInstanceOf(RuntimeException.class);
+    }
+
+    @Test
+    public void 
configureListenerShouldAddMailboxListenerWhenConfigurationIsGood() {
+        DefaultConfigurationBuilder configuration = new 
DefaultConfigurationBuilder();
+        configuration.addProperty("class", 
"org.apache.james.modules.mailbox.NoopMailboxListener");
+
+        testee.configureListener(configuration);
+
+        assertThat(registry.getGlobalListeners()).hasSize(1);
+    }
+
+    @Test
+    public void configureShouldAddMailboxListenersWhenConfigurationIsGood() 
throws ConfigurationException {
+        DefaultConfigurationBuilder configuration = 
toConfigutation("<listeners>" +
+                    "<listener>" +
+                        
"<class>org.apache.james.modules.mailbox.NoopMailboxListener</class>" +
+                    "</listener>" +
+                    "<listener>" +
+                        
"<class>org.apache.james.modules.mailbox.NoopMailboxListener</class>" +
+                    "</listener>" +
+                "</listeners>");
+
+        testee.configure(configuration);
+
+        assertThat(registry.getGlobalListeners()).hasSize(2);
+    }
+
+    private DefaultConfigurationBuilder toConfigutation(String 
configurationString) throws ConfigurationException {
+        DefaultConfigurationBuilder configuration = new 
DefaultConfigurationBuilder();
+        configuration.load(new 
ByteArrayInputStream(configurationString.getBytes(StandardCharsets.UTF_8)));
+        return configuration;
+    }
+}


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

Reply via email to