JAMES-2004 All XML configuration files should have default values

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

Branch: refs/heads/master
Commit: 3aea08173f369ad9d0e4ce43551827c9a63c6c57
Parents: 67e769c
Author: benwa <btell...@linagora.com>
Authored: Tue Apr 18 08:14:09 2017 +0700
Committer: benwa <btell...@linagora.com>
Committed: Fri Apr 21 08:27:41 2017 +0700

----------------------------------------------------------------------
 server/container/guice/guice-common/pom.xml     |  10 +-
 ...ltProcessorsConfigurationProviderModule.java |  43 ++++++
 .../james/utils/FileConfigurationProvider.java  |  40 +++--
 .../utils/InMemoryMailRepositoryStore.java      |  17 ++-
 .../james/AbstractJmapJamesServerTest.java      | 145 -------------------
 .../utils/FileConfigurationProviderTest.java    |   6 +-
 .../utils/InMemoryMailRepositoryStoreTest.java  |  18 ++-
 .../org/apache/james/JPAJamesServerMain.java    |  22 +--
 .../main/resources/defaultMailetContainer.xml   |  87 +++++++++++
 .../org/apache/james/JPAJamesServerMain.java    |  12 +-
 .../main/resources/defaultMailetContainer.xml   |  81 +++++++++++
 .../server/CamelMailetContainerModule.java      |  77 ++++++++--
 .../src/test/resources/imapserver.xml           |  54 -------
 server/container/guice/protocols/jmap/pom.xml   |   9 ++
 .../java/org/apache/james/jmap/JMAPModule.java  |  15 ++
 .../resources/defaultJmapMailetContainer.xml    |  97 +++++++++++++
 .../james/AbstractJmapJamesServerTest.java      | 145 +++++++++++++++++++
 .../user/ldap/ReadOnlyUsersLDAPRepository.java  |  14 ++
 18 files changed, 639 insertions(+), 253 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/guice-common/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/pom.xml 
b/server/container/guice/guice-common/pom.xml
index 4f63bfa..c0ee50b 100644
--- a/server/container/guice/guice-common/pom.xml
+++ b/server/container/guice/guice-common/pom.xml
@@ -192,11 +192,6 @@
                 </dependency>
                 <dependency>
                     <groupId>${project.groupId}</groupId>
-                    <artifactId>james-server-guice-jmap</artifactId>
-                    <scope>test</scope>
-                </dependency>
-                <dependency>
-                    <groupId>${project.groupId}</groupId>
                     <artifactId>james-server-guice-lmtp</artifactId>
                     <scope>test</scope>
                 </dependency>
@@ -301,6 +296,11 @@
                     <groupId>org.slf4j</groupId>
                     <artifactId>slf4j-api</artifactId>
                 </dependency>
+                <dependency>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-simple</artifactId>
+                    <scope>test</scope>
+                </dependency>
             </dependencies>
         </profile>
         <profile>

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DefaultProcessorsConfigurationProviderModule.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DefaultProcessorsConfigurationProviderModule.java
 
b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DefaultProcessorsConfigurationProviderModule.java
new file mode 100644
index 0000000..a3e27bf
--- /dev/null
+++ 
b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DefaultProcessorsConfigurationProviderModule.java
@@ -0,0 +1,43 @@
+/****************************************************************
+ * 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.server;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.james.utils.FileConfigurationProvider;
+
+import com.google.common.base.Throwables;
+import com.google.inject.AbstractModule;
+
+public class DefaultProcessorsConfigurationProviderModule extends 
AbstractModule {
+
+    @Override
+    protected void configure() {
+        
bind(CamelMailetContainerModule.DefaultProcessorsConfigurationSupplier.class)
+            .toInstance(
+                () -> {
+                    try {
+                        return 
FileConfigurationProvider.getConfig(ClassLoader.getSystemResourceAsStream("defaultMailetContainer.xml"));
+                    } catch (ConfigurationException e) {
+                        throw Throwables.propagate(e);
+                    }
+                }
+            );
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/guice-common/src/main/java/org/apache/james/utils/FileConfigurationProvider.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/FileConfigurationProvider.java
 
b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/FileConfigurationProvider.java
index 6fa9090..c87a628 100644
--- 
a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/FileConfigurationProvider.java
+++ 
b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/FileConfigurationProvider.java
@@ -22,6 +22,7 @@ package org.apache.james.utils;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.List;
+import java.util.Optional;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -31,6 +32,8 @@ import 
org.apache.commons.configuration.HierarchicalConfiguration;
 import org.apache.commons.configuration.XMLConfiguration;
 import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.modules.CommonServicesModule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Preconditions;
 import com.google.common.base.Splitter;
@@ -39,7 +42,17 @@ import com.google.common.collect.Iterables;
 
 public class FileConfigurationProvider implements ConfigurationProvider {
 
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(FileConfigurationProvider.class);
     private static final String CONFIGURATION_FILE_SUFFIX = ".xml";
+    public static final HierarchicalConfiguration EMTY_CONFIGURATION = new 
HierarchicalConfiguration();
+
+    public static XMLConfiguration getConfig(InputStream configStream) throws 
ConfigurationException {
+        XMLConfiguration config = new XMLConfiguration();
+        config.setDelimiterParsingDisabled(true);
+        config.setAttributeSplittingDisabled(true);
+        config.load(configStream);
+        return config;
+    }
     
     private final FileSystem fileSystem;
     private final String configurationPrefix;
@@ -55,27 +68,30 @@ public class FileConfigurationProvider implements 
ConfigurationProvider {
         Preconditions.checkNotNull(component);
         List<String> configPathParts = Splitter.on(".").splitToList(component);
         Preconditions.checkArgument(!configPathParts.isEmpty());
-        HierarchicalConfiguration config = 
getConfig(retrieveConfigInputStream(configPathParts.get(0)));
+
+        Optional<InputStream> inputStream = 
retrieveConfigInputStream(configPathParts.get(0));
+        if (inputStream.isPresent()) {
+            return selectConfigurationPart(configPathParts,
+                getConfig(inputStream.get()));
+        }
+        return EMTY_CONFIGURATION;
+    }
+
+    private HierarchicalConfiguration selectConfigurationPart(List<String> 
configPathParts, HierarchicalConfiguration config) {
         return selectHierarchicalConfigPart(config, 
Iterables.skip(configPathParts, 1));
     }
 
-    private InputStream retrieveConfigInputStream(String 
configurationFileWithoutExtension) throws ConfigurationException {
+    private Optional<InputStream> retrieveConfigInputStream(String 
configurationFileWithoutExtension) throws ConfigurationException {
         
Preconditions.checkArgument(!Strings.isNullOrEmpty(configurationFileWithoutExtension),
 "The configuration file name should not be empty or null");
         try {
-            return fileSystem.getResource(configurationPrefix + 
configurationFileWithoutExtension + CONFIGURATION_FILE_SUFFIX);
+            return Optional.of(
+                fileSystem.getResource(configurationPrefix + 
configurationFileWithoutExtension + CONFIGURATION_FILE_SUFFIX));
         } catch (IOException e) {
-            throw new ConfigurationException("Unable to locate configuration 
file " + configurationFileWithoutExtension + CONFIGURATION_FILE_SUFFIX, e);
+            LOGGER.warn("Unable to locate configuration file " + 
configurationFileWithoutExtension + CONFIGURATION_FILE_SUFFIX + ", assuming 
empty configuration");
+            return Optional.empty();
         }
     }
 
-    private XMLConfiguration getConfig(InputStream configStream) throws 
ConfigurationException {
-        XMLConfiguration config = new XMLConfiguration();
-        config.setDelimiterParsingDisabled(true);
-        config.setAttributeSplittingDisabled(true);
-        config.load(configStream);
-        return config;
-    }
-
     private HierarchicalConfiguration 
selectHierarchicalConfigPart(HierarchicalConfiguration config, Iterable<String> 
configsPathParts) {
         HierarchicalConfiguration currentConfig = config;
         for (String nextPathPart : configsPathParts) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/guice-common/src/main/java/org/apache/james/utils/InMemoryMailRepositoryStore.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/InMemoryMailRepositoryStore.java
 
b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/InMemoryMailRepositoryStore.java
index 85b9dad..1c11f3b 100644
--- 
a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/InMemoryMailRepositoryStore.java
+++ 
b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/InMemoryMailRepositoryStore.java
@@ -25,7 +25,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
-import java.util.stream.Collectors;
 
 import org.apache.commons.configuration.CombinedConfiguration;
 import org.apache.commons.configuration.ConfigurationException;
@@ -39,6 +38,7 @@ import org.apache.james.repository.api.Initializable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.ImmutableList;
 import com.google.inject.Inject;
 
 public class InMemoryMailRepositoryStore implements MailRepositoryStore, 
Configurable {
@@ -61,9 +61,7 @@ public class InMemoryMailRepositoryStore implements 
MailRepositoryStore, Configu
 
     @Override
     public List<String> getUrls() {
-        return destinationToRepositoryAssociations.keySet()
-            .stream()
-            .collect(Collectors.toList());
+        return 
ImmutableList.copyOf(destinationToRepositoryAssociations.keySet());
     }
 
     @Override
@@ -73,12 +71,21 @@ public class InMemoryMailRepositoryStore implements 
MailRepositoryStore, Configu
 
     public void init() throws Exception {
         LOGGER.info("JamesMailStore init... " + this);
-        List<HierarchicalConfiguration> registeredClasses = 
configuration.configurationsAt("mailrepositories.mailrepository");
+        List<HierarchicalConfiguration> registeredClasses = 
retrieveRegisteredClassConfiguration();
         for (HierarchicalConfiguration registeredClass : registeredClasses) {
             readConfigurationEntry(registeredClass);
         }
     }
 
+    private List<HierarchicalConfiguration> 
retrieveRegisteredClassConfiguration() {
+        try {
+            return 
configuration.configurationsAt("mailrepositories.mailrepository");
+        } catch (Exception e) {
+            LOGGER.warn("Could not process configuration. Skipping Mail 
Repository initialization.", e);
+            return ImmutableList.of();
+        }
+    }
+
     @Override
     public MailRepository select(String destination) throws 
MailRepositoryStoreException {
         MailRepository mailRepository = 
destinationToRepositoryAssociations.get(destination);

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/guice-common/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/guice-common/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
 
b/server/container/guice/guice-common/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
deleted file mode 100644
index 051fc46..0000000
--- 
a/server/container/guice/guice-common/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/****************************************************************
- * 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;
-
-import static com.jayway.restassured.RestAssured.given;
-import static com.jayway.restassured.config.EncoderConfig.encoderConfig;
-import static com.jayway.restassured.config.RestAssuredConfig.newConfig;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.nio.charset.Charset;
-
-import org.apache.james.utils.DataProbeImpl;
-import org.apache.james.utils.JmapGuiceProbe;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.base.Charsets;
-import com.jayway.restassured.RestAssured;
-import com.jayway.restassured.builder.RequestSpecBuilder;
-import com.jayway.restassured.http.ContentType;
-
-public abstract class AbstractJmapJamesServerTest {
-
-    private static final int IMAP_PORT_SSL = 1993;
-    private static final int POP3_PORT = 1110;
-    private static final int SMTP_PORT = 1025;
-    private static final int LMTP_PORT = 1024;
-
-    protected static final String JAMES_SERVER_HOST = "127.0.0.1";
-    protected static final int IMAP_PORT = 1143; // You need to be root 
(superuser) to bind to ports under 1024.
-
-    private GuiceJamesServer server;
-    private SocketChannel socketChannel;
-
-    @Before
-    public void setup() throws Exception {
-        server = createJamesServer();
-        socketChannel = SocketChannel.open();
-        server.start();
-
-        RestAssured.requestSpecification = new RequestSpecBuilder()
-                       .setContentType(ContentType.JSON)
-                       .setAccept(ContentType.JSON)
-                       
.setConfig(newConfig().encoderConfig(encoderConfig().defaultContentCharset(Charsets.UTF_8)))
-                       
.setPort(server.getProbe(JmapGuiceProbe.class).getJmapPort())
-                       .build();
-    }
-
-    protected abstract GuiceJamesServer createJamesServer();
-
-    protected abstract void clean();
-
-    @After
-    public void tearDown() throws Exception {
-        if (server != null) {
-            server.stop();
-        }
-        clean();
-    }
-
-    @Test
-    public void hostnameShouldBeUsedAsDefaultDomain() throws Exception {
-        String expectedDefaultDomain = 
InetAddress.getLocalHost().getHostName();
-
-        
assertThat(server.getProbe(DataProbeImpl.class).getDefaultDomain()).isEqualTo(expectedDefaultDomain);
-    }
-
-    @Test
-    public void hostnameShouldBeRetrievedWhenRestarting() throws Exception {
-        server.stop();
-        server.start();
-        String expectedDefaultDomain = 
InetAddress.getLocalHost().getHostName();
-
-        
assertThat(server.getProbe(DataProbeImpl.class).getDefaultDomain()).isEqualTo(expectedDefaultDomain);
-    }
-
-    @Test
-    public void connectIMAPServerShouldSendShabangOnConnect() throws Exception 
{
-        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, 
IMAP_PORT));
-        assertThat(getServerConnectionResponse(socketChannel)).startsWith("* 
OK JAMES IMAP4rev1 Server");
-    }
-
-    @Test
-    public void 
connectOnSecondaryIMAPServerIMAPServerShouldSendShabangOnConnect() throws 
Exception {
-        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, 
IMAP_PORT_SSL));
-        assertThat(getServerConnectionResponse(socketChannel)).startsWith("* 
OK JAMES IMAP4rev1 Server");
-    }
-
-    @Test
-    public void connectPOP3ServerShouldSendShabangOnConnect() throws Exception 
{
-        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, 
POP3_PORT));
-        assertThat(getServerConnectionResponse(socketChannel)).contains("POP3 
server (JAMES POP3 Server ) ready");
-    }
-
-    @Test
-    public void connectSMTPServerShouldSendShabangOnConnect() throws Exception 
{
-        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, 
SMTP_PORT));
-        assertThat(getServerConnectionResponse(socketChannel)).startsWith("220 
JAMES Linagora's SMTP awesome Server");
-    }
-
-    @Test
-    public void connectLMTPServerShouldSendShabangOnConnect() throws Exception 
{
-        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, 
LMTP_PORT));
-        assertThat(getServerConnectionResponse(socketChannel)).contains("LMTP 
Server (JAMES Protocols Server) ready");
-    }
-
-    @Test
-    public void connectJMAPServerShouldRespondBadRequest() throws Exception {
-        given()
-            .body("{\"badAttributeName\": \"value\"}")
-        .when()
-            .post("/authentication")
-        .then()
-            .statusCode(400);
-    }
-
-    private String getServerConnectionResponse(SocketChannel socketChannel) 
throws IOException {
-        ByteBuffer byteBuffer = ByteBuffer.allocate(1000);
-        socketChannel.read(byteBuffer);
-        byte[] bytes = byteBuffer.array();
-        return new String(bytes, Charset.forName("UTF-8"));
-    }
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FileConfigurationProviderTest.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FileConfigurationProviderTest.java
 
b/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FileConfigurationProviderTest.java
index 0eeb88f..04562f2 100644
--- 
a/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FileConfigurationProviderTest.java
+++ 
b/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FileConfigurationProviderTest.java
@@ -105,9 +105,9 @@ public class FileConfigurationProviderTest {
         
assertThat(hierarchicalConfiguration.getProperty(CONFIG_KEY_2)).isEqualTo(VALUE_2);
     }
 
-    @Test(expected = ConfigurationException.class)
-    public void getConfigurationShouldThrowOnNonExistingXMLFile() throws 
Exception {
-        
assertThat(configurationProvider.getConfiguration(FAKE_CONFIG_KEY)).isNotNull();
+    @Test
+    public void getConfigurationShouldReturnDefaultOnNonExistingXMLFile() 
throws Exception {
+        
assertThat(configurationProvider.getConfiguration(FAKE_CONFIG_KEY)).isEqualTo(FileConfigurationProvider.EMTY_CONFIGURATION);
     }
 
     @Test(expected = IllegalArgumentException.class)

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/guice-common/src/test/java/org/apache/james/utils/InMemoryMailRepositoryStoreTest.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/guice-common/src/test/java/org/apache/james/utils/InMemoryMailRepositoryStoreTest.java
 
b/server/container/guice/guice-common/src/test/java/org/apache/james/utils/InMemoryMailRepositoryStoreTest.java
index d8582b3..9964eae 100644
--- 
a/server/container/guice/guice-common/src/test/java/org/apache/james/utils/InMemoryMailRepositoryStoreTest.java
+++ 
b/server/container/guice/guice-common/src/test/java/org/apache/james/utils/InMemoryMailRepositoryStoreTest.java
@@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.fail;
 
 import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.HierarchicalConfiguration;
 import org.apache.james.core.JamesServerResourceLoader;
 import org.apache.james.core.filesystem.FileSystemImpl;
 import org.apache.james.filesystem.api.FileSystem;
@@ -45,7 +46,8 @@ public class InMemoryMailRepositoryStoreTest {
         repositoryStore = new InMemoryMailRepositoryStore(Sets.newHashSet(
                 new MailStoreRepositoryModule.FileMailRepositoryProvider(
                         fileSystem)));
-        repositoryStore.configure(new FileConfigurationProvider(fileSystem, 
FileSystem.CLASSPATH_PROTOCOL).getConfiguration("mailrepositorystore"));
+        repositoryStore.configure(new FileConfigurationProvider(fileSystem, 
FileSystem.CLASSPATH_PROTOCOL)
+            .getConfiguration("mailrepositorystore"));
         repositoryStore.init();
     }
 
@@ -83,6 +85,20 @@ public class InMemoryMailRepositoryStoreTest {
     }
 
     @Test
+    public void configureShouldNotThrowOnEmptyConfiguration() throws Exception 
{
+        try {
+            repositoryStore = new InMemoryMailRepositoryStore(Sets.newHashSet(
+                new MailStoreRepositoryModule.FileMailRepositoryProvider(
+                    fileSystem)));
+        } catch (Exception e) {
+            fail("Unexpected failure : ", e);
+        }
+        repositoryStore.configure(new HierarchicalConfiguration());
+
+        repositoryStore.init();
+    }
+
+    @Test
     public void getUrlsShouldBeEmptyIfNoSelectWerePerformed() {
         assertThat(repositoryStore.getUrls()).isEmpty();
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/jpa-guice/src/main/java/org/apache/james/JPAJamesServerMain.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/jpa-guice/src/main/java/org/apache/james/JPAJamesServerMain.java
 
b/server/container/guice/jpa-guice/src/main/java/org/apache/james/JPAJamesServerMain.java
index 1b64bb2..096559c 100644
--- 
a/server/container/guice/jpa-guice/src/main/java/org/apache/james/JPAJamesServerMain.java
+++ 
b/server/container/guice/jpa-guice/src/main/java/org/apache/james/JPAJamesServerMain.java
@@ -32,6 +32,7 @@ import 
org.apache.james.modules.protocols.ProtocolHandlerModule;
 import org.apache.james.modules.protocols.SMTPServerModule;
 import org.apache.james.modules.server.ActiveMQQueueModule;
 import org.apache.james.modules.server.DataRoutesModules;
+import 
org.apache.james.modules.server.DefaultProcessorsConfigurationProviderModule;
 import org.apache.james.modules.server.JMXServerModule;
 import org.apache.james.modules.server.MailboxRoutesModule;
 import org.apache.james.modules.server.NoJwtModule;
@@ -44,15 +45,15 @@ import com.google.inject.util.Modules;
 public class JPAJamesServerMain {
 
     public static final Module protocols = Modules.combine(
-            new IMAPServerModule(),
-            new ProtocolHandlerModule(),
-            new POP3ServerModule(),
-            new SMTPServerModule(),
-            new LMTPServerModule(),
-            new ManageSieveServerModule(),
-            new WebAdminServerModule(),
-            new DataRoutesModules(),
-            new MailboxRoutesModule());
+        new IMAPServerModule(),
+        new ProtocolHandlerModule(),
+        new POP3ServerModule(),
+        new SMTPServerModule(),
+        new LMTPServerModule(),
+        new ManageSieveServerModule(),
+        new WebAdminServerModule(),
+        new DataRoutesModules(),
+        new MailboxRoutesModule());
     
     public static final Module jpaServerModule = Modules.combine(
         new JPAMailboxModule(),
@@ -61,7 +62,8 @@ public class JPAJamesServerMain {
         new ActiveMQQueueModule(),
         new RawPostDequeueDecoratorModule(),
         new MailboxModule(),
-        new NoJwtModule());
+        new NoJwtModule(),
+        new DefaultProcessorsConfigurationProviderModule());
 
     public static void main(String[] args) throws Exception {
         GuiceJamesServer server = new GuiceJamesServer()

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/jpa-guice/src/main/resources/defaultMailetContainer.xml
----------------------------------------------------------------------
diff --git 
a/server/container/guice/jpa-guice/src/main/resources/defaultMailetContainer.xml
 
b/server/container/guice/jpa-guice/src/main/resources/defaultMailetContainer.xml
new file mode 100644
index 0000000..8a0e360
--- /dev/null
+++ 
b/server/container/guice/jpa-guice/src/main/resources/defaultMailetContainer.xml
@@ -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.
+ -->
+
+<processors>
+    <processor state="root" enableJmx="false">
+        <mailet match="All" class="PostmasterAlias"/>
+        <mailet match="RelayLimit=30" class="Null"/>
+        <mailet match="All" class="ToProcessor">
+            <processor>transport</processor>
+        </mailet>
+    </processor>
+
+    <processor state="error" enableJmx="false">
+        <mailet match="All" class="Bounce"/>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+
+    <processor state="transport" enableJmx="false">
+        <mailet match="SMTPAuthSuccessful" class="SetMimeHeader">
+            <name>X-UserIsAuth</name>
+            <value>true</value>
+        </mailet>
+        <mailet match="All" class="RemoveMimeHeader">
+            <name>bcc</name>
+        </mailet>
+        <mailet match="All" class="RecipientRewriteTable" />
+        <mailet match="RecipientIsLocal" class="LocalDelivery"/>
+        <mailet match="HostIsLocal" class="ToProcessor">
+            <processor>local-address-error</processor>
+            <notice>550 - Requested action not taken: no such user 
here</notice>
+        </mailet>
+        <mailet match="SMTPAuthSuccessful" class="RemoteDelivery">
+            <outgoingQueue>outgoing</outgoingQueue>
+            <delayTime>5000, 100000, 500000</delayTime>
+            <maxRetries>25</maxRetries>
+            <maxDnsProblemRetries>0</maxDnsProblemRetries>
+            <deliveryThreads>10</deliveryThreads>
+            <sendpartial>true</sendpartial>
+            <bounceProcessor>bounces</bounceProcessor>
+        </mailet>
+        <mailet match="All" class="ToProcessor">
+            <processor>relay-denied</processor>
+        </mailet>
+    </processor>
+
+    <processor state="spam" enableJmx="false">
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="local-address-error" enableJmx="false">
+        <mailet match="All" class="Bounce">
+            <attachment>none</attachment>
+        </mailet>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="relay-denied" enableJmx="false">
+        <mailet match="All" class="Bounce">
+            <attachment>none</attachment>
+        </mailet>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="bounces" enableJmx="false">
+        <mailet match="All" class="DSNBounce">
+            <passThrough>false</passThrough>
+        </mailet>
+    </processor>
+
+</processors>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/jpa-smtp/src/main/java/org/apache/james/JPAJamesServerMain.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/jpa-smtp/src/main/java/org/apache/james/JPAJamesServerMain.java
 
b/server/container/guice/jpa-smtp/src/main/java/org/apache/james/JPAJamesServerMain.java
index f8ebc93..2fd0585 100644
--- 
a/server/container/guice/jpa-smtp/src/main/java/org/apache/james/JPAJamesServerMain.java
+++ 
b/server/container/guice/jpa-smtp/src/main/java/org/apache/james/JPAJamesServerMain.java
@@ -26,6 +26,7 @@ import 
org.apache.james.modules.protocols.ProtocolHandlerModule;
 import org.apache.james.modules.protocols.SMTPServerModule;
 import org.apache.james.modules.server.ActiveMQQueueModule;
 import org.apache.james.modules.server.DataRoutesModules;
+import 
org.apache.james.modules.server.DefaultProcessorsConfigurationProviderModule;
 import org.apache.james.modules.server.NoJwtModule;
 import org.apache.james.modules.server.RawPostDequeueDecoratorModule;
 import org.apache.james.modules.server.WebAdminServerModule;
@@ -37,11 +38,12 @@ import com.google.inject.util.Modules;
 public class JPAJamesServerMain {
 
     public static final Module protocols = Modules.combine(
-            new ProtocolHandlerModule(),
-            new SMTPServerModule(),
-            new WebAdminServerModule(),
-            new DataRoutesModules(),
-            new NoJwtModule());
+        new ProtocolHandlerModule(),
+        new SMTPServerModule(),
+        new WebAdminServerModule(),
+        new DataRoutesModules(),
+        new NoJwtModule(),
+        new DefaultProcessorsConfigurationProviderModule());
     
     public static final Module jpaServerModule = Modules.combine(
         new JPADataModule(),

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/jpa-smtp/src/main/resources/defaultMailetContainer.xml
----------------------------------------------------------------------
diff --git 
a/server/container/guice/jpa-smtp/src/main/resources/defaultMailetContainer.xml 
b/server/container/guice/jpa-smtp/src/main/resources/defaultMailetContainer.xml
new file mode 100644
index 0000000..8ce1d59
--- /dev/null
+++ 
b/server/container/guice/jpa-smtp/src/main/resources/defaultMailetContainer.xml
@@ -0,0 +1,81 @@
+<!--
+  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.
+ -->
+
+<processors>
+    <processor state="root" enableJmx="false">
+        <mailet match="All" class="PostmasterAlias"/>
+        <mailet match="RelayLimit=30" class="Null"/>
+        <mailet match="All" class="ToProcessor">
+            <processor>transport</processor>
+        </mailet>
+    </processor>
+
+    <processor state="error" enableJmx="false">
+        <mailet match="All" class="Bounce"/>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="transport" enableJmx="false">
+        <mailet match="SMTPAuthSuccessful" class="SetMimeHeader">
+            <name>X-UserIsAuth</name>
+            <value>true</value>
+        </mailet>
+        <mailet match="All" class="RemoveMimeHeader">
+            <name>bcc</name>
+        </mailet>
+        <mailet match="All" class="RecipientRewriteTable" />
+        <mailet match="SMTPAuthSuccessful" class="RemoteDelivery">
+            <outgoingQueue>outgoing</outgoingQueue>
+            <delayTime>5000, 100000, 500000</delayTime>
+            <maxRetries>25</maxRetries>
+            <maxDnsProblemRetries>0</maxDnsProblemRetries>
+            <deliveryThreads>10</deliveryThreads>
+            <sendpartial>true</sendpartial>
+            <bounceProcessor>bounces</bounceProcessor>
+        </mailet>
+        <mailet match="All" class="ToProcessor">
+            <processor>relay-denied</processor>
+        </mailet>
+    </processor>
+
+    <processor state="spam" enableJmx="false">
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="local-address-error" enableJmx="false">
+        <mailet match="All" class="Bounce">
+            <attachment>none</attachment>
+        </mailet>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="relay-denied" enableJmx="false">
+        <mailet match="All" class="Bounce">
+            <attachment>none</attachment>
+        </mailet>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="bounces" enableJmx="false">
+        <mailet match="All" class="DSNBounce">
+            <passThrough>false</passThrough>
+        </mailet>
+    </processor>
+
+</processors>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
 
b/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
index 34a64a5..58e57c3 100644
--- 
a/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
+++ 
b/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
@@ -26,6 +26,7 @@ import java.util.Set;
 import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.impl.SimpleRegistry;
 import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.HierarchicalConfiguration;
 import org.apache.james.dnsservice.api.DNSService;
 import org.apache.james.domainlist.api.DomainList;
 import org.apache.james.lifecycle.api.Configurable;
@@ -65,6 +66,7 @@ public class CamelMailetContainerModule extends 
AbstractModule {
     private static final Logger CAMEL_LOGGER = 
LoggerFactory.getLogger(CamelCompositeProcessor.class);
     private static final Logger SPOOLER_LOGGER = 
LoggerFactory.getLogger(JamesMailSpooler.class);
     private static final Logger MAILET_LOGGER = 
LoggerFactory.getLogger(JamesMailetContext.class);
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(CamelMailetContainerModule.class);
 
     @Override
     protected void configure() {
@@ -106,7 +108,8 @@ public class CamelMailetContainerModule extends 
AbstractModule {
         private final JamesMailSpooler jamesMailSpooler;
         private final JamesMailetContext mailetContext;
         private final MailQueueFactory mailQueueFactory;
-        private Set<TransportProcessorCheck> transportProcessorCheckSet;
+        private final DefaultProcessorsConfigurationSupplier 
defaultProcessorsConfigurationSupplier;
+        private final Set<TransportProcessorCheck> transportProcessorCheckSet;
 
         @Inject
         public MailetModuleConfigurationPerformer(ConfigurationProvider 
configurationProvider,
@@ -114,13 +117,15 @@ public class CamelMailetContainerModule extends 
AbstractModule {
                                                 JamesMailSpooler 
jamesMailSpooler,
                                                 JamesMailetContext 
mailetContext,
                                                 MailQueueFactory 
mailQueueFactory,
-                                                Set<TransportProcessorCheck> 
transportProcessorCheckSet) {
+                                                Set<TransportProcessorCheck> 
transportProcessorCheckSet,
+                                                
DefaultProcessorsConfigurationSupplier defaultProcessorsConfigurationSupplier) {
             this.configurationProvider = configurationProvider;
             this.camelCompositeProcessor = camelCompositeProcessor;
             this.jamesMailSpooler = jamesMailSpooler;
             this.mailetContext = mailetContext;
             this.mailQueueFactory = mailQueueFactory;
             this.transportProcessorCheckSet = transportProcessorCheckSet;
+            this.defaultProcessorsConfigurationSupplier = 
defaultProcessorsConfigurationSupplier;
         }
 
         @Override
@@ -129,24 +134,66 @@ public class CamelMailetContainerModule extends 
AbstractModule {
                 DefaultCamelContext camelContext = new DefaultCamelContext();
                 camelContext.disableJMX();
                 camelContext.setRegistry(new SimpleRegistry());
-                camelCompositeProcessor.setLog(CAMEL_LOGGER);
-                camelCompositeProcessor.setCamelContext(camelContext);
-                
camelCompositeProcessor.configure(configurationProvider.getConfiguration("mailetcontainer").configurationAt("processors"));
-                camelCompositeProcessor.init();
+                configureProcessors(camelContext);
                 checkProcessors();
-                jamesMailSpooler.setMailProcessor(camelCompositeProcessor);
-                jamesMailSpooler.setLog(SPOOLER_LOGGER);
-                
jamesMailSpooler.configure(configurationProvider.getConfiguration("mailetcontainer").configurationAt("spooler"));
-                jamesMailSpooler.init();
-                mailetContext.setLog(MAILET_LOGGER);
-                
mailetContext.configure(configurationProvider.getConfiguration("mailetcontainer").configurationAt("context"));
-                mailetContext.retrieveRootMailQueue(mailQueueFactory);
+                configureJamesSpooler();
+                configureMailetContext();
             } catch (Exception e) {
                 throw Throwables.propagate(e);
             }
 
         }
 
+        private void configureProcessors(DefaultCamelContext camelContext) 
throws Exception {
+            camelCompositeProcessor.setLog(CAMEL_LOGGER);
+            camelCompositeProcessor.setCamelContext(camelContext);
+            camelCompositeProcessor.configure(getProcessorConfiguration());
+            camelCompositeProcessor.init();
+        }
+
+        private HierarchicalConfiguration getProcessorConfiguration() {
+            try {
+                return 
configurationProvider.getConfiguration("mailetcontainer")
+                    .configurationAt("processors");
+            } catch (Exception e) {
+                LOGGER.warn("Could not load configuration for Processors. 
Fallback to default.");
+                return 
defaultProcessorsConfigurationSupplier.getDefaultConfiguration();
+            }
+        }
+
+        private void configureJamesSpooler() throws ConfigurationException {
+            jamesMailSpooler.setMailProcessor(camelCompositeProcessor);
+            jamesMailSpooler.setLog(SPOOLER_LOGGER);
+            jamesMailSpooler.configure(getJamesSpoolerConfiguration());
+            jamesMailSpooler.init();
+        }
+
+        private HierarchicalConfiguration getJamesSpoolerConfiguration() {
+            try {
+                return 
configurationProvider.getConfiguration("mailetcontainer")
+                    .configurationAt("spooler");
+            } catch (Exception e) {
+                LOGGER.warn("Could not locate configuration for James Spooler. 
Assuming empty configuration for this component.");
+                return new HierarchicalConfiguration();
+            }
+        }
+
+        private void configureMailetContext() throws ConfigurationException {
+            mailetContext.setLog(MAILET_LOGGER);
+            mailetContext.configure(getMailetContextConfiguration());
+            mailetContext.retrieveRootMailQueue(mailQueueFactory);
+        }
+
+        private HierarchicalConfiguration getMailetContextConfiguration() {
+            try {
+                return 
configurationProvider.getConfiguration("mailetcontainer")
+                    .configurationAt("context");
+            } catch (Exception e) {
+                LOGGER.warn("Could not locate configuration for Mailet 
context. Assuming empty configuration for this component.");
+                return new HierarchicalConfiguration();
+            }
+        }
+
         private void checkProcessors() throws ConfigurationException {
             MailProcessor mailProcessor = 
Optional.ofNullable(camelCompositeProcessor.getProcessor("transport"))
                 .orElseThrow(() -> new RuntimeException("JMAP needs a 
transport processor"));
@@ -184,4 +231,8 @@ public class CamelMailetContainerModule extends 
AbstractModule {
         }
     }
 
+    public interface DefaultProcessorsConfigurationSupplier {
+        HierarchicalConfiguration getDefaultConfiguration();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/memory-guice/src/test/resources/imapserver.xml
----------------------------------------------------------------------
diff --git 
a/server/container/guice/memory-guice/src/test/resources/imapserver.xml 
b/server/container/guice/memory-guice/src/test/resources/imapserver.xml
deleted file mode 100644
index ff478a9..0000000
--- a/server/container/guice/memory-guice/src/test/resources/imapserver.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-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.
--->
-
-
-<imapservers>
-       <imapserver enabled="true">
-               <jmxName>imapserver</jmxName>
-               <bind>0.0.0.0:1143</bind>
-               <connectionBacklog>200</connectionBacklog>
-               <tls socketTLS="false" startTLS="false">
-                       <!-- To create a new keystore execute:
-            keytool -genkey -alias james -keyalg RSA -keystore 
/path/to/james/conf/keystore
-              -->
-                       <keystore>file://conf/keystore</keystore>
-                       <secret>james72laBalle</secret>
-                       
<provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
-               </tls>
-               <connectionLimit>0</connectionLimit>
-               <connectionLimitPerIP>0</connectionLimitPerIP>
-       </imapserver>
-       <imapserver enabled="true">
-               <jmxName>imapserver-ssl</jmxName>
-               <bind>0.0.0.0:1993</bind>
-               <connectionBacklog>200</connectionBacklog>
-               <tls socketTLS="false" startTLS="false">
-                       <!-- To create a new keystore execute:
-              keytool -genkey -alias james -keyalg RSA -keystore 
/path/to/james/conf/keystore
-             -->
-                       <keystore>file://conf/keystore</keystore>
-                       <secret>james72laBalle</secret>
-                       
<provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
-               </tls>
-               <connectionLimit>0</connectionLimit>
-               <connectionLimitPerIP>0</connectionLimitPerIP>
-       </imapserver>
-</imapservers>

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/protocols/jmap/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/pom.xml 
b/server/container/guice/protocols/jmap/pom.xml
index dcc9fee..c0b43bd 100644
--- a/server/container/guice/protocols/jmap/pom.xml
+++ b/server/container/guice/protocols/jmap/pom.xml
@@ -160,6 +160,10 @@
                     <scope>test</scope>
                 </dependency>
                 <dependency>
+                    <groupId>org.apache.james</groupId>
+                    <artifactId>james-server-guice-common</artifactId>
+                </dependency>
+                <dependency>
                     <groupId>${project.groupId}</groupId>
                     <artifactId>james-server-guice-configuration</artifactId>
                 </dependency>
@@ -180,6 +184,11 @@
                     <artifactId>guice-multibindings</artifactId>
                 </dependency>
                 <dependency>
+                    <groupId>com.jayway.restassured</groupId>
+                    <artifactId>rest-assured</artifactId>
+                    <scope>test</scope>
+                </dependency>
+                <dependency>
                     <groupId>junit</groupId>
                     <artifactId>junit</artifactId>
                     <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
 
b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
index 86f3f5e..73ef2f5 100644
--- 
a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
+++ 
b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Optional;
 
 import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.DefaultConfigurationBuilder;
 import org.apache.commons.configuration.PropertiesConfiguration;
 import org.apache.commons.io.FileUtils;
 import org.apache.james.filesystem.api.FileSystem;
@@ -44,6 +45,7 @@ import 
org.apache.james.modules.server.CamelMailetContainerModule;
 import org.apache.james.queue.api.MailQueueItemDecoratorFactory;
 import org.apache.james.transport.matchers.RecipientIsLocal;
 import org.apache.james.utils.ConfigurationPerformer;
+import org.apache.james.utils.FileConfigurationProvider;
 import org.apache.james.utils.PropertiesProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -51,6 +53,7 @@ import org.slf4j.LoggerFactory;
 import com.github.fge.lambdas.Throwing;
 import com.google.common.base.Charsets;
 import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
 import com.google.common.collect.ImmutableList;
 import com.google.inject.AbstractModule;
 import com.google.inject.Inject;
@@ -62,11 +65,23 @@ import com.google.inject.multibindings.Multibinder;
 public class JMAPModule extends AbstractModule {
     private static final int DEFAULT_JMAP_PORT = 80;
     private static final Logger LOGGER = 
LoggerFactory.getLogger(JMAPModule.class);
+    public static final 
CamelMailetContainerModule.DefaultProcessorsConfigurationSupplier 
DEFAULT_JMAP_PROCESSORS_CONFIGURATION_SUPPLIER =
+        () -> {
+            try {
+                return 
FileConfigurationProvider.getConfig(ClassLoader.getSystemResourceAsStream("defaultJmapMailetContainer.xml"));
+            } catch (ConfigurationException e) {
+                throw Throwables.propagate(e);
+            }
+        };
 
     @Override
     protected void configure() {
         install(new JMAPCommonModule());
         install(new MethodsModule());
+        install(binder -> binder
+            
.bind(CamelMailetContainerModule.DefaultProcessorsConfigurationSupplier.class)
+            .toInstance(DEFAULT_JMAP_PROCESSORS_CONFIGURATION_SUPPLIER));
+
         bind(JMAPServer.class).in(Scopes.SINGLETON);
         bind(RequestHandler.class).in(Scopes.SINGLETON);
         bind(UploadHandler.class).in(Scopes.SINGLETON);

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml
----------------------------------------------------------------------
diff --git 
a/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml
 
b/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml
new file mode 100644
index 0000000..81386a4
--- /dev/null
+++ 
b/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml
@@ -0,0 +1,97 @@
+<!--
+  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.
+ -->
+
+<processors>
+    <processor state="root" enableJmx="false">
+        <mailet match="All" class="PostmasterAlias"/>
+        <mailet match="RelayLimit=30" class="Null"/>
+        <mailet match="All" class="ToProcessor">
+            <processor>transport</processor>
+        </mailet>
+    </processor>
+
+    <processor state="error" enableJmx="false">
+        <mailet match="All" class="Bounce"/>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+
+    <processor state="transport" enableJmx="false">
+        <mailet match="SMTPAuthSuccessful" class="SetMimeHeader">
+            <name>X-UserIsAuth</name>
+            <value>true</value>
+        </mailet>
+        <mailet match="All" class="RemoveMimeHeader">
+            <name>bcc</name>
+        </mailet>
+        <mailet match="All" class="RecipientRewriteTable" />
+        <mailet match="RecipientIsLocal" 
class="org.apache.james.jmap.mailet.VacationMailet"/>
+        <mailet match="RecipientIsLocal" class="LocalDelivery"/>
+        <mailet match="HostIsLocal" class="ToProcessor">
+            <processor>local-address-error</processor>
+            <notice>550 - Requested action not taken: no such user 
here</notice>
+        </mailet>
+        <mailet match="SMTPAuthSuccessful" class="ToProcessor">
+            <processor>relay</processor>
+        </mailet>
+        <mailet 
match="HasMailAttribute=org.apache.james.jmap.send.MailMetaData.messageId" 
class="ToProcessor">
+            <processor>relay</processor>
+        </mailet>
+        <mailet match="All" class="ToProcessor">
+            <processor>relay-denied</processor>
+        </mailet>
+    </processor>
+
+    <processor state="relay" enableJmx="true">
+        <mailet match="All" class="RemoteDelivery">
+            <outgoingQueue>outgoing</outgoingQueue>
+            <delayTime>5000, 100000, 500000</delayTime>
+            <maxRetries>25</maxRetries>
+            <maxDnsProblemRetries>0</maxDnsProblemRetries>
+            <deliveryThreads>10</deliveryThreads>
+            <sendpartial>true</sendpartial>
+            <bounceProcessor>bounces</bounceProcessor>
+        </mailet>
+    </processor>
+
+    <processor state="spam" enableJmx="false">
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="local-address-error" enableJmx="false">
+        <mailet match="All" class="Bounce">
+            <attachment>none</attachment>
+        </mailet>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="relay-denied" enableJmx="false">
+        <mailet match="All" class="Bounce">
+            <attachment>none</attachment>
+        </mailet>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="bounces" enableJmx="false">
+        <mailet match="All" class="DSNBounce">
+            <passThrough>false</passThrough>
+        </mailet>
+    </processor>
+
+</processors>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/protocols/jmap/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/protocols/jmap/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
 
b/server/container/guice/protocols/jmap/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
new file mode 100644
index 0000000..46a4394
--- /dev/null
+++ 
b/server/container/guice/protocols/jmap/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
@@ -0,0 +1,145 @@
+/****************************************************************
+ * 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;
+
+import static com.jayway.restassured.RestAssured.given;
+import static com.jayway.restassured.config.EncoderConfig.encoderConfig;
+import static com.jayway.restassured.config.RestAssuredConfig.newConfig;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.nio.charset.Charset;
+
+import org.apache.james.utils.DataProbeImpl;
+import org.apache.james.utils.JmapGuiceProbe;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.base.Charsets;
+import com.jayway.restassured.RestAssured;
+import com.jayway.restassured.builder.RequestSpecBuilder;
+import com.jayway.restassured.http.ContentType;
+
+public abstract class AbstractJmapJamesServerTest {
+
+    private static final int IMAP_PORT_SSL = 1993;
+    private static final int POP3_PORT = 1110;
+    private static final int SMTP_PORT = 1025;
+    private static final int LMTP_PORT = 1024;
+
+    protected static final String JAMES_SERVER_HOST = "127.0.0.1";
+    protected static final int IMAP_PORT = 1143; // You need to be root 
(superuser) to bind to ports under 1024.
+
+    private GuiceJamesServer server;
+    private SocketChannel socketChannel;
+
+    @Before
+    public void setup() throws Exception {
+        server = createJamesServer();
+        socketChannel = SocketChannel.open();
+        server.start();
+
+        RestAssured.requestSpecification = new RequestSpecBuilder()
+            .setContentType(ContentType.JSON)
+            .setAccept(ContentType.JSON)
+            
.setConfig(newConfig().encoderConfig(encoderConfig().defaultContentCharset(Charsets.UTF_8)))
+            .setPort(server.getProbe(JmapGuiceProbe.class).getJmapPort())
+            .build();
+    }
+
+    protected abstract GuiceJamesServer createJamesServer();
+
+    protected abstract void clean();
+
+    @After
+    public void tearDown() throws Exception {
+        if (server != null) {
+            server.stop();
+        }
+        clean();
+    }
+
+    @Test
+    public void hostnameShouldBeUsedAsDefaultDomain() throws Exception {
+        String expectedDefaultDomain = 
InetAddress.getLocalHost().getHostName();
+
+        
assertThat(server.getProbe(DataProbeImpl.class).getDefaultDomain()).isEqualTo(expectedDefaultDomain);
+    }
+
+    @Test
+    public void hostnameShouldBeRetrievedWhenRestarting() throws Exception {
+        server.stop();
+        server.start();
+        String expectedDefaultDomain = 
InetAddress.getLocalHost().getHostName();
+
+        
assertThat(server.getProbe(DataProbeImpl.class).getDefaultDomain()).isEqualTo(expectedDefaultDomain);
+    }
+
+    @Test
+    public void connectIMAPServerShouldSendShabangOnConnect() throws Exception 
{
+        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, 
IMAP_PORT));
+        assertThat(getServerConnectionResponse(socketChannel)).startsWith("* 
OK JAMES IMAP4rev1 Server");
+    }
+
+    @Test
+    public void 
connectOnSecondaryIMAPServerIMAPServerShouldSendShabangOnConnect() throws 
Exception {
+        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, 
IMAP_PORT_SSL));
+        assertThat(getServerConnectionResponse(socketChannel)).startsWith("* 
OK JAMES IMAP4rev1 Server");
+    }
+
+    @Test
+    public void connectPOP3ServerShouldSendShabangOnConnect() throws Exception 
{
+        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, 
POP3_PORT));
+        assertThat(getServerConnectionResponse(socketChannel)).contains("POP3 
server (JAMES POP3 Server ) ready");
+    }
+
+    @Test
+    public void connectSMTPServerShouldSendShabangOnConnect() throws Exception 
{
+        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, 
SMTP_PORT));
+        assertThat(getServerConnectionResponse(socketChannel)).startsWith("220 
JAMES Linagora's SMTP awesome Server");
+    }
+
+    @Test
+    public void connectLMTPServerShouldSendShabangOnConnect() throws Exception 
{
+        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, 
LMTP_PORT));
+        assertThat(getServerConnectionResponse(socketChannel)).contains("LMTP 
Server (JAMES Protocols Server) ready");
+    }
+
+    @Test
+    public void connectJMAPServerShouldRespondBadRequest() throws Exception {
+        given()
+            .body("{\"badAttributeName\": \"value\"}")
+        .when()
+            .post("/authentication")
+        .then()
+            .statusCode(400);
+    }
+
+    private String getServerConnectionResponse(SocketChannel socketChannel) 
throws IOException {
+        ByteBuffer byteBuffer = ByteBuffer.allocate(1000);
+        socketChannel.read(byteBuffer);
+        byte[] bytes = byteBuffer.array();
+        return new String(bytes, Charset.forName("UTF-8"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java
----------------------------------------------------------------------
diff --git 
a/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java
 
b/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java
index 7d8ff6c..e91ede4 100644
--- 
a/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java
+++ 
b/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java
@@ -388,6 +388,20 @@ public class ReadOnlyUsersLDAPRepository implements 
UsersRepository, Configurabl
         filter = configuration.getString("[@filter]");
 
         administratorId = 
Optional.fromNullable(configuration.getString("[@administratorId]"));
+
+        checkState();
+    }
+
+    private void checkState() throws ConfigurationException {
+        if (userBase == null) {
+            throw new ConfigurationException("[@userBase] is mandatory");
+        }
+        if (userIdAttribute == null) {
+            throw new ConfigurationException("[@userIdAttribute] is 
mandatory");
+        }
+        if (userObjectClass == null) {
+            throw new ConfigurationException("[@userObjectClass] is 
mandatory");
+        }
     }
 
     /**


---------------------------------------------------------------------
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