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 2018/06/13 02:49:10 UTC

[1/8] james-project git commit: JAMES-2415 es-reporter actually use http to put data in ES, drop backend-es dependency

Repository: james-project
Updated Branches:
  refs/heads/master 257eae573 -> 175f1f29c


JAMES-2415 es-reporter actually use http to put data in ES, drop backend-es dependency


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

Branch: refs/heads/master
Commit: ca761df4264d1cc4f5f3b727df43fb7a0d55d63f
Parents: a6d58e4
Author: Matthieu Baechler <ma...@apache.org>
Authored: Wed Jun 6 17:47:08 2018 +0200
Committer: benwa <bt...@linagora.com>
Committed: Wed Jun 13 09:41:33 2018 +0700

----------------------------------------------------------------------
 server/container/metrics/metrics-es-reporter/pom.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/ca761df4/server/container/metrics/metrics-es-reporter/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/metrics/metrics-es-reporter/pom.xml b/server/container/metrics/metrics-es-reporter/pom.xml
index 6c1a197..3406d14 100644
--- a/server/container/metrics/metrics-es-reporter/pom.xml
+++ b/server/container/metrics/metrics-es-reporter/pom.xml
@@ -32,6 +32,11 @@
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>apache-james-backends-es</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-util-java8</artifactId>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
@@ -68,11 +73,6 @@
         </dependency>
         <dependency>
             <groupId>org.elasticsearch</groupId>
-            <artifactId>elasticsearch</artifactId>
-            <version>2.2.1</version>
-        </dependency>
-        <dependency>
-            <groupId>org.elasticsearch</groupId>
             <artifactId>metrics-elasticsearch-reporter</artifactId>
         </dependency>
         <dependency>


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


[3/8] james-project git commit: JAMES-2413 Enable / disable repository creation in ToSenderDomainRepository

Posted by bt...@apache.org.
JAMES-2413 Enable / disable repository creation in ToSenderDomainRepository


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

Branch: refs/heads/master
Commit: addce27e46343b643404aebb9e05a9a7290ef06f
Parents: be94620
Author: benwa <bt...@linagora.com>
Authored: Thu Jun 7 11:03:52 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Wed Jun 13 09:42:35 2018 +0700

----------------------------------------------------------------------
 .../james/utils/MailRepositoryProbeImpl.java    |   9 ++
 .../mailets/ToSenderDomainRepositoryTest.java   | 131 ++++++++++++++++---
 .../mailets/ToSenderDomainRepository.java       |  31 ++++-
 3 files changed, 150 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/addce27e/server/container/guice/guice-common/src/main/java/org/apache/james/utils/MailRepositoryProbeImpl.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/MailRepositoryProbeImpl.java b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/MailRepositoryProbeImpl.java
index e3143f2..f49fedd 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/MailRepositoryProbeImpl.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/MailRepositoryProbeImpl.java
@@ -43,10 +43,19 @@ public class MailRepositoryProbeImpl implements GuiceProbe {
         return repositoryStore.select(url).size();
     }
 
+    public void createRepository(String url) throws Exception {
+        repositoryStore.select(url);
+    }
+
     public List<String> listMailKeys(String url) throws Exception {
         return ImmutableList.copyOf(
             repositoryStore.select(url)
                 .list());
     }
 
+    public List<String> listRepositoryUrls() {
+        return ImmutableList.copyOf(
+            repositoryStore.getUrls());
+    }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/addce27e/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
index 1e19e08..b811e8f 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
@@ -24,19 +24,18 @@ import static org.apache.james.mailets.configuration.Constants.LOCALHOST_IP;
 import static org.apache.james.mailets.configuration.Constants.PASSWORD;
 import static org.apache.james.mailets.configuration.Constants.SMTP_PORT;
 import static org.apache.james.mailets.configuration.Constants.awaitAtMostOneMinute;
+import static org.assertj.core.api.Assertions.assertThat;
 
 import org.apache.james.mailets.TemporaryJamesServer;
 import org.apache.james.mailets.configuration.MailetConfiguration;
 import org.apache.james.mailets.configuration.MailetContainer;
 import org.apache.james.mailets.configuration.ProcessorConfiguration;
-import org.apache.james.probe.DataProbe;
 import org.apache.james.transport.matchers.All;
 import org.apache.james.utils.DataProbeImpl;
 import org.apache.james.utils.IMAPMessageReader;
 import org.apache.james.utils.MailRepositoryProbeImpl;
 import org.apache.james.utils.SMTPMessageSender;
 import org.junit.After;
-import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
@@ -45,6 +44,7 @@ public class ToSenderDomainRepositoryTest {
 
     private static final String RECIPIENT = "touser@" + DEFAULT_DOMAIN;
     private static final String CUSTOM_REPOSITORY_PREFIX = "file://var/mail/custom/";
+    public static final String AWAIT_REPOSITORY_PATH = "file://var/mail/await/";
 
     @Rule
     public TemporaryFolder temporaryFolder = new TemporaryFolder();
@@ -54,49 +54,140 @@ public class ToSenderDomainRepositoryTest {
     public SMTPMessageSender messageSender = new SMTPMessageSender(DEFAULT_DOMAIN);
 
     private TemporaryJamesServer jamesServer;
-    private MailRepositoryProbeImpl probe;
 
-    @Before
-    public void setup() throws Exception {
-        MailetContainer.Builder mailetContainer = TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+    @After
+    public void tearDown() {
+        if (jamesServer != null) {
+            jamesServer.shutdown();
+        }
+    }
+
+    @Test
+    public void incomingMailShouldBeStoredInCorrespondingMailRepository() throws Exception {
+        initializeJamesServer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
             .putProcessor(ProcessorConfiguration.root()
                 .addMailet(MailetConfiguration.builder()
                     .matcher(All.class)
                     .mailet(ToSenderDomainRepository.class)
-                    .addProperty("urlPrefix", CUSTOM_REPOSITORY_PREFIX)));
+                    .addProperty("urlPrefix", CUSTOM_REPOSITORY_PREFIX))));
 
-        jamesServer = TemporaryJamesServer.builder()
-            .withMailetContainer(mailetContainer)
-            .build(temporaryFolder);
+        messageSender.connect(LOCALHOST_IP, SMTP_PORT)
+            .sendMessage(RECIPIENT, RECIPIENT);
+
+        awaitAtMostOneMinute.until(
+            () -> jamesServer.getProbe(MailRepositoryProbeImpl.class)
+                .getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 1);
+    }
+
+    @Test
+    public void incomingMailShouldBeStoredWhenRepositoryDoNotExistAndAllowedToCreateRepository() throws Exception {
+        initializeJamesServer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+            .putProcessor(ProcessorConfiguration.root()
+                .addMailet(MailetConfiguration.builder()
+                    .matcher(All.class)
+                    .mailet(ToSenderDomainRepository.class)
+                    .addProperty("urlPrefix", CUSTOM_REPOSITORY_PREFIX)
+                    .addProperty("allowRepositoryCreation", "true"))));
 
-        DataProbe dataProbe = jamesServer.getProbe(DataProbeImpl.class);
-        dataProbe.addDomain(DEFAULT_DOMAIN);
-        dataProbe.addUser(RECIPIENT, PASSWORD);
+        messageSender.connect(LOCALHOST_IP, SMTP_PORT)
+            .sendMessage(RECIPIENT, RECIPIENT);
 
-        probe = jamesServer.getProbe(MailRepositoryProbeImpl.class);
+        awaitAtMostOneMinute.until(
+            () -> jamesServer.getProbe(MailRepositoryProbeImpl.class)
+                .getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 1);
     }
 
-    @After
-    public void tearDown() {
-        jamesServer.shutdown();
+    @Test
+    public void incomingMailShouldBeStoredWhenRepositoryExistsAndAllowedToCreateRepository() throws Exception {
+        initializeJamesServer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+            .putProcessor(ProcessorConfiguration.root()
+                .addMailet(MailetConfiguration.builder()
+                    .matcher(All.class)
+                    .mailet(ToSenderDomainRepository.class)
+                    .addProperty("urlPrefix", CUSTOM_REPOSITORY_PREFIX)
+                    .addProperty("allowRepositoryCreation", "true"))));
+        jamesServer.getProbe(MailRepositoryProbeImpl.class)
+            .createRepository(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN);
+
+        messageSender.connect(LOCALHOST_IP, SMTP_PORT)
+            .sendMessage(RECIPIENT, RECIPIENT);
+
+        awaitAtMostOneMinute.until(
+            () -> jamesServer.getProbe(MailRepositoryProbeImpl.class)
+                .getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 1);
     }
 
     @Test
-    public void incomingMailShouldBeStoredInCorrespondingMailRepository() throws Exception {
+    public void incomingMailShouldBeIgnoredWhenRepositoryDoNotExistAndNotAllowedToCreateRepository() throws Exception {
+        initializeJamesServer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+            .putProcessor(ProcessorConfiguration.root()
+                .addMailet(MailetConfiguration.builder()
+                    .matcher(All.class)
+                    .mailet(ToSenderDomainRepository.class)
+                    .addProperty("urlPrefix", CUSTOM_REPOSITORY_PREFIX)
+                    .addProperty("allowRepositoryCreation", "false")
+                    .addProperty("passThrough", "true"))
+                .addMailet(MailetConfiguration.builder()
+                    .matcher(All.class)
+                    .mailet(ToRepository.class)
+                    .addProperty("repositoryPath", AWAIT_REPOSITORY_PATH))));
+        MailRepositoryProbeImpl mailRepositoryProbe = jamesServer.getProbe(MailRepositoryProbeImpl.class);
+
         messageSender.connect(LOCALHOST_IP, SMTP_PORT)
             .sendMessage(RECIPIENT, RECIPIENT);
 
         awaitAtMostOneMinute.until(
-            () -> probe.getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 1);
+            () -> mailRepositoryProbe.getRepositoryMailCount(AWAIT_REPOSITORY_PATH) == 1);
+
+        assertThat(mailRepositoryProbe.listRepositoryUrls())
+            .doesNotContain(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN);
+    }
+
+    @Test
+    public void incomingMailShouldBeStoredWhenRepositoryExistsAndNotAllowedToCreateRepository() throws Exception {
+        initializeJamesServer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+            .putProcessor(ProcessorConfiguration.root()
+                .addMailet(MailetConfiguration.builder()
+                    .matcher(All.class)
+                    .mailet(ToSenderDomainRepository.class)
+                    .addProperty("urlPrefix", CUSTOM_REPOSITORY_PREFIX)
+                    .addProperty("allowRepositoryCreation", "false"))));
+        jamesServer.getProbe(MailRepositoryProbeImpl.class)
+            .createRepository(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN);
+
+        messageSender.connect(LOCALHOST_IP, SMTP_PORT)
+            .sendMessage(RECIPIENT, RECIPIENT);
+
+        awaitAtMostOneMinute.until(
+            () -> jamesServer.getProbe(MailRepositoryProbeImpl.class)
+                .getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 1);
     }
 
     @Test
     public void incomingMailsShouldBeStoredInCorrespondingMailRepository() throws Exception {
+        initializeJamesServer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+            .putProcessor(ProcessorConfiguration.root()
+                .addMailet(MailetConfiguration.builder()
+                    .matcher(All.class)
+                    .mailet(ToSenderDomainRepository.class)
+                    .addProperty("urlPrefix", CUSTOM_REPOSITORY_PREFIX))));
+
         messageSender.connect(LOCALHOST_IP, SMTP_PORT)
             .sendMessage(RECIPIENT, RECIPIENT)
             .sendMessage(RECIPIENT, RECIPIENT);
 
         awaitAtMostOneMinute.until(
-            () -> probe.getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 2);
+            () -> jamesServer.getProbe(MailRepositoryProbeImpl.class)
+                .getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 2);
+    }
+
+    private void initializeJamesServer(MailetContainer.Builder mailetContainer) throws Exception {
+        jamesServer = TemporaryJamesServer.builder()
+            .withMailetContainer(mailetContainer)
+            .build(temporaryFolder);
+
+        jamesServer.getProbe(DataProbeImpl.class)
+            .fluentAddDomain(DEFAULT_DOMAIN)
+            .fluentAddUser(RECIPIENT, PASSWORD);
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/addce27e/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
index b86482e..8f417c6 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
@@ -24,9 +24,15 @@ import java.util.Optional;
 import javax.inject.Inject;
 import javax.mail.MessagingException;
 
+import org.apache.james.mailrepository.api.MailRepository;
 import org.apache.james.mailrepository.api.MailRepositoryStore;
 import org.apache.mailet.Mail;
 import org.apache.mailet.base.GenericMailet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.github.fge.lambdas.Throwing;
+import com.github.fge.lambdas.consumers.ThrowingConsumer;
 
 /**
  * Stores incoming Mail in a repository defined by the sender's domain.<br>
@@ -37,21 +43,29 @@ import org.apache.mailet.base.GenericMailet;
  *  For example for the value 'cassandra://var/mail/sendersRepositories/', a mail sent by 'user@james.org'
  *  will be stored in 'cassandra://var/mail/sendersRepositories/james.org'.
  *  - "passThrough" optional, defaults to false. If true, the processing of the mail continues. If false it stops.
+ *  - "allowRepositoryCreation" optional, defaults to true. If true, non existing repository will be created. In case of
+ *  misconfiguration, this might lead to arbitrary repository creation. If false, the incoming mails will be stored only
+ *  in already existing repository. If not existing, the email will be dropped with an appropriate log warning (leading
+ *  to potential data loss).
  *
  *  Example:
  *
  * &lt;mailet matcher="All" class="ToSenderDomainRepository"&gt;
  *     &lt;urlPrefix&gt;cassandra://var/mail/sendersRepositories/&lt;/urlPrefix&gt;
  *     &lt;passThrough&gt;false&lt;/passThrough&gt;
+ *     &lt;allowRepositoryCreation&gt;true&lt;/allowRepositoryCreation&gt;
  * &lt;/mailet&gt;
  */
 public class ToSenderDomainRepository extends GenericMailet {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(ToSenderDomainRepository.class);
     private static final boolean DEFAULT_CONSUME = false;
+    private static final boolean DEFAULT_ALLOW_REPOSITORY_CREATION = true;
 
     private final MailRepositoryStore mailRepositoryStore;
     private String urlPrefix;
     private boolean passThrough;
+    private boolean allowRepositoryCreation;
 
     @Inject
     public ToSenderDomainRepository(MailRepositoryStore mailRepositoryStore) {
@@ -63,6 +77,7 @@ public class ToSenderDomainRepository extends GenericMailet {
         urlPrefix = Optional.ofNullable(getInitParameter("urlPrefix"))
             .orElseThrow(() -> new MessagingException("'urlPrefix' is a mandatory configuration property"));
         passThrough = getInitParameter("passThrough", DEFAULT_CONSUME);
+        allowRepositoryCreation = getInitParameter("allowRepositoryCreation", DEFAULT_ALLOW_REPOSITORY_CREATION);
     }
 
     @Override
@@ -76,12 +91,26 @@ public class ToSenderDomainRepository extends GenericMailet {
 
     private void store(Mail mail, String url) throws MessagingException {
         try {
-            mailRepositoryStore.select(url).store(mail);
+            Optional<MailRepository> mailRepository = retrieveRepository(url);
+            if (!mailRepository.isPresent()) {
+                LOGGER.warn("'{}' mail repository does not exist and will not be created. Mail {} will not be stored in it.",
+                    url, mail.getName());
+            }
+            ThrowingConsumer<MailRepository> storingConsumer = repository -> repository.store(mail);
+            mailRepository.ifPresent(Throwing.consumer(storingConsumer).sneakyThrow());
         } catch (MailRepositoryStore.MailRepositoryStoreException e) {
             throw new MessagingException("Error while selecting url " + url, e);
         }
     }
 
+    private Optional<MailRepository> retrieveRepository(String url) throws MailRepositoryStore.MailRepositoryStoreException {
+        if (allowRepositoryCreation) {
+            return Optional.of(mailRepositoryStore.select(url));
+        } else {
+            return mailRepositoryStore.get(url);
+        }
+    }
+
     @Override
     public String getMailetInfo() {
         return "ToSenderDomainRepository Mailet";


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


[4/8] james-project git commit: JAMES-2413 [DLP] Mailet to store an email in a repository depending on the domain of the sender

Posted by bt...@apache.org.
JAMES-2413 [DLP] Mailet to store an email in a repository depending on the domain of the sender


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

Branch: refs/heads/master
Commit: adfcf46d62be5c2eb5e2a174123ae40dbb12349b
Parents: ca761df
Author: duc <tr...@gmail.com>
Authored: Wed Jun 6 16:55:06 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Wed Jun 13 09:42:35 2018 +0700

----------------------------------------------------------------------
 .../mailets/ToSenderDomainRepositoryTest.java   | 102 ++++++++++
 server/mailet/mailets/pom.xml                   |  31 ++-
 .../mailets/ToSenderDomainRepository.java       |  89 +++++++++
 .../mailets/ToSenderDomainRepositoryTest.java   | 195 +++++++++++++++++++
 4 files changed, 412 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/adfcf46d/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
new file mode 100644
index 0000000..1e19e08
--- /dev/null
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
@@ -0,0 +1,102 @@
+/****************************************************************
+ * 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.transport.mailets;
+
+import static org.apache.james.mailets.configuration.Constants.DEFAULT_DOMAIN;
+import static org.apache.james.mailets.configuration.Constants.LOCALHOST_IP;
+import static org.apache.james.mailets.configuration.Constants.PASSWORD;
+import static org.apache.james.mailets.configuration.Constants.SMTP_PORT;
+import static org.apache.james.mailets.configuration.Constants.awaitAtMostOneMinute;
+
+import org.apache.james.mailets.TemporaryJamesServer;
+import org.apache.james.mailets.configuration.MailetConfiguration;
+import org.apache.james.mailets.configuration.MailetContainer;
+import org.apache.james.mailets.configuration.ProcessorConfiguration;
+import org.apache.james.probe.DataProbe;
+import org.apache.james.transport.matchers.All;
+import org.apache.james.utils.DataProbeImpl;
+import org.apache.james.utils.IMAPMessageReader;
+import org.apache.james.utils.MailRepositoryProbeImpl;
+import org.apache.james.utils.SMTPMessageSender;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+public class ToSenderDomainRepositoryTest {
+
+    private static final String RECIPIENT = "touser@" + DEFAULT_DOMAIN;
+    private static final String CUSTOM_REPOSITORY_PREFIX = "file://var/mail/custom/";
+
+    @Rule
+    public TemporaryFolder temporaryFolder = new TemporaryFolder();
+    @Rule
+    public IMAPMessageReader imapMessageReader = new IMAPMessageReader();
+    @Rule
+    public SMTPMessageSender messageSender = new SMTPMessageSender(DEFAULT_DOMAIN);
+
+    private TemporaryJamesServer jamesServer;
+    private MailRepositoryProbeImpl probe;
+
+    @Before
+    public void setup() throws Exception {
+        MailetContainer.Builder mailetContainer = TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+            .putProcessor(ProcessorConfiguration.root()
+                .addMailet(MailetConfiguration.builder()
+                    .matcher(All.class)
+                    .mailet(ToSenderDomainRepository.class)
+                    .addProperty("urlPrefix", CUSTOM_REPOSITORY_PREFIX)));
+
+        jamesServer = TemporaryJamesServer.builder()
+            .withMailetContainer(mailetContainer)
+            .build(temporaryFolder);
+
+        DataProbe dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DEFAULT_DOMAIN);
+        dataProbe.addUser(RECIPIENT, PASSWORD);
+
+        probe = jamesServer.getProbe(MailRepositoryProbeImpl.class);
+    }
+
+    @After
+    public void tearDown() {
+        jamesServer.shutdown();
+    }
+
+    @Test
+    public void incomingMailShouldBeStoredInCorrespondingMailRepository() throws Exception {
+        messageSender.connect(LOCALHOST_IP, SMTP_PORT)
+            .sendMessage(RECIPIENT, RECIPIENT);
+
+        awaitAtMostOneMinute.until(
+            () -> probe.getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 1);
+    }
+
+    @Test
+    public void incomingMailsShouldBeStoredInCorrespondingMailRepository() throws Exception {
+        messageSender.connect(LOCALHOST_IP, SMTP_PORT)
+            .sendMessage(RECIPIENT, RECIPIENT)
+            .sendMessage(RECIPIENT, RECIPIENT);
+
+        awaitAtMostOneMinute.until(
+            () -> probe.getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 2);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/adfcf46d/server/mailet/mailets/pom.xml
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/pom.xml b/server/mailet/mailets/pom.xml
index fdbe73a..eb72017 100644
--- a/server/mailet/mailets/pom.xml
+++ b/server/mailet/mailets/pom.xml
@@ -113,6 +113,12 @@
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-data-library</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>james-server-data-memory</artifactId>
             <scope>test</scope>
         </dependency>
@@ -140,6 +146,11 @@
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-mailrepository-memory</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>james-server-queue-api</artifactId>
         </dependency>
         <dependency>
@@ -192,11 +203,6 @@
             <artifactId>joda-time</artifactId>
         </dependency>
         <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
         </dependency>
@@ -230,6 +236,21 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-launcher</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.vintage</groupId>
+            <artifactId>junit-vintage-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/adfcf46d/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
new file mode 100644
index 0000000..b86482e
--- /dev/null
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
@@ -0,0 +1,89 @@
+/****************************************************************
+ * 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.transport.mailets;
+
+import java.util.Optional;
+
+import javax.inject.Inject;
+import javax.mail.MessagingException;
+
+import org.apache.james.mailrepository.api.MailRepositoryStore;
+import org.apache.mailet.Mail;
+import org.apache.mailet.base.GenericMailet;
+
+/**
+ * Stores incoming Mail in a repository defined by the sender's domain.<br>
+ *
+ * Supported configuration parameters:
+ *
+ *  - "urlPrefix" mandatory: defines the prefix for the per sender's domain repository.
+ *  For example for the value 'cassandra://var/mail/sendersRepositories/', a mail sent by 'user@james.org'
+ *  will be stored in 'cassandra://var/mail/sendersRepositories/james.org'.
+ *  - "passThrough" optional, defaults to false. If true, the processing of the mail continues. If false it stops.
+ *
+ *  Example:
+ *
+ * &lt;mailet matcher="All" class="ToSenderDomainRepository"&gt;
+ *     &lt;urlPrefix&gt;cassandra://var/mail/sendersRepositories/&lt;/urlPrefix&gt;
+ *     &lt;passThrough&gt;false&lt;/passThrough&gt;
+ * &lt;/mailet&gt;
+ */
+public class ToSenderDomainRepository extends GenericMailet {
+
+    private static final boolean DEFAULT_CONSUME = false;
+
+    private final MailRepositoryStore mailRepositoryStore;
+    private String urlPrefix;
+    private boolean passThrough;
+
+    @Inject
+    public ToSenderDomainRepository(MailRepositoryStore mailRepositoryStore) {
+        this.mailRepositoryStore = mailRepositoryStore;
+    }
+
+    @Override
+    public void init() throws MessagingException {
+        urlPrefix = Optional.ofNullable(getInitParameter("urlPrefix"))
+            .orElseThrow(() -> new MessagingException("'urlPrefix' is a mandatory configuration property"));
+        passThrough = getInitParameter("passThrough", DEFAULT_CONSUME);
+    }
+
+    @Override
+    public void service(Mail mail) throws MessagingException {
+        String url = urlPrefix + mail.getSender().getDomain().asString();
+        store(mail, url);
+        if (!passThrough) {
+            mail.setState(Mail.GHOST);
+        }
+    }
+
+    private void store(Mail mail, String url) throws MessagingException {
+        try {
+            mailRepositoryStore.select(url).store(mail);
+        } catch (MailRepositoryStore.MailRepositoryStoreException e) {
+            throw new MessagingException("Error while selecting url " + url, e);
+        }
+    }
+
+    @Override
+    public String getMailetInfo() {
+        return "ToSenderDomainRepository Mailet";
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/adfcf46d/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
new file mode 100644
index 0000000..e532e90
--- /dev/null
+++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
@@ -0,0 +1,195 @@
+/****************************************************************
+ * 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.transport.mailets;
+
+import static org.apache.mailet.base.MailAddressFixture.JAMES_LOCAL;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import javax.mail.MessagingException;
+
+import org.apache.james.mailrepository.api.MailRepository;
+import org.apache.james.mailrepository.api.MailRepositoryStore;
+import org.apache.james.mailrepository.memory.MemoryMailRepository;
+import org.apache.james.mailrepository.mock.MockMailRepositoryStore;
+import org.apache.mailet.Mail;
+import org.apache.mailet.base.MailAddressFixture;
+import org.apache.mailet.base.test.FakeMail;
+import org.apache.mailet.base.test.FakeMailetConfig;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class ToSenderDomainRepositoryTest {
+
+    private static final FakeMailetConfig DEFAULT_MAILET_CONFIG = FakeMailetConfig.builder()
+        .mailetName("TestConfig")
+        .setProperty("urlPrefix", "memory://var/mail/dlp/")
+        .build();
+    private ToSenderDomainRepository mailet;
+    private MockMailRepositoryStore mailRepositoryStore;
+
+    @BeforeEach
+    void setup() {
+        mailRepositoryStore = new MockMailRepositoryStore();
+        mailRepositoryStore.add("memory://var/mail/dlp/" + JAMES_LOCAL, new MemoryMailRepository());
+        mailet = new ToSenderDomainRepository(mailRepositoryStore);
+    }
+
+    @Test
+    void initShouldThrowExceptionWhenUrlPrefixIsAbsent() {
+        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+            .mailetName("Test")
+            .build();
+
+        assertThatThrownBy(() -> mailet.init(mailetConfig))
+            .isInstanceOf(MessagingException.class);
+    }
+
+    @Test
+    void initShouldNotThrowWhenUrlPrefixIsPresent() throws MessagingException {
+        mailet.init(DEFAULT_MAILET_CONFIG);
+    }
+
+    @Test
+    void serviceShouldStoreMailInRepository() throws Exception {
+        mailet.init(DEFAULT_MAILET_CONFIG);
+
+        String mailName = "mailName";
+        mailet.service(FakeMail.builder()
+            .name(mailName)
+            .sender(MailAddressFixture.SENDER)
+            .build());
+
+        MailRepository mailRepository = mailRepositoryStore.select("memory://var/mail/dlp/" + JAMES_LOCAL);
+
+        assertThat(mailRepository.list())
+            .extracting(mailRepository::retrieve)
+            .extracting(Mail::getName)
+            .containsOnly(mailName);
+    }
+
+    @Test
+    void serviceShouldGhostMailWhenNotPassThrough() throws Exception {
+        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+            .mailetName("TestConfig")
+            .setProperty("passThrough", "false")
+            .setProperty("urlPrefix", "memory://var/mail/dlp/")
+            .build();
+        mailet.init(mailetConfig);
+
+        FakeMail mail = FakeMail.builder()
+            .name("mailName")
+            .sender(MailAddressFixture.SENDER)
+            .state(Mail.DEFAULT)
+            .build();
+
+        mailet.service(mail);
+
+        assertThat(mail.getState())
+            .isEqualTo(Mail.GHOST);
+    }
+
+    @Test
+    void serviceShouldPreserveMailStateWhenPassThrough() throws Exception {
+        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+            .mailetName("TestConfig")
+            .setProperty("passThrough", "true")
+            .setProperty("urlPrefix", "memory://var/mail/dlp/")
+            .build();
+        mailet.init(mailetConfig);
+
+        FakeMail mail = FakeMail.builder()
+            .name("mailName")
+            .sender(MailAddressFixture.SENDER)
+            .state(Mail.DEFAULT)
+            .build();
+
+        mailet.service(mail);
+
+        assertThat(mail.getState())
+            .isEqualTo(Mail.DEFAULT);
+    }
+
+    @Test
+    void passThroughShouldDefaultToFalse() throws Exception {
+        mailet.init(DEFAULT_MAILET_CONFIG);
+
+        FakeMail mail = FakeMail.builder()
+            .name("mailName")
+            .sender(MailAddressFixture.SENDER)
+            .state(Mail.DEFAULT)
+            .build();
+
+        mailet.service(mail);
+
+        assertThat(mail.getState())
+            .isEqualTo(Mail.GHOST);
+    }
+
+    @Test
+    void initShouldSetNotPassThroughWhenPassThroughIsNotSet() throws Exception {
+        MailRepositoryStore mailRepositoryStore = mock(MailRepositoryStore.class);
+        ToSenderDomainRepository mailet = new ToSenderDomainRepository(mailRepositoryStore);
+        when(mailRepositoryStore.select(any()))
+            .thenThrow(new MailRepositoryStore.MailRepositoryStoreException("any"));
+
+        mailet.init(DEFAULT_MAILET_CONFIG);
+
+        FakeMail mail = FakeMail.builder()
+            .name("mailName")
+            .sender(MailAddressFixture.SENDER)
+            .state(Mail.DEFAULT)
+            .build();
+
+        assertThatThrownBy(() -> mailet.service(mail))
+            .isInstanceOf(MessagingException.class);
+    }
+
+    @Test
+    void initShouldSetNotPassThroughWhenPassThroughIsNotBoolean() throws Exception {
+        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+            .mailetName("TestConfig")
+            .setProperty("urlPrefix", "memory://var/mail/dlp/")
+            .setProperty("passThrough", "not boolean")
+            .build();
+
+        mailet.init(mailetConfig);
+
+        FakeMail mail = FakeMail.builder()
+            .name("mailName")
+            .sender(MailAddressFixture.SENDER)
+            .state(Mail.DEFAULT)
+            .build();
+
+        mailet.service(mail);
+
+        assertThat(mail.getState())
+            .isEqualTo(Mail.GHOST);
+    }
+
+    @Test
+    void getMailetInfoShouldReturnExpectedResult() {
+        assertThat(mailet.getMailetInfo())
+            .isEqualTo("ToSenderDomainRepository Mailet");
+    }
+}


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


[2/8] james-project git commit: JAMES-2415 remove some test dependencies

Posted by bt...@apache.org.
JAMES-2415 remove some test dependencies


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

Branch: refs/heads/master
Commit: a6d58e413d5cef2f28a954e2ee98fb4b804ec225
Parents: 257eae5
Author: Matthieu Baechler <ma...@apache.org>
Authored: Wed Jun 6 17:35:23 2018 +0200
Committer: benwa <bt...@linagora.com>
Committed: Wed Jun 13 09:41:33 2018 +0700

----------------------------------------------------------------------
 server/container/filesystem-api/pom.xml                    | 1 +
 server/container/guice/jpa-smtp/pom.xml                    | 1 +
 server/container/guice/mailbox-plugin-spamassassin/pom.xml | 5 +++++
 server/container/guice/mailbox/pom.xml                     | 5 +++++
 4 files changed, 12 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/a6d58e41/server/container/filesystem-api/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/filesystem-api/pom.xml b/server/container/filesystem-api/pom.xml
index 6391a76..3874fa6 100644
--- a/server/container/filesystem-api/pom.xml
+++ b/server/container/filesystem-api/pom.xml
@@ -49,6 +49,7 @@
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.assertj</groupId>

http://git-wip-us.apache.org/repos/asf/james-project/blob/a6d58e41/server/container/guice/jpa-smtp/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/jpa-smtp/pom.xml b/server/container/guice/jpa-smtp/pom.xml
index 6097cbd..07e5ce0 100644
--- a/server/container/guice/jpa-smtp/pom.xml
+++ b/server/container/guice/jpa-smtp/pom.xml
@@ -104,6 +104,7 @@
         <dependency>
             <groupId>com.jayway.awaitility</groupId>
             <artifactId>awaitility</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>com.jayway.restassured</groupId>

http://git-wip-us.apache.org/repos/asf/james-project/blob/a6d58e41/server/container/guice/mailbox-plugin-spamassassin/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/mailbox-plugin-spamassassin/pom.xml b/server/container/guice/mailbox-plugin-spamassassin/pom.xml
index ce12d12..a3f75a2 100644
--- a/server/container/guice/mailbox-plugin-spamassassin/pom.xml
+++ b/server/container/guice/mailbox-plugin-spamassassin/pom.xml
@@ -53,6 +53,11 @@
             <artifactId>commons-configuration</artifactId>
         </dependency>
         <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.assertj</groupId>
             <artifactId>assertj-core</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/a6d58e41/server/container/guice/mailbox/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/mailbox/pom.xml b/server/container/guice/mailbox/pom.xml
index 77c4183..51979a0 100644
--- a/server/container/guice/mailbox/pom.xml
+++ b/server/container/guice/mailbox/pom.xml
@@ -57,6 +57,11 @@
             <artifactId>guice-multibindings</artifactId>
         </dependency>
         <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.assertj</groupId>
             <artifactId>assertj-core</artifactId>
             <scope>test</scope>


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


[8/8] james-project git commit: MAILBOX-341 EventDeliver should report MailboxListener execution timings

Posted by bt...@apache.org.
MAILBOX-341 EventDeliver should report MailboxListener execution timings


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

Branch: refs/heads/master
Commit: 175f1f29c95220392ae1027c1c826353355c2e61
Parents: 72bc076
Author: benwa <bt...@linagora.com>
Authored: Tue Jun 12 10:32:11 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Wed Jun 13 09:48:48 2018 +0700

----------------------------------------------------------------------
 .../main/resources/META-INF/spring/event-system.xml   |  5 ++++-
 .../test/resources/META-INF/spring/event-alias.xml    |  2 ++
 .../store/event/AsynchronousEventDelivery.java        |  4 ++--
 .../store/event/DefaultDelegatingMailboxListener.java |  6 +++++-
 .../mailbox/store/event/SynchronousEventDelivery.java | 14 ++++++++++++++
 .../BroadcastDelegatingMailboxListener.java           |  6 +++++-
 .../RegisteredDelegatingMailboxListener.java          |  6 +++++-
 .../store/event/AsynchronousEventDeliveryTest.java    |  4 +++-
 .../mailbox/store/event/MixedEventDeliveryTest.java   | 11 +++++++----
 .../store/event/SynchronousEventDeliveryTest.java     |  3 ++-
 .../james/modules/mailbox/DefaultEventModule.java     |  8 +++++---
 11 files changed, 54 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/175f1f29/mailbox/spring/src/main/resources/META-INF/spring/event-system.xml
----------------------------------------------------------------------
diff --git a/mailbox/spring/src/main/resources/META-INF/spring/event-system.xml b/mailbox/spring/src/main/resources/META-INF/spring/event-system.xml
index e64f0b7..4e04252 100644
--- a/mailbox/spring/src/main/resources/META-INF/spring/event-system.xml
+++ b/mailbox/spring/src/main/resources/META-INF/spring/event-system.xml
@@ -71,12 +71,15 @@
         <constructor-arg index="0" ref="mailbox-id-deserializer"/>
     </bean>
 
-    <bean id="synchronous-event-delivery" class="org.apache.james.mailbox.store.event.SynchronousEventDelivery" lazy-init="true"/>
+    <bean id="synchronous-event-delivery" class="org.apache.james.mailbox.store.event.SynchronousEventDelivery" lazy-init="true">
+        <constructor-arg index="0" ref="metricFactory"/>
+    </bean>
 
     <bean id="event-registry" class="org.apache.james.mailbox.store.event.MailboxListenerRegistry"/>
 
     <bean id="asynchronous-event-delivery" class="org.apache.james.mailbox.store.event.AsynchronousEventDelivery" lazy-init="true">
         <constructor-arg index="0" ref="${event.delivery.thread.count}"/>
+        <constructor-arg index="1" ref="synchronous-event-delivery"/>
     </bean>
 
     <bean id="mixed-event-delivery" class="org.apache.james.mailbox.store.event.MixedEventDelivery" lazy-init="true">

http://git-wip-us.apache.org/repos/asf/james-project/blob/175f1f29/mailbox/spring/src/test/resources/META-INF/spring/event-alias.xml
----------------------------------------------------------------------
diff --git a/mailbox/spring/src/test/resources/META-INF/spring/event-alias.xml b/mailbox/spring/src/test/resources/META-INF/spring/event-alias.xml
index fb3cace..7406b84 100644
--- a/mailbox/spring/src/test/resources/META-INF/spring/event-alias.xml
+++ b/mailbox/spring/src/test/resources/META-INF/spring/event-alias.xml
@@ -29,4 +29,6 @@
         <constructor-arg index="0" ref="delegating-listener"/>
     </bean>
 
+    <bean id="metricFactory" class="org.apache.james.metrics.api.NoopMetricFactory"/>
+
 </beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/175f1f29/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/AsynchronousEventDelivery.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/AsynchronousEventDelivery.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/AsynchronousEventDelivery.java
index 98a43ab..9ca9824 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/AsynchronousEventDelivery.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/AsynchronousEventDelivery.java
@@ -32,9 +32,9 @@ public class AsynchronousEventDelivery implements EventDelivery {
     private final ExecutorService threadPoolExecutor;
     private final SynchronousEventDelivery synchronousEventDelivery;
 
-    public AsynchronousEventDelivery(int threadPoolSize) {
+    public AsynchronousEventDelivery(int threadPoolSize, SynchronousEventDelivery synchronousEventDelivery) {
         this.threadPoolExecutor = Executors.newFixedThreadPool(threadPoolSize);
-        this.synchronousEventDelivery = new SynchronousEventDelivery();
+        this.synchronousEventDelivery = synchronousEventDelivery;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/175f1f29/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/DefaultDelegatingMailboxListener.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/DefaultDelegatingMailboxListener.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/DefaultDelegatingMailboxListener.java
index 43a236c..a380304 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/DefaultDelegatingMailboxListener.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/DefaultDelegatingMailboxListener.java
@@ -28,6 +28,9 @@ import org.apache.james.mailbox.MailboxListener;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.metrics.api.NoopMetricFactory;
+
+import com.google.common.annotations.VisibleForTesting;
 
 /**
  * Receive a {@link org.apache.james.mailbox.MailboxListener.MailboxEvent} and delegate it to an other
@@ -45,8 +48,9 @@ public class DefaultDelegatingMailboxListener implements DelegatingMailboxListen
         return ListenerType.EACH_NODE;
     }
 
+    @VisibleForTesting
     public DefaultDelegatingMailboxListener() {
-        this(new SynchronousEventDelivery(),
+        this(new SynchronousEventDelivery(new NoopMetricFactory()),
             new MailboxListenerRegistry());
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/175f1f29/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/SynchronousEventDelivery.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/SynchronousEventDelivery.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/SynchronousEventDelivery.java
index 97112de..df52819 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/SynchronousEventDelivery.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/SynchronousEventDelivery.java
@@ -19,8 +19,12 @@
 
 package org.apache.james.mailbox.store.event;
 
+import javax.inject.Inject;
+
 import org.apache.james.mailbox.Event;
 import org.apache.james.mailbox.MailboxListener;
+import org.apache.james.metrics.api.MetricFactory;
+import org.apache.james.metrics.api.TimeMetric;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -28,14 +32,24 @@ public class SynchronousEventDelivery implements EventDelivery {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(SynchronousEventDelivery.class);
 
+    private final MetricFactory metricFactory;
+
+    @Inject
+    public SynchronousEventDelivery(MetricFactory metricFactory) {
+        this.metricFactory = metricFactory;
+    }
+
     @Override
     public void deliver(MailboxListener mailboxListener, Event event) {
+        TimeMetric timer = metricFactory.timer("mailbox-listener-" + mailboxListener.getClass().getSimpleName());
         try {
             mailboxListener.event(event);
         } catch (Throwable throwable) {
             LOGGER.error("Error while processing listener {} for {}",
                     mailboxListener.getClass().getCanonicalName(), event.getClass().getCanonicalName(),
                     throwable);
+        } finally {
+            timer.stopAndPublish();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/175f1f29/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/distributed/BroadcastDelegatingMailboxListener.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/distributed/BroadcastDelegatingMailboxListener.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/distributed/BroadcastDelegatingMailboxListener.java
index 74fd142..2171e80 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/distributed/BroadcastDelegatingMailboxListener.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/distributed/BroadcastDelegatingMailboxListener.java
@@ -33,9 +33,12 @@ import org.apache.james.mailbox.store.event.SynchronousEventDelivery;
 import org.apache.james.mailbox.store.publisher.MessageConsumer;
 import org.apache.james.mailbox.store.publisher.Publisher;
 import org.apache.james.mailbox.store.publisher.Topic;
+import org.apache.james.metrics.api.NoopMetricFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.annotations.VisibleForTesting;
+
 public class BroadcastDelegatingMailboxListener implements DistributedDelegatingMailboxListener {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(BroadcastDelegatingMailboxListener.class);
@@ -60,11 +63,12 @@ public class BroadcastDelegatingMailboxListener implements DistributedDelegating
         messageConsumer.init(this.globalTopic);
     }
 
+    @VisibleForTesting
     public BroadcastDelegatingMailboxListener(Publisher publisher,
                                               MessageConsumer messageConsumer,
                                               EventSerializer eventSerializer,
                                               String globalTopic) throws Exception {
-        this(publisher, messageConsumer, eventSerializer, new SynchronousEventDelivery(), globalTopic);
+        this(publisher, messageConsumer, eventSerializer, new SynchronousEventDelivery(new NoopMetricFactory()), globalTopic);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/175f1f29/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/distributed/RegisteredDelegatingMailboxListener.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/distributed/RegisteredDelegatingMailboxListener.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/distributed/RegisteredDelegatingMailboxListener.java
index 383da95..8165536 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/distributed/RegisteredDelegatingMailboxListener.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/distributed/RegisteredDelegatingMailboxListener.java
@@ -34,9 +34,12 @@ import org.apache.james.mailbox.store.event.SynchronousEventDelivery;
 import org.apache.james.mailbox.store.publisher.MessageConsumer;
 import org.apache.james.mailbox.store.publisher.Publisher;
 import org.apache.james.mailbox.store.publisher.Topic;
+import org.apache.james.metrics.api.NoopMetricFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.annotations.VisibleForTesting;
+
 public class RegisteredDelegatingMailboxListener implements DistributedDelegatingMailboxListener {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(RegisteredDelegatingMailboxListener.class);
@@ -61,11 +64,12 @@ public class RegisteredDelegatingMailboxListener implements DistributedDelegatin
         messageConsumer.init(mailboxPathRegister.getLocalTopic());
     }
 
+    @VisibleForTesting
     public RegisteredDelegatingMailboxListener(EventSerializer eventSerializer,
                                                Publisher publisher,
                                                MessageConsumer messageConsumer,
                                                MailboxPathRegister mailboxPathRegister) throws Exception {
-        this(eventSerializer, publisher, messageConsumer, mailboxPathRegister, new SynchronousEventDelivery());
+        this(eventSerializer, publisher, messageConsumer, mailboxPathRegister, new SynchronousEventDelivery(new NoopMetricFactory()));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/175f1f29/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/AsynchronousEventDeliveryTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/AsynchronousEventDeliveryTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/AsynchronousEventDeliveryTest.java
index a072bbf..1fbe4d7 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/AsynchronousEventDeliveryTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/AsynchronousEventDeliveryTest.java
@@ -28,6 +28,7 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.james.mailbox.MailboxListener;
 import org.apache.james.mailbox.mock.MockMailboxSession;
+import org.apache.james.metrics.api.NoopMetricFactory;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -41,7 +42,8 @@ public class AsynchronousEventDeliveryTest {
     @Before
     public void setUp() {
         mailboxListener = mock(MailboxListener.class);
-        asynchronousEventDelivery = new AsynchronousEventDelivery(2);
+        asynchronousEventDelivery = new AsynchronousEventDelivery(2,
+            new SynchronousEventDelivery(new NoopMetricFactory()));
     }
 
     @After

http://git-wip-us.apache.org/repos/asf/james-project/blob/175f1f29/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/MixedEventDeliveryTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/MixedEventDeliveryTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/MixedEventDeliveryTest.java
index 08dacee..5a6dc92 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/MixedEventDeliveryTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/MixedEventDeliveryTest.java
@@ -29,6 +29,7 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.james.mailbox.MailboxListener;
+import org.apache.james.metrics.api.NoopMetricFactory;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -44,7 +45,9 @@ public class MixedEventDeliveryTest {
     @Before
     public void setUp() {
         listener = mock(MailboxListener.class);
-        mixedEventDelivery = new MixedEventDelivery(new AsynchronousEventDelivery(2), new SynchronousEventDelivery());
+        SynchronousEventDelivery synchronousEventDelivery = new SynchronousEventDelivery(new NoopMetricFactory());
+        AsynchronousEventDelivery asynchronousEventDelivery = new AsynchronousEventDelivery(2, synchronousEventDelivery);
+        mixedEventDelivery = new MixedEventDelivery(asynchronousEventDelivery, synchronousEventDelivery);
     }
 
     @After
@@ -53,7 +56,7 @@ public class MixedEventDeliveryTest {
     }
 
     @Test
-    public void deliverShouldWorkOnSynchronousListeners() throws Exception {
+    public void deliverShouldWorkOnSynchronousListeners() {
         when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.SYNCHRONOUS);
         MailboxListener.MailboxEvent event = new MailboxListener.MailboxEvent(null, null) {};
         mixedEventDelivery.deliver(listener, event);
@@ -61,7 +64,7 @@ public class MixedEventDeliveryTest {
     }
 
     @Test
-    public void deliverShouldEventuallyDeliverOnAsynchronousListeners() throws Exception {
+    public void deliverShouldEventuallyDeliverOnAsynchronousListeners() {
         MailboxListener.MailboxEvent event = new MailboxListener.MailboxEvent(null, null) {};
         when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
         mixedEventDelivery.deliver(listener, event);
@@ -69,7 +72,7 @@ public class MixedEventDeliveryTest {
     }
 
     @Test(timeout = ONE_MINUTE)
-    public void deliverShouldNotBlockOnAsynchronousListeners() throws Exception {
+    public void deliverShouldNotBlockOnAsynchronousListeners() {
         MailboxListener.MailboxEvent event = new MailboxListener.MailboxEvent(null, null) {};
         when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
         final CountDownLatch latch = new CountDownLatch(1);

http://git-wip-us.apache.org/repos/asf/james-project/blob/175f1f29/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/SynchronousEventDeliveryTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/SynchronousEventDeliveryTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/SynchronousEventDeliveryTest.java
index 5b5137a..85bc13f 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/SynchronousEventDeliveryTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/SynchronousEventDeliveryTest.java
@@ -25,6 +25,7 @@ import static org.mockito.Mockito.verify;
 
 import org.apache.james.mailbox.MailboxListener;
 import org.apache.james.mailbox.mock.MockMailboxSession;
+import org.apache.james.metrics.api.NoopMetricFactory;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -36,7 +37,7 @@ public class SynchronousEventDeliveryTest {
     @Before
     public void setUp() {
         mailboxListener = mock(MailboxListener.class);
-        synchronousEventDelivery = new SynchronousEventDelivery();
+        synchronousEventDelivery = new SynchronousEventDelivery(new NoopMetricFactory());
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/james-project/blob/175f1f29/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultEventModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultEventModule.java b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultEventModule.java
index b788ed9..835eccc 100644
--- a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultEventModule.java
+++ b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultEventModule.java
@@ -36,6 +36,7 @@ import org.apache.james.mailbox.store.event.MailboxListenerRegistry;
 import org.apache.james.mailbox.store.event.MixedEventDelivery;
 import org.apache.james.mailbox.store.event.SynchronousEventDelivery;
 import org.apache.james.mailbox.store.quota.ListeningCurrentQuotaUpdater;
+import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.ConfigurationPerformer;
 
@@ -69,12 +70,13 @@ public class DefaultEventModule extends AbstractModule {
 
     @Provides
     @Singleton
-    EventDelivery provideEventDelivery(ConfigurationProvider configurationProvider) {
+    EventDelivery provideEventDelivery(ConfigurationProvider configurationProvider, MetricFactory metricFactory) {
         int poolSize = retrievePoolSize(configurationProvider);
 
+        SynchronousEventDelivery synchronousEventDelivery = new SynchronousEventDelivery(metricFactory);
         return new MixedEventDelivery(
-            new AsynchronousEventDelivery(poolSize),
-            new SynchronousEventDelivery());
+            new AsynchronousEventDelivery(poolSize, synchronousEventDelivery),
+            synchronousEventDelivery);
     }
 
     private int retrievePoolSize(ConfigurationProvider configurationProvider) {


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


[5/8] james-project git commit: JAMES-2413 Allow to use DataProbeImpl in a fluent fashion

Posted by bt...@apache.org.
JAMES-2413 Allow to use DataProbeImpl in a fluent fashion


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

Branch: refs/heads/master
Commit: be9462075d2435cea903c6c57f5c4fda933ca4d1
Parents: adfcf46
Author: benwa <bt...@linagora.com>
Authored: Thu Jun 7 10:51:10 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Wed Jun 13 09:42:35 2018 +0700

----------------------------------------------------------------------
 .../james/cli/DataCommandsIntegrationTest.java      |  8 ++++----
 .../CassandraMailRepositoryIntegrationTest.java     |  7 ++++---
 .../test/java/org/apache/james/ESReporterTest.java  |  6 +++---
 .../java/org/apache/james/utils/DataProbeImpl.java  | 15 ++++++++++++---
 .../java/org/apache/james/JPAJamesServerTest.java   |  6 +++---
 .../mailets/crypto/SMIMEDecryptIntegrationTest.java |  6 +++---
 .../transport/mailets/ContactExtractorTest.java     | 16 ++++++++--------
 .../james/transport/mailets/SpamAssassinTest.java   | 10 +++++-----
 .../apache/james/jmap/JMAPAuthenticationTest.java   |  5 +++--
 .../org/apache/james/jmap/ProvisioningTest.java     |  6 +++---
 .../integration/SetVacationResponseTest.java        |  5 +++--
 .../methods/integration/SpamAssassinContract.java   | 11 ++++++-----
 12 files changed, 57 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/be946207/server/container/cli-integration/src/test/java/org/apache/james/cli/DataCommandsIntegrationTest.java
----------------------------------------------------------------------
diff --git a/server/container/cli-integration/src/test/java/org/apache/james/cli/DataCommandsIntegrationTest.java b/server/container/cli-integration/src/test/java/org/apache/james/cli/DataCommandsIntegrationTest.java
index ed5a446..eeddbd0 100644
--- a/server/container/cli-integration/src/test/java/org/apache/james/cli/DataCommandsIntegrationTest.java
+++ b/server/container/cli-integration/src/test/java/org/apache/james/cli/DataCommandsIntegrationTest.java
@@ -109,8 +109,8 @@ public class DataCommandsIntegrationTest {
 
     @Test
     public void removeUserShouldWork() throws Exception {
-        dataProbe.addDomain(DOMAIN);
-        dataProbe.addUser(MAIL_ADDRESS, PASSWORD);
+        dataProbe.fluentAddDomain(DOMAIN)
+            .fluentAddUser(MAIL_ADDRESS, PASSWORD);
 
         ServerCmd.doMain(new String[] {"-h", "127.0.0.1", "-p", "9999", "REMOVEUSER", MAIL_ADDRESS});
 
@@ -119,8 +119,8 @@ public class DataCommandsIntegrationTest {
 
     @Test
     public void listUsersShouldWork() throws Exception {
-        dataProbe.addDomain(DOMAIN);
-        dataProbe.addUser(MAIL_ADDRESS, PASSWORD);
+        dataProbe.fluentAddDomain(DOMAIN)
+            .fluentAddUser(MAIL_ADDRESS, PASSWORD);
 
         ServerCmd.executeAndOutputToStream(new String[] {"-h", "127.0.0.1", "-p", "9999", "listusers"}, outputCapture.getPrintStream());
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/be946207/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraMailRepositoryIntegrationTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraMailRepositoryIntegrationTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraMailRepositoryIntegrationTest.java
index 3d5db0c..836e27d 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraMailRepositoryIntegrationTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraMailRepositoryIntegrationTest.java
@@ -59,14 +59,15 @@ public class CassandraMailRepositoryIntegrationTest {
     }
 
     @After
-    public void tearDown() throws Exception {
+    public void tearDown() {
         server.stop();
     }
 
     @Test
     public void deniedSenderMailShouldBeStoredInCassandraMailRepositoryWhenConfigured() throws Exception {
-        server.getProbe(DataProbeImpl.class).addDomain("domain.com");
-        server.getProbe(DataProbeImpl.class).addUser("user@domain.com", "secret");
+        server.getProbe(DataProbeImpl.class)
+            .fluentAddDomain("domain.com")
+            .fluentAddUser("user@domain.com", "secret");
 
         smtpMessageSender.connect("127.0.0.1", 1025)
             .sendMessage("denied@other.com", "user@domain.com");

http://git-wip-us.apache.org/repos/asf/james-project/blob/be946207/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java
index a020a49..148c42c 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java
@@ -77,9 +77,9 @@ public class ESReporterTest {
     public void setup() throws Exception {
         server = cassandraJmap.jmapServer();
         server.start();
-        DataProbeImpl serverProbe = server.getProbe(DataProbeImpl.class);
-        serverProbe.addDomain(DOMAIN);
-        serverProbe.addUser(USERNAME, PASSWORD);
+        server.getProbe(DataProbeImpl.class)
+            .fluentAddDomain(DOMAIN)
+            .fluentAddUser(USERNAME, PASSWORD);
 
         RestAssured.requestSpecification = new RequestSpecBuilder()
                 .setContentType(ContentType.JSON)

http://git-wip-us.apache.org/repos/asf/james-project/blob/be946207/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java
index c5cab72..f016129 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java
@@ -58,13 +58,18 @@ public class DataProbeImpl implements GuiceProbe, DataProbe {
         usersRepository.addUser(userName, password);
     }
 
+    public DataProbeImpl fluentAddUser(String userName, String password) throws Exception {
+        addUser(userName, password);
+        return this;
+    }
+
     @Override
     public void removeUser(String username) throws Exception {
         usersRepository.removeUser(username);
     }
 
     @Override
-    public void setPassword(String userName, String password) throws Exception {
+    public void setPassword(String userName, String password) {
         throw new NotImplementedException();
     }
 
@@ -78,6 +83,10 @@ public class DataProbeImpl implements GuiceProbe, DataProbe {
         domainList.addDomain(Domain.of(domain));
     }
 
+    public DataProbeImpl fluentAddDomain(String domain) throws Exception {
+        addDomain(domain);
+        return this;
+    }
 
     @Override
     public boolean containsDomain(String domain) throws Exception {
@@ -107,12 +116,12 @@ public class DataProbeImpl implements GuiceProbe, DataProbe {
             .collect(
                 Guavate.toImmutableMap(
                     entry -> entry.getKey().asString(),
-                    entry -> entry.getValue()));
+                    Map.Entry::getValue));
 
     }
 
     @Override
-    public Mappings listUserDomainMappings(String user, String domain) throws Exception {
+    public Mappings listUserDomainMappings(String user, String domain) {
         throw new NotImplementedException();
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/be946207/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerTest.java b/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerTest.java
index 114b060..e07727b 100644
--- a/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerTest.java
+++ b/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerTest.java
@@ -77,9 +77,9 @@ public class JPAJamesServerTest extends AbstractJamesServerTest {
 
     @Test
     public void jpaGuiceServerShouldUpdateQuota() throws Exception {
-        DataProbeImpl dataProbe = server.getProbe(DataProbeImpl.class);
-        dataProbe.addDomain(DOMAIN);
-        dataProbe.addUser(USER, PASSWORD);
+        server.getProbe(DataProbeImpl.class)
+            .fluentAddDomain(DOMAIN)
+            .fluentAddUser(USER, PASSWORD);
         server.getProbe(QuotaProbesImpl.class).setGlobalMaxStorage(new SerializableQuotaValue<>(QuotaSize.size(50 * 1024)));
 
         // ~ 12 KB email

http://git-wip-us.apache.org/repos/asf/james-project/blob/be946207/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/crypto/SMIMEDecryptIntegrationTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/crypto/SMIMEDecryptIntegrationTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/crypto/SMIMEDecryptIntegrationTest.java
index 554e0d5..ba91794 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/crypto/SMIMEDecryptIntegrationTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/crypto/SMIMEDecryptIntegrationTest.java
@@ -84,9 +84,9 @@ public class SMIMEDecryptIntegrationTest {
             .withMailetContainer(mailetContainer)
             .build(temporaryFolder);
 
-        DataProbeImpl serverProbe = jamesServer.getProbe(DataProbeImpl.class);
-        serverProbe.addDomain(DEFAULT_DOMAIN);
-        serverProbe.addUser(FROM, PASSWORD);
+        jamesServer.getProbe(DataProbeImpl.class)
+            .fluentAddDomain(DEFAULT_DOMAIN)
+            .fluentAddUser(FROM, PASSWORD);
     }
 
     @After

http://git-wip-us.apache.org/repos/asf/james-project/blob/be946207/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ContactExtractorTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ContactExtractorTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ContactExtractorTest.java
index 800a5de..c29535f 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ContactExtractorTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ContactExtractorTest.java
@@ -101,14 +101,14 @@ public class ContactExtractorTest {
             .build(folder);
 
         DataProbeImpl probe = jamesServer.getProbe(DataProbeImpl.class);
-        probe.addDomain(DEFAULT_DOMAIN);
-        probe.addUser(SENDER, PASSWORD);
-        probe.addUser(TO, PASSWORD);
-        probe.addUser(TO2, PASSWORD);
-        probe.addUser(CC, PASSWORD);
-        probe.addUser(CC2, PASSWORD);
-        probe.addUser(BCC, PASSWORD);
-        probe.addUser(BCC2, PASSWORD);
+        probe.fluentAddDomain(DEFAULT_DOMAIN)
+            .fluentAddUser(SENDER, PASSWORD)
+            .fluentAddUser(TO, PASSWORD)
+            .fluentAddUser(TO2, PASSWORD)
+            .fluentAddUser(CC, PASSWORD)
+            .fluentAddUser(CC2, PASSWORD)
+            .fluentAddUser(BCC, PASSWORD)
+            .fluentAddUser(BCC2, PASSWORD);
     }
 
     @After

http://git-wip-us.apache.org/repos/asf/james-project/blob/be946207/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/SpamAssassinTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/SpamAssassinTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/SpamAssassinTest.java
index 274b0e8..3c56362 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/SpamAssassinTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/SpamAssassinTest.java
@@ -86,11 +86,11 @@ public class SpamAssassinTest {
             .withMailetContainer(mailets)
             .build(temporaryFolder);
 
-        DataProbeImpl probe = jamesServer.getProbe(DataProbeImpl.class);
-        probe.addDomain(DEFAULT_DOMAIN);
-        probe.addUser(FROM, PASSWORD);
-        probe.addUser(RECIPIENT, PASSWORD);
-        probe.addUser(RECIPIENT2, PASSWORD);
+        jamesServer.getProbe(DataProbeImpl.class)
+            .fluentAddDomain(DEFAULT_DOMAIN)
+            .fluentAddUser(FROM, PASSWORD)
+            .fluentAddUser(RECIPIENT, PASSWORD)
+            .fluentAddUser(RECIPIENT2, PASSWORD);
     }
 
     @After

http://git-wip-us.apache.org/repos/asf/james-project/blob/be946207/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java
index 1631477..eae6a4c 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java
@@ -72,8 +72,9 @@ public abstract class JMAPAuthenticationTest {
 
         
         String domain = "domain.tld";
-        jmapServer.getProbe(DataProbeImpl.class).addDomain(domain);
-        jmapServer.getProbe(DataProbeImpl.class).addUser(userCredentials.getUsername(), userCredentials.getPassword());
+        jmapServer.getProbe(DataProbeImpl.class)
+            .fluentAddDomain(domain)
+            .fluentAddUser(userCredentials.getUsername(), userCredentials.getPassword());
         
     }
     

http://git-wip-us.apache.org/repos/asf/james-project/blob/be946207/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/ProvisioningTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/ProvisioningTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/ProvisioningTest.java
index 0d05796..fcb02b5 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/ProvisioningTest.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/ProvisioningTest.java
@@ -63,9 +63,9 @@ public abstract class ProvisioningTest {
             .setPort(jmapServer.getProbe(JmapGuiceProbe.class).getJmapPort())
             .build();
 
-        DataProbeImpl serverProbe = jmapServer.getProbe(DataProbeImpl.class);
-        serverProbe.addDomain(DOMAIN);
-        serverProbe.addUser(USER, PASSWORD);
+        jmapServer.getProbe(DataProbeImpl.class)
+            .fluentAddDomain(DOMAIN)
+            .fluentAddUser(USER, PASSWORD);
     }
 
     @After

http://git-wip-us.apache.org/repos/asf/james-project/blob/be946207/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetVacationResponseTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetVacationResponseTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetVacationResponseTest.java
index 4767e92..f86015c 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetVacationResponseTest.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetVacationResponseTest.java
@@ -71,8 +71,9 @@ public abstract class SetVacationResponseTest {
                 .setPort(jmapGuiceProbe.getJmapPort())
                 .build();
 
-        jmapServer.getProbe(DataProbeImpl.class).addDomain(DOMAIN);
-        jmapServer.getProbe(DataProbeImpl.class).addUser(USER, PASSWORD);
+        jmapServer.getProbe(DataProbeImpl.class)
+            .fluentAddDomain(DOMAIN)
+            .fluentAddUser(USER, PASSWORD);
         accessToken = authenticateJamesUser(baseUri(jmapServer), USER, PASSWORD);
 
         await();

http://git-wip-us.apache.org/repos/asf/james-project/blob/be946207/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SpamAssassinContract.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SpamAssassinContract.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SpamAssassinContract.java
index 5326b43..358579b 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SpamAssassinContract.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SpamAssassinContract.java
@@ -73,11 +73,12 @@ public interface SpamAssassinContract {
                 .build();
         RestAssured.defaultParser = Parser.JSON;
 
-        james.getJmapServer().getProbe(DataProbeImpl.class).addDomain(BOBS_DOMAIN);
-        james.getJmapServer().getProbe(DataProbeImpl.class).addDomain(RECIPIENTS_DOMAIN);
-        james.getJmapServer().getProbe(DataProbeImpl.class).addUser(BOB, BOB_PASSWORD);
-        james.getJmapServer().getProbe(DataProbeImpl.class).addUser(ALICE, ALICE_PASSWORD);
-        james.getJmapServer().getProbe(DataProbeImpl.class).addUser(PAUL, PAUL_PASSWORD);
+        james.getJmapServer().getProbe(DataProbeImpl.class)
+            .fluentAddDomain(BOBS_DOMAIN)
+            .fluentAddDomain(RECIPIENTS_DOMAIN)
+            .fluentAddUser(BOB, BOB_PASSWORD)
+            .fluentAddUser(ALICE, ALICE_PASSWORD)
+            .fluentAddUser(PAUL, PAUL_PASSWORD);
     }
 
     default AccessToken accessTokenFor(GuiceJamesServer james, String user, String password) {


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


[7/8] james-project git commit: JAMES-1840 Accept null user when resolving quota root.

Posted by bt...@apache.org.
JAMES-1840 Accept null user when resolving quota root.


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

Branch: refs/heads/master
Commit: 72bc076c1884dcd4c9349cc2747b3a7df3144596
Parents: 7488a2e
Author: Edgar Asatryan <ns...@gmail.com>
Authored: Fri Jun 8 21:04:25 2018 +0400
Committer: benwa <bt...@linagora.com>
Committed: Wed Jun 13 09:48:48 2018 +0700

----------------------------------------------------------------------
 .../quota/DefaultUserQuotaRootResolver.java     | 12 ++-
 .../quota/DefaultQuotaRootResolverTest.java     | 85 ------------------
 .../quota/DefaultUserQuotaRootResolverTest.java | 92 ++++++++++++++++++++
 3 files changed, 100 insertions(+), 89 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/72bc076c/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolver.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolver.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolver.java
index bbf90a2..09a55c9 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolver.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolver.java
@@ -20,6 +20,7 @@
 package org.apache.james.mailbox.store.quota;
 
 import java.util.List;
+import java.util.Optional;
 
 import javax.inject.Inject;
 
@@ -57,10 +58,13 @@ public class DefaultUserQuotaRootResolver implements UserQuotaRootResolver {
     @Override
     public QuotaRoot getQuotaRoot(MailboxPath mailboxPath) {
         Preconditions.checkArgument(!mailboxPath.getNamespace().contains(SEPARATOR), "Namespace should not contain " + SEPARATOR);
-        Preconditions.checkArgument(!mailboxPath.getUser().contains(SEPARATOR), "Username should not contain " + SEPARATOR);
-        User user = User.fromUsername(mailboxPath.getUser());
-        return QuotaRoot.quotaRoot(mailboxPath.getNamespace() + SEPARATOR + user.asString(),
-            user.getDomainPart());
+        return Optional.ofNullable(mailboxPath.getUser())
+                .map(user -> {
+                    Preconditions.checkArgument(!mailboxPath.getUser().contains(SEPARATOR), "Username should not contain " + SEPARATOR);
+                    return User.fromUsername(mailboxPath.getUser());
+                })
+                .map(user -> QuotaRoot.quotaRoot(mailboxPath.getNamespace() + SEPARATOR + user.asString(), user.getDomainPart()))
+                .orElseGet(() -> QuotaRoot.quotaRoot(mailboxPath.getNamespace(), Optional.empty()));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/72bc076c/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/DefaultQuotaRootResolverTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/DefaultQuotaRootResolverTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/DefaultQuotaRootResolverTest.java
deleted file mode 100644
index 4c855bf..0000000
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/DefaultQuotaRootResolverTest.java
+++ /dev/null
@@ -1,85 +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.mailbox.store.quota;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.Optional;
-
-import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.QuotaRoot;
-import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
-import org.apache.james.mailbox.store.mail.MailboxMapper;
-import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.collect.Lists;
-
-public class DefaultQuotaRootResolverTest {
-
-    public static final MailboxPath MAILBOX_PATH = MailboxPath.forUser("benwa", "INBOX");
-    public static final SimpleMailbox MAILBOX = new SimpleMailbox(MAILBOX_PATH, 10);
-    public static final MailboxPath PATH_LIKE = MailboxPath.forUser("benwa", "%");
-    public static final MailboxPath MAILBOX_PATH_2 = MailboxPath.forUser("benwa", "test");
-    public static final SimpleMailbox MAILBOX_2 = new SimpleMailbox(MAILBOX_PATH_2, 10);
-    public static final QuotaRoot QUOTA_ROOT = QuotaRoot.quotaRoot("#private&benwa", Optional.empty());
-
-    private DefaultUserQuotaRootResolver testee;
-    private MailboxSessionMapperFactory mockedFactory;
-
-    @Before
-    public void setUp() {
-        mockedFactory = mock(MailboxSessionMapperFactory.class);
-        testee = new DefaultUserQuotaRootResolver(mockedFactory);
-    }
-
-    @Test
-    public void getQuotaRootShouldReturnUserRelatedQuotaRoot() throws Exception {
-        assertThat(testee.getQuotaRoot(MAILBOX_PATH)).isEqualTo(QUOTA_ROOT);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void getQuotaRootShouldThrowWhenNamespaceContainsSeparator() throws Exception {
-        testee.getQuotaRoot(new MailboxPath("#pr&ivate", "benwa", "INBOX"));
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void getQuotaRootShouldThrowWhenUserContainsSeparator() throws Exception {
-        testee.getQuotaRoot(MailboxPath.forUser("ben&wa", "INBOX"));
-    }
-
-    @Test
-    public void retrieveAssociatedMailboxesShouldWork() throws Exception {
-        final MailboxMapper mockedMapper = mock(MailboxMapper.class);
-        when(mockedFactory.getMailboxMapper(null)).thenReturn(mockedMapper);
-        when(mockedMapper.findMailboxWithPathLike(PATH_LIKE)).thenReturn(Lists.newArrayList(MAILBOX, MAILBOX_2));
-        assertThat(testee.retrieveAssociatedMailboxes(QUOTA_ROOT, null)).containsOnly(MAILBOX_PATH, MAILBOX_PATH_2);
-    }
-
-    @Test(expected = MailboxException.class)
-    public void retrieveAssociatedMailboxesShouldThrowWhenQuotaRootContainsSeparator2Times() throws Exception {
-        testee.retrieveAssociatedMailboxes(QuotaRoot.quotaRoot("#private&be&nwa", Optional.empty()), null);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/72bc076c/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolverTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolverTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolverTest.java
new file mode 100644
index 0000000..92b9f6c
--- /dev/null
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolverTest.java
@@ -0,0 +1,92 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.store.quota;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Optional;
+
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.QuotaRoot;
+import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
+import org.apache.james.mailbox.store.mail.MailboxMapper;
+import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.Lists;
+
+public class DefaultUserQuotaRootResolverTest {
+
+    public static final MailboxPath MAILBOX_PATH = MailboxPath.forUser("benwa", "INBOX");
+    public static final SimpleMailbox MAILBOX = new SimpleMailbox(MAILBOX_PATH, 10);
+    public static final MailboxPath PATH_LIKE = MailboxPath.forUser("benwa", "%");
+    public static final MailboxPath MAILBOX_PATH_2 = MailboxPath.forUser("benwa", "test");
+    public static final SimpleMailbox MAILBOX_2 = new SimpleMailbox(MAILBOX_PATH_2, 10);
+    public static final QuotaRoot QUOTA_ROOT = QuotaRoot.quotaRoot("#private&benwa", Optional.empty());
+
+    private DefaultUserQuotaRootResolver testee;
+    private MailboxSessionMapperFactory mockedFactory;
+
+    @Before
+    public void setUp() {
+        mockedFactory = mock(MailboxSessionMapperFactory.class);
+        testee = new DefaultUserQuotaRootResolver(mockedFactory);
+    }
+
+    @Test
+    public void getQuotaRootShouldReturnUserRelatedQuotaRoot() throws Exception {
+        assertThat(testee.getQuotaRoot(MAILBOX_PATH)).isEqualTo(QUOTA_ROOT);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void getQuotaRootShouldThrowWhenNamespaceContainsSeparator() throws Exception {
+        testee.getQuotaRoot(new MailboxPath("#pr&ivate", "benwa", "INBOX"));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void getQuotaRootShouldThrowWhenUserContainsSeparator() throws Exception {
+        testee.getQuotaRoot(MailboxPath.forUser("ben&wa", "INBOX"));
+    }
+
+    @Test
+    public void getQuotaRootShouldWorkWhenUserIsNull() throws Exception {
+        QuotaRoot quotaRoot = testee.getQuotaRoot(new MailboxPath("#private", null, "INBOX"));
+
+        assertThat(quotaRoot).isEqualTo(QuotaRoot.quotaRoot("#private", Optional.empty()));
+    }
+
+    @Test
+    public void retrieveAssociatedMailboxesShouldWork() throws Exception {
+        final MailboxMapper mockedMapper = mock(MailboxMapper.class);
+        when(mockedFactory.getMailboxMapper(null)).thenReturn(mockedMapper);
+        when(mockedMapper.findMailboxWithPathLike(PATH_LIKE)).thenReturn(Lists.newArrayList(MAILBOX, MAILBOX_2));
+        assertThat(testee.retrieveAssociatedMailboxes(QUOTA_ROOT, null)).containsOnly(MAILBOX_PATH, MAILBOX_PATH_2);
+    }
+
+    @Test(expected = MailboxException.class)
+    public void retrieveAssociatedMailboxesShouldThrowWhenQuotaRootContainsSeparator2Times() throws Exception {
+        testee.retrieveAssociatedMailboxes(QuotaRoot.quotaRoot("#private&be&nwa", Optional.empty()), null);
+    }
+
+}


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


[6/8] james-project git commit: JAMES-2413 Define route for creating mail repository in webadmin

Posted by bt...@apache.org.
JAMES-2413 Define route for creating mail repository in webadmin


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

Branch: refs/heads/master
Commit: 7488a2e0d6f817d949023291a6497dd69cde3479
Parents: addce27
Author: duc <tr...@gmail.com>
Authored: Thu Jun 7 12:52:50 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Wed Jun 13 09:43:47 2018 +0700

----------------------------------------------------------------------
 .../james/cli/DataCommandsIntegrationTest.java  |  10 +-
 .../CassandraMailRepositoryIntegrationTest.java |   5 +-
 .../java/org/apache/james/ESReporterTest.java   |   5 +-
 .../org/apache/james/utils/DataProbeImpl.java   |  10 --
 .../org/apache/james/JPAJamesServerTest.java    |   5 +-
 .../mailrepository/api/MailRepositoryStore.java |   8 +
 .../java/org/apache/james/probe/DataProbe.java  |  27 +++
 .../crypto/SMIMEDecryptIntegrationTest.java     |   5 +-
 .../transport/mailets/ContactExtractorTest.java |  19 +-
 .../transport/mailets/SpamAssassinTest.java     |   9 +-
 .../mailets/ToSenderDomainRepositoryTest.java   |  66 ++++---
 server/mailet/mailets/pom.xml                   |   5 +
 .../mailets/ToSenderDomainRepository.java       |   9 +-
 .../mailets/ToSenderDomainRepositoryTest.java   |  20 ++-
 .../james/jmap/JMAPAuthenticationTest.java      |   5 +-
 .../org/apache/james/jmap/ProvisioningTest.java |   5 +-
 .../integration/SetVacationResponseTest.java    |   5 +-
 .../integration/SpamAssassinContract.java       |  11 +-
 .../webadmin/routes/MailRepositoriesRoutes.java |  30 +++-
 .../service/MailRepositoryStoreService.java     |   3 +
 .../routes/MailRepositoriesRoutesTest.java      |  59 +++++-
 src/site/markdown/server/manage-webadmin.md     | 180 ++++++++++---------
 22 files changed, 331 insertions(+), 170 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/container/cli-integration/src/test/java/org/apache/james/cli/DataCommandsIntegrationTest.java
----------------------------------------------------------------------
diff --git a/server/container/cli-integration/src/test/java/org/apache/james/cli/DataCommandsIntegrationTest.java b/server/container/cli-integration/src/test/java/org/apache/james/cli/DataCommandsIntegrationTest.java
index eeddbd0..7cb8fbd 100644
--- a/server/container/cli-integration/src/test/java/org/apache/james/cli/DataCommandsIntegrationTest.java
+++ b/server/container/cli-integration/src/test/java/org/apache/james/cli/DataCommandsIntegrationTest.java
@@ -109,8 +109,9 @@ public class DataCommandsIntegrationTest {
 
     @Test
     public void removeUserShouldWork() throws Exception {
-        dataProbe.fluentAddDomain(DOMAIN)
-            .fluentAddUser(MAIL_ADDRESS, PASSWORD);
+        dataProbe.fluent()
+            .addDomain(DOMAIN)
+            .addUser(MAIL_ADDRESS, PASSWORD);
 
         ServerCmd.doMain(new String[] {"-h", "127.0.0.1", "-p", "9999", "REMOVEUSER", MAIL_ADDRESS});
 
@@ -119,8 +120,9 @@ public class DataCommandsIntegrationTest {
 
     @Test
     public void listUsersShouldWork() throws Exception {
-        dataProbe.fluentAddDomain(DOMAIN)
-            .fluentAddUser(MAIL_ADDRESS, PASSWORD);
+        dataProbe.fluent()
+            .addDomain(DOMAIN)
+            .addUser(MAIL_ADDRESS, PASSWORD);
 
         ServerCmd.executeAndOutputToStream(new String[] {"-h", "127.0.0.1", "-p", "9999", "listusers"}, outputCapture.getPrintStream());
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraMailRepositoryIntegrationTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraMailRepositoryIntegrationTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraMailRepositoryIntegrationTest.java
index 836e27d..e694ec9 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraMailRepositoryIntegrationTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraMailRepositoryIntegrationTest.java
@@ -66,8 +66,9 @@ public class CassandraMailRepositoryIntegrationTest {
     @Test
     public void deniedSenderMailShouldBeStoredInCassandraMailRepositoryWhenConfigured() throws Exception {
         server.getProbe(DataProbeImpl.class)
-            .fluentAddDomain("domain.com")
-            .fluentAddUser("user@domain.com", "secret");
+            .fluent()
+            .addDomain("domain.com")
+            .addUser("user@domain.com", "secret");
 
         smtpMessageSender.connect("127.0.0.1", 1025)
             .sendMessage("denied@other.com", "user@domain.com");

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java
index 148c42c..b0f555e 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java
@@ -78,8 +78,9 @@ public class ESReporterTest {
         server = cassandraJmap.jmapServer();
         server.start();
         server.getProbe(DataProbeImpl.class)
-            .fluentAddDomain(DOMAIN)
-            .fluentAddUser(USERNAME, PASSWORD);
+            .fluent()
+            .addDomain(DOMAIN)
+            .addUser(USERNAME, PASSWORD);
 
         RestAssured.requestSpecification = new RequestSpecBuilder()
                 .setContentType(ContentType.JSON)

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java
index f016129..314ec07 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java
@@ -58,11 +58,6 @@ public class DataProbeImpl implements GuiceProbe, DataProbe {
         usersRepository.addUser(userName, password);
     }
 
-    public DataProbeImpl fluentAddUser(String userName, String password) throws Exception {
-        addUser(userName, password);
-        return this;
-    }
-
     @Override
     public void removeUser(String username) throws Exception {
         usersRepository.removeUser(username);
@@ -83,11 +78,6 @@ public class DataProbeImpl implements GuiceProbe, DataProbe {
         domainList.addDomain(Domain.of(domain));
     }
 
-    public DataProbeImpl fluentAddDomain(String domain) throws Exception {
-        addDomain(domain);
-        return this;
-    }
-
     @Override
     public boolean containsDomain(String domain) throws Exception {
         return domainList.containsDomain(Domain.of(domain));

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerTest.java b/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerTest.java
index e07727b..d99192a 100644
--- a/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerTest.java
+++ b/server/container/guice/jpa-guice/src/test/java/org/apache/james/JPAJamesServerTest.java
@@ -78,8 +78,9 @@ public class JPAJamesServerTest extends AbstractJamesServerTest {
     @Test
     public void jpaGuiceServerShouldUpdateQuota() throws Exception {
         server.getProbe(DataProbeImpl.class)
-            .fluentAddDomain(DOMAIN)
-            .fluentAddUser(USER, PASSWORD);
+            .fluent()
+            .addDomain(DOMAIN)
+            .addUser(USER, PASSWORD);
         server.getProbe(QuotaProbesImpl.class).setGlobalMaxStorage(new SerializableQuotaValue<>(QuotaSize.size(50 * 1024)));
 
         // ~ 12 KB email

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/data/data-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryStore.java
----------------------------------------------------------------------
diff --git a/server/data/data-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryStore.java b/server/data/data-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryStore.java
index a454767..37f1902 100644
--- a/server/data/data-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryStore.java
+++ b/server/data/data-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryStore.java
@@ -34,6 +34,14 @@ public interface MailRepositoryStore {
     MailRepository select(String url) throws MailRepositoryStoreException;
 
     /**
+     * Create the {@link MailRepository} for the given url and return it. If the repository already exists,
+     * then no new repository is created, the old one will be returned.
+     */
+    default MailRepository create(String url) throws MailRepositoryStoreException {
+        return select(url);
+    }
+
+    /**
      * Returns the {@link MailRepository} for the given url.
      * This mail repository will not be created if it does not exist.
      */

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/data/data-api/src/main/java/org/apache/james/probe/DataProbe.java
----------------------------------------------------------------------
diff --git a/server/data/data-api/src/main/java/org/apache/james/probe/DataProbe.java b/server/data/data-api/src/main/java/org/apache/james/probe/DataProbe.java
index e85c06c..6832fcd 100644
--- a/server/data/data-api/src/main/java/org/apache/james/probe/DataProbe.java
+++ b/server/data/data-api/src/main/java/org/apache/james/probe/DataProbe.java
@@ -26,6 +26,33 @@ import org.apache.james.rrt.lib.Mappings;
 
 public interface DataProbe {
 
+    class FluentDataProbe {
+
+        private final DataProbe dataProbe;
+
+        private FluentDataProbe(DataProbe dataProbe) {
+            this.dataProbe = dataProbe;
+        }
+
+        public DataProbe getDataProbe() {
+            return dataProbe;
+        }
+
+        public FluentDataProbe addUser(String userName, String password) throws Exception {
+            dataProbe.addUser(userName, password);
+            return this;
+        }
+
+        public FluentDataProbe addDomain(String domain) throws Exception {
+            dataProbe.addDomain(domain);
+            return this;
+        }
+    }
+
+    default FluentDataProbe fluent() {
+        return new FluentDataProbe(this);
+    }
+
     void addUser(String userName, String password) throws Exception;
 
     void removeUser(String username) throws Exception;

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/crypto/SMIMEDecryptIntegrationTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/crypto/SMIMEDecryptIntegrationTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/crypto/SMIMEDecryptIntegrationTest.java
index ba91794..0e9b4a6 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/crypto/SMIMEDecryptIntegrationTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/crypto/SMIMEDecryptIntegrationTest.java
@@ -85,8 +85,9 @@ public class SMIMEDecryptIntegrationTest {
             .build(temporaryFolder);
 
         jamesServer.getProbe(DataProbeImpl.class)
-            .fluentAddDomain(DEFAULT_DOMAIN)
-            .fluentAddUser(FROM, PASSWORD);
+            .fluent()
+            .addDomain(DEFAULT_DOMAIN)
+            .addUser(FROM, PASSWORD);
     }
 
     @After

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ContactExtractorTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ContactExtractorTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ContactExtractorTest.java
index c29535f..e16b948 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ContactExtractorTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ContactExtractorTest.java
@@ -100,15 +100,16 @@ public class ContactExtractorTest {
             .withMailetContainer(mailets)
             .build(folder);
 
-        DataProbeImpl probe = jamesServer.getProbe(DataProbeImpl.class);
-        probe.fluentAddDomain(DEFAULT_DOMAIN)
-            .fluentAddUser(SENDER, PASSWORD)
-            .fluentAddUser(TO, PASSWORD)
-            .fluentAddUser(TO2, PASSWORD)
-            .fluentAddUser(CC, PASSWORD)
-            .fluentAddUser(CC2, PASSWORD)
-            .fluentAddUser(BCC, PASSWORD)
-            .fluentAddUser(BCC2, PASSWORD);
+        jamesServer.getProbe(DataProbeImpl.class)
+            .fluent()
+            .addDomain(DEFAULT_DOMAIN)
+            .addUser(SENDER, PASSWORD)
+            .addUser(TO, PASSWORD)
+            .addUser(TO2, PASSWORD)
+            .addUser(CC, PASSWORD)
+            .addUser(CC2, PASSWORD)
+            .addUser(BCC, PASSWORD)
+            .addUser(BCC2, PASSWORD);
     }
 
     @After

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/SpamAssassinTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/SpamAssassinTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/SpamAssassinTest.java
index 3c56362..cad6813 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/SpamAssassinTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/SpamAssassinTest.java
@@ -87,10 +87,11 @@ public class SpamAssassinTest {
             .build(temporaryFolder);
 
         jamesServer.getProbe(DataProbeImpl.class)
-            .fluentAddDomain(DEFAULT_DOMAIN)
-            .fluentAddUser(FROM, PASSWORD)
-            .fluentAddUser(RECIPIENT, PASSWORD)
-            .fluentAddUser(RECIPIENT2, PASSWORD);
+            .fluent()
+            .addDomain(DEFAULT_DOMAIN)
+            .addUser(FROM, PASSWORD)
+            .addUser(RECIPIENT, PASSWORD)
+            .addUser(RECIPIENT2, PASSWORD);
     }
 
     @After

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
index b811e8f..467f3d3 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
@@ -64,62 +64,71 @@ public class ToSenderDomainRepositoryTest {
 
     @Test
     public void incomingMailShouldBeStoredInCorrespondingMailRepository() throws Exception {
-        initializeJamesServer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+        startJamesServerWithMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
             .putProcessor(ProcessorConfiguration.root()
                 .addMailet(MailetConfiguration.builder()
                     .matcher(All.class)
                     .mailet(ToSenderDomainRepository.class)
                     .addProperty("urlPrefix", CUSTOM_REPOSITORY_PREFIX))));
+        MailRepositoryProbeImpl probe = jamesServer.getProbe(MailRepositoryProbeImpl.class);
 
         messageSender.connect(LOCALHOST_IP, SMTP_PORT)
             .sendMessage(RECIPIENT, RECIPIENT);
 
         awaitAtMostOneMinute.until(
-            () -> jamesServer.getProbe(MailRepositoryProbeImpl.class)
-                .getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 1);
+            () -> probe.getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 1);
+
+        assertThat(probe.getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN))
+            .isEqualTo(1);
     }
 
     @Test
-    public void incomingMailShouldBeStoredWhenRepositoryDoNotExistAndAllowedToCreateRepository() throws Exception {
-        initializeJamesServer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+    public void incomingMailShouldBeStoredWhenRepositoryDoesNotExistAndAllowedToCreateRepository() throws Exception {
+        startJamesServerWithMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
             .putProcessor(ProcessorConfiguration.root()
                 .addMailet(MailetConfiguration.builder()
                     .matcher(All.class)
                     .mailet(ToSenderDomainRepository.class)
                     .addProperty("urlPrefix", CUSTOM_REPOSITORY_PREFIX)
                     .addProperty("allowRepositoryCreation", "true"))));
+        MailRepositoryProbeImpl probe = jamesServer.getProbe(MailRepositoryProbeImpl.class);
 
         messageSender.connect(LOCALHOST_IP, SMTP_PORT)
             .sendMessage(RECIPIENT, RECIPIENT);
 
         awaitAtMostOneMinute.until(
-            () -> jamesServer.getProbe(MailRepositoryProbeImpl.class)
-                .getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 1);
+            () -> probe.getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 1);
+
+        assertThat(probe.getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN))
+            .isEqualTo(1);
     }
 
     @Test
     public void incomingMailShouldBeStoredWhenRepositoryExistsAndAllowedToCreateRepository() throws Exception {
-        initializeJamesServer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+        startJamesServerWithMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
             .putProcessor(ProcessorConfiguration.root()
                 .addMailet(MailetConfiguration.builder()
                     .matcher(All.class)
                     .mailet(ToSenderDomainRepository.class)
                     .addProperty("urlPrefix", CUSTOM_REPOSITORY_PREFIX)
                     .addProperty("allowRepositoryCreation", "true"))));
-        jamesServer.getProbe(MailRepositoryProbeImpl.class)
-            .createRepository(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN);
+        MailRepositoryProbeImpl probe = jamesServer.getProbe(MailRepositoryProbeImpl.class);
+
+        probe.createRepository(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN);
 
         messageSender.connect(LOCALHOST_IP, SMTP_PORT)
             .sendMessage(RECIPIENT, RECIPIENT);
 
         awaitAtMostOneMinute.until(
-            () -> jamesServer.getProbe(MailRepositoryProbeImpl.class)
-                .getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 1);
+            () -> probe.getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 1);
+
+        assertThat(probe.getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN))
+            .isEqualTo(1);
     }
 
     @Test
-    public void incomingMailShouldBeIgnoredWhenRepositoryDoNotExistAndNotAllowedToCreateRepository() throws Exception {
-        initializeJamesServer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+    public void incomingMailShouldBeIgnoredWhenRepositoryDoesNotExistAndNotAllowedToCreateRepository() throws Exception {
+        startJamesServerWithMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
             .putProcessor(ProcessorConfiguration.root()
                 .addMailet(MailetConfiguration.builder()
                     .matcher(All.class)
@@ -145,49 +154,56 @@ public class ToSenderDomainRepositoryTest {
 
     @Test
     public void incomingMailShouldBeStoredWhenRepositoryExistsAndNotAllowedToCreateRepository() throws Exception {
-        initializeJamesServer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+        startJamesServerWithMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
             .putProcessor(ProcessorConfiguration.root()
                 .addMailet(MailetConfiguration.builder()
                     .matcher(All.class)
                     .mailet(ToSenderDomainRepository.class)
                     .addProperty("urlPrefix", CUSTOM_REPOSITORY_PREFIX)
                     .addProperty("allowRepositoryCreation", "false"))));
-        jamesServer.getProbe(MailRepositoryProbeImpl.class)
-            .createRepository(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN);
+        MailRepositoryProbeImpl probe = jamesServer.getProbe(MailRepositoryProbeImpl.class);
+
+        probe.createRepository(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN);
 
         messageSender.connect(LOCALHOST_IP, SMTP_PORT)
             .sendMessage(RECIPIENT, RECIPIENT);
 
         awaitAtMostOneMinute.until(
-            () -> jamesServer.getProbe(MailRepositoryProbeImpl.class)
-                .getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 1);
+            () -> probe.getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 1);
+
+        assertThat(probe.getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN))
+            .isEqualTo(1);
     }
 
     @Test
     public void incomingMailsShouldBeStoredInCorrespondingMailRepository() throws Exception {
-        initializeJamesServer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+        startJamesServerWithMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
             .putProcessor(ProcessorConfiguration.root()
                 .addMailet(MailetConfiguration.builder()
                     .matcher(All.class)
                     .mailet(ToSenderDomainRepository.class)
                     .addProperty("urlPrefix", CUSTOM_REPOSITORY_PREFIX))));
+        MailRepositoryProbeImpl probe = jamesServer.getProbe(MailRepositoryProbeImpl.class);
 
         messageSender.connect(LOCALHOST_IP, SMTP_PORT)
             .sendMessage(RECIPIENT, RECIPIENT)
             .sendMessage(RECIPIENT, RECIPIENT);
 
         awaitAtMostOneMinute.until(
-            () -> jamesServer.getProbe(MailRepositoryProbeImpl.class)
-                .getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 2);
+            () -> probe.getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 2);
+
+        assertThat(probe.getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN))
+            .isEqualTo(2);
     }
 
-    private void initializeJamesServer(MailetContainer.Builder mailetContainer) throws Exception {
+    private void startJamesServerWithMailetContainer(MailetContainer.Builder mailetContainer) throws Exception {
         jamesServer = TemporaryJamesServer.builder()
             .withMailetContainer(mailetContainer)
             .build(temporaryFolder);
 
         jamesServer.getProbe(DataProbeImpl.class)
-            .fluentAddDomain(DEFAULT_DOMAIN)
-            .fluentAddUser(RECIPIENT, PASSWORD);
+            .fluent()
+            .addDomain(DEFAULT_DOMAIN)
+            .addUser(RECIPIENT, PASSWORD);
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/mailet/mailets/pom.xml
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/pom.xml b/server/mailet/mailets/pom.xml
index eb72017..687df0e 100644
--- a/server/mailet/mailets/pom.xml
+++ b/server/mailet/mailets/pom.xml
@@ -236,6 +236,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>java-hamcrest</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.junit.jupiter</groupId>
             <artifactId>junit-jupiter-engine</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
index 8f417c6..f86becc 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
@@ -46,7 +46,10 @@ import com.github.fge.lambdas.consumers.ThrowingConsumer;
  *  - "allowRepositoryCreation" optional, defaults to true. If true, non existing repository will be created. In case of
  *  misconfiguration, this might lead to arbitrary repository creation. If false, the incoming mails will be stored only
  *  in already existing repository. If not existing, the email will be dropped with an appropriate log warning (leading
- *  to potential data loss).
+ *  to potential data loss). In case, you want to create a repository manually, make a http PUT request to
+ *  /mailRepositories/encodedUrlOfTheRepository from web admin api.
+ *  For example http://ip:port/mailRepositories/file%3A%2F%2FmailRepo
+ *  @see <a href="https://james.apache.org/server/manage-webadmin.html">Create a mail repository</a>
  *
  *  Example:
  *
@@ -82,8 +85,8 @@ public class ToSenderDomainRepository extends GenericMailet {
 
     @Override
     public void service(Mail mail) throws MessagingException {
-        String url = urlPrefix + mail.getSender().getDomain().asString();
-        store(mail, url);
+        String repositoryUrl = urlPrefix + mail.getSender().getDomain().asString();
+        store(mail, repositoryUrl);
         if (!passThrough) {
             mail.setState(Mail.GHOST);
         }

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
index e532e90..b69807a 100644
--- a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
+++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java
@@ -21,6 +21,7 @@ package org.apache.james.transport.mailets;
 
 import static org.apache.mailet.base.MailAddressFixture.JAMES_LOCAL;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
@@ -41,9 +42,10 @@ import org.junit.jupiter.api.Test;
 
 class ToSenderDomainRepositoryTest {
 
+    private static final String MEMORY_URL_PREFIX = "memory://var/mail/dlp/";
     private static final FakeMailetConfig DEFAULT_MAILET_CONFIG = FakeMailetConfig.builder()
         .mailetName("TestConfig")
-        .setProperty("urlPrefix", "memory://var/mail/dlp/")
+        .setProperty("urlPrefix", MEMORY_URL_PREFIX)
         .build();
     private ToSenderDomainRepository mailet;
     private MockMailRepositoryStore mailRepositoryStore;
@@ -51,7 +53,7 @@ class ToSenderDomainRepositoryTest {
     @BeforeEach
     void setup() {
         mailRepositoryStore = new MockMailRepositoryStore();
-        mailRepositoryStore.add("memory://var/mail/dlp/" + JAMES_LOCAL, new MemoryMailRepository());
+        mailRepositoryStore.add(MEMORY_URL_PREFIX + JAMES_LOCAL, new MemoryMailRepository());
         mailet = new ToSenderDomainRepository(mailRepositoryStore);
     }
 
@@ -66,8 +68,10 @@ class ToSenderDomainRepositoryTest {
     }
 
     @Test
-    void initShouldNotThrowWhenUrlPrefixIsPresent() throws MessagingException {
-        mailet.init(DEFAULT_MAILET_CONFIG);
+    void initShouldNotThrowWhenUrlPrefixIsPresent() {
+        assertThatCode(
+            () -> mailet.init(DEFAULT_MAILET_CONFIG))
+            .doesNotThrowAnyException();
     }
 
     @Test
@@ -80,7 +84,7 @@ class ToSenderDomainRepositoryTest {
             .sender(MailAddressFixture.SENDER)
             .build());
 
-        MailRepository mailRepository = mailRepositoryStore.select("memory://var/mail/dlp/" + JAMES_LOCAL);
+        MailRepository mailRepository = mailRepositoryStore.select(MEMORY_URL_PREFIX + JAMES_LOCAL);
 
         assertThat(mailRepository.list())
             .extracting(mailRepository::retrieve)
@@ -93,7 +97,7 @@ class ToSenderDomainRepositoryTest {
         FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
             .mailetName("TestConfig")
             .setProperty("passThrough", "false")
-            .setProperty("urlPrefix", "memory://var/mail/dlp/")
+            .setProperty("urlPrefix", MEMORY_URL_PREFIX)
             .build();
         mailet.init(mailetConfig);
 
@@ -114,7 +118,7 @@ class ToSenderDomainRepositoryTest {
         FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
             .mailetName("TestConfig")
             .setProperty("passThrough", "true")
-            .setProperty("urlPrefix", "memory://var/mail/dlp/")
+            .setProperty("urlPrefix", MEMORY_URL_PREFIX)
             .build();
         mailet.init(mailetConfig);
 
@@ -169,7 +173,7 @@ class ToSenderDomainRepositoryTest {
     void initShouldSetNotPassThroughWhenPassThroughIsNotBoolean() throws Exception {
         FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
             .mailetName("TestConfig")
-            .setProperty("urlPrefix", "memory://var/mail/dlp/")
+            .setProperty("urlPrefix", MEMORY_URL_PREFIX)
             .setProperty("passThrough", "not boolean")
             .build();
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java
index eae6a4c..1f3492e 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java
@@ -73,8 +73,9 @@ public abstract class JMAPAuthenticationTest {
         
         String domain = "domain.tld";
         jmapServer.getProbe(DataProbeImpl.class)
-            .fluentAddDomain(domain)
-            .fluentAddUser(userCredentials.getUsername(), userCredentials.getPassword());
+            .fluent()
+            .addDomain(domain)
+            .addUser(userCredentials.getUsername(), userCredentials.getPassword());
         
     }
     

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/ProvisioningTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/ProvisioningTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/ProvisioningTest.java
index fcb02b5..e5d49a5 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/ProvisioningTest.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/ProvisioningTest.java
@@ -64,8 +64,9 @@ public abstract class ProvisioningTest {
             .build();
 
         jmapServer.getProbe(DataProbeImpl.class)
-            .fluentAddDomain(DOMAIN)
-            .fluentAddUser(USER, PASSWORD);
+            .fluent()
+            .addDomain(DOMAIN)
+            .addUser(USER, PASSWORD);
     }
 
     @After

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetVacationResponseTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetVacationResponseTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetVacationResponseTest.java
index f86015c..d5f4257 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetVacationResponseTest.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetVacationResponseTest.java
@@ -72,8 +72,9 @@ public abstract class SetVacationResponseTest {
                 .build();
 
         jmapServer.getProbe(DataProbeImpl.class)
-            .fluentAddDomain(DOMAIN)
-            .fluentAddUser(USER, PASSWORD);
+            .fluent()
+            .addDomain(DOMAIN)
+            .addUser(USER, PASSWORD);
         accessToken = authenticateJamesUser(baseUri(jmapServer), USER, PASSWORD);
 
         await();

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SpamAssassinContract.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SpamAssassinContract.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SpamAssassinContract.java
index 358579b..8a2a62c 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SpamAssassinContract.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SpamAssassinContract.java
@@ -74,11 +74,12 @@ public interface SpamAssassinContract {
         RestAssured.defaultParser = Parser.JSON;
 
         james.getJmapServer().getProbe(DataProbeImpl.class)
-            .fluentAddDomain(BOBS_DOMAIN)
-            .fluentAddDomain(RECIPIENTS_DOMAIN)
-            .fluentAddUser(BOB, BOB_PASSWORD)
-            .fluentAddUser(ALICE, ALICE_PASSWORD)
-            .fluentAddUser(PAUL, PAUL_PASSWORD);
+            .fluent()
+            .addDomain(BOBS_DOMAIN)
+            .addDomain(RECIPIENTS_DOMAIN)
+            .addUser(BOB, BOB_PASSWORD)
+            .addUser(ALICE, ALICE_PASSWORD)
+            .addUser(PAUL, PAUL_PASSWORD);
     }
 
     default AccessToken accessTokenFor(GuiceJamesServer james, String user, String password) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/routes/MailRepositoriesRoutes.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/routes/MailRepositoriesRoutes.java b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/routes/MailRepositoriesRoutes.java
index c9f07cc..b60bb6f 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/routes/MailRepositoriesRoutes.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/routes/MailRepositoriesRoutes.java
@@ -34,6 +34,7 @@ import javax.mail.internet.MimeMessage;
 import javax.servlet.http.HttpServletResponse;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 
@@ -95,6 +96,8 @@ public class MailRepositoriesRoutes implements Routes {
     public void define(Service service) {
         this.service = service;
 
+        definePutMailRepository();
+
         defineGetMailRepositories();
 
         defineListMails();
@@ -112,6 +115,31 @@ public class MailRepositoriesRoutes implements Routes {
         defineReprocessOne();
     }
 
+    @PUT
+    @Path("/{encodedUrl}")
+    @ApiOperation(value = "Create a repository")
+    @ApiResponses(value = {
+        @ApiResponse(code = HttpStatus.NO_CONTENT_204, message = "The repository is created"),
+        @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500, message = "Internal server error - Something went bad on the server side."),
+    })
+    public void definePutMailRepository() {
+        service.put(MAIL_REPOSITORIES + "/:encodedUrl", (request, response) -> {
+            String url = decodedRepositoryUrl(request);
+            try {
+                repositoryStoreService.createMailRepository(url);
+                response.status(HttpStatus.NO_CONTENT_204);
+                return Constants.EMPTY_BODY;
+            } catch (MailRepositoryStore.MailRepositoryStoreException e) {
+                throw ErrorResponder.builder()
+                    .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500)
+                    .type(ErrorResponder.ErrorType.SERVER_ERROR)
+                    .cause(e)
+                    .message(String.format("Error while creating a mail repository with url '%s'", url))
+                    .haltError();
+            }
+        }, jsonTransformer);
+    }
+
     @GET
     @Path("/{encodedUrl}/mails")
     @ApiOperation(value = "Listing all mails in a repository")
@@ -144,7 +172,7 @@ public class MailRepositoriesRoutes implements Routes {
             Offset offset = ParametersExtractor.extractOffset(request);
             Limit limit = ParametersExtractor.extractLimit(request);
             String encodedUrl = request.params("encodedUrl");
-            String url = URLDecoder.decode(encodedUrl, StandardCharsets.UTF_8.displayName());
+            String url = decodedRepositoryUrl(request);
             try {
                 return repositoryStoreService.listMails(url, offset, limit)
                     .orElseThrow(() -> ErrorResponder.builder()

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/MailRepositoryStoreService.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/MailRepositoryStoreService.java b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/MailRepositoryStoreService.java
index 6f69be3..de33041 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/MailRepositoryStoreService.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/MailRepositoryStoreService.java
@@ -58,6 +58,9 @@ public class MailRepositoryStoreService {
             .collect(Guavate.toImmutableList());
     }
 
+    public MailRepository createMailRepository(String repositoryUrl) throws MailRepositoryStore.MailRepositoryStoreException {
+        return mailRepositoryStore.create(repositoryUrl);
+    }
 
     public Optional<List<MailKey>> listMails(String url, Offset offset, Limit limit) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {
         Optional<MailRepository> mailRepository = Optional.ofNullable(getRepository(url));

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/routes/MailRepositoriesRoutesTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/routes/MailRepositoriesRoutesTest.java b/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/routes/MailRepositoriesRoutesTest.java
index e7b57fb..7370e3c 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/routes/MailRepositoriesRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/routes/MailRepositoriesRoutesTest.java
@@ -32,7 +32,11 @@ import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.isEmptyOrNullString;
 import static org.hamcrest.Matchers.notNullValue;
+import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import java.nio.charset.StandardCharsets;
@@ -73,12 +77,12 @@ import com.jayway.restassured.parsing.Parser;
 
 public class MailRepositoriesRoutesTest {
 
-    public static final String URL_MY_REPO = "url://myRepo";
-    public static final String URL_ESCAPED_MY_REPO = "url%3A%2F%2FmyRepo";
-    public static final String MY_REPO_MAILS = "url%3A%2F%2FmyRepo/mails";
-    public static final String CUSTOM_QUEUE = "customQueue";
-    public static final String NAME_1 = "name1";
-    public static final String NAME_2 = "name2";
+    private static final String URL_MY_REPO = "url://myRepo";
+    private static final String URL_ESCAPED_MY_REPO = "url%3A%2F%2FmyRepo";
+    private static final String MY_REPO_MAILS = "url%3A%2F%2FmyRepo/mails";
+    private static final String CUSTOM_QUEUE = "customQueue";
+    private static final String NAME_1 = "name1";
+    private static final String NAME_2 = "name2";
     private WebAdminServer webAdminServer;
     private MailRepositoryStore mailRepositoryStore;
     private MemoryMailRepository mailRepository;
@@ -111,6 +115,7 @@ public class MailRepositoriesRoutesTest {
         RestAssured.requestSpecification = WebAdminUtils.buildRequestSpecification(webAdminServer)
             .setBasePath(MailRepositoriesRoutes.MAIL_REPOSITORIES)
             .build();
+        RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
     }
 
     @After
@@ -119,6 +124,48 @@ public class MailRepositoriesRoutesTest {
     }
 
     @Test
+    public void putMailRepositoryShouldReturnOkWhenRepositoryIsCreated() throws Exception {
+        when()
+            .put(URL_ESCAPED_MY_REPO)
+        .then()
+            .statusCode(HttpStatus.NO_CONTENT_204);
+
+        verify(mailRepositoryStore).create(URL_MY_REPO);
+        verifyNoMoreInteractions(mailRepositoryStore);
+    }
+
+    @Test
+    public void putMailRepositoryShouldReturnOkWhenRepositoryAlreadyExists() throws Exception {
+        when()
+            .put(URL_ESCAPED_MY_REPO)
+        .then()
+            .statusCode(HttpStatus.NO_CONTENT_204);
+
+        when()
+            .put(URL_ESCAPED_MY_REPO)
+        .then()
+            .statusCode(HttpStatus.NO_CONTENT_204);
+
+        verify(mailRepositoryStore, times(2)).create(URL_MY_REPO);
+        verifyNoMoreInteractions(mailRepositoryStore);
+    }
+
+    @Test
+    public void putMailRepositoryShouldReturnServerErrorWhenCannotCreateRepository() throws Exception {
+        when(mailRepositoryStore.create(anyString()))
+            .thenThrow(new MailRepositoryStore.MailRepositoryStoreException("Error while selecting repository url://myRepo"));
+
+        when()
+            .put(URL_ESCAPED_MY_REPO)
+        .then()
+            .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500)
+            .body("statusCode", is(500))
+            .body("type", is(ErrorResponder.ErrorType.SERVER_ERROR.getType()))
+            .body("message", is("Error while creating a mail repository with url 'url://myRepo'"))
+            .body("details", is("Error while selecting repository url://myRepo"));
+    }
+
+    @Test
     public void getMailRepositoriesShouldReturnEmptyWhenEmpty() {
         List<Object> mailRepositories =
             when()

http://git-wip-us.apache.org/repos/asf/james-project/blob/7488a2e0/src/site/markdown/server/manage-webadmin.md
----------------------------------------------------------------------
diff --git a/src/site/markdown/server/manage-webadmin.md b/src/site/markdown/server/manage-webadmin.md
index 01d2022..1a574d3 100644
--- a/src/site/markdown/server/manage-webadmin.md
+++ b/src/site/markdown/server/manage-webadmin.md
@@ -21,26 +21,26 @@ In case of any error, the system will return an error message which is json form
 
 ## Navigation menu
 
- - [Administrating domains](#administrating-domains)
- - [Administrating users](#administrating-users)
- - [Administrating user mailboxes](#administrating-user-mailboxes)
- - [Administrating quotas by users](#administrating-quotas-by-users)
- - [Administrating quotas by domains](#administrating-quotas-by-domains)
- - [Administrating global quotas](#administrating-global-quotas)
- - [Cassandra Schema upgrades](#cassandra-schema-upgrades)
- - [Correcting ghost mailbox](#correcting-ghost-mailbox)
- - [Creating address group](#creating-address-group)
- - [Creating address forwards](#creating-address-forwards)
- - [Administrating mail repositories](#administrating-mail-repositories)
- - [Administrating mail queues](#administrating-mail-queues)
- - [Task management](#task-management)
+ - [Administrating domains](#Administrating_domains)
+ - [Administrating users](#Administrating_users)
+ - [Administrating user mailboxes](#Administrating_user_mailboxes)
+ - [Administrating quotas by users](#Administrating_quotas_by_users)
+ - [Administrating quotas by domains](#Administrating_quotas_by_domains)
+ - [Administrating global quotas](#Administrating_global_quotas)
+ - [Cassandra Schema upgrades](#Cassandra_schema_upgrades)
+ - [Correcting ghost mailbox](#Correcting_ghost_mailbox)
+ - [Creating address group](#Creating_address_group)
+ - [Creating address forwards](#Creating_address_forwards)
+ - [Administrating mail repositories](#Administrating_mail_repositories)
+ - [Administrating mail queues](#Administrating_mail_queues)
+ - [Task management](#Task_management)
 
 ## Administrating domains
 
-   - [Create a domain](#create-a-domain)
-   - [Delete a domain](#delete-a-domain)
-   - [Test if a domain exists](#test-if-a-domain-exists)
-   - [Get the list of domains](#get-the-list-of-domains)
+   - [Create a domain](#Create_a_domain)
+   - [Delete a domain](#Delete_a_domain)
+   - [Test if a domain exists](#Test_if_a_domain_exists)
+   - [Get the list of domains](#Get_the_list_of_domains)
 
 ### Create a domain
 
@@ -103,10 +103,10 @@ Response codes:
 
 ## Administrating users
 
-   - [Create a user](#create-a-user)
-   - [Updating a user password](#updating-a-user-password)
-   - [Deleting a domain](#deleting-a-user)
-   - [Retrieving the user list](#retrieving-the-user-list)
+   - [Create a user](#Create_a_user)
+   - [Updating a user password](#Updating_a_user_password)
+   - [Deleting a domain](#Deleting_a_user)
+   - [Retrieving the user list](#Retrieving_the_user_list)
 
 ### Create a user
 
@@ -165,11 +165,11 @@ Response codes:
 
 ## Administrating user mailboxes
 
- - [Creating a mailbox](#creating-a-mailbox)
- - [Deleting a mailbox and its children](#deleting-a-mailbox-and-its-children)
- - [Testing existence of a mailbox](#testing-existence-of-a-mailbox)
- - [Listing user mailboxes](#listing-user-mailboxes)
- - [Deleting_user_mailboxes](#deleting-user-mailboxes)
+ - [Creating a mailbox](#Creating_a_mailbox)
+ - [Deleting a mailbox and its children](#Deleting_a_mailbox_and_its_children)
+ - [Testing existence of a mailbox](#Testing_existence_of_a_mailbox)
+ - [Listing user mailboxes](#Listing_user_mailboxes)
+ - [Deleting_user_mailboxes](#Deleting_user_mailboxes)
 
 ### Creating a mailbox
 
@@ -261,15 +261,15 @@ Response codes:
 
 ## Administrating quotas by users
 
- - [Getting the quota for a user](#getting-the-quota-for-a-user)
- - [Updating the quota for a user](#updating-the-quota-for-a-user)
- - [Getting the quota count for a user](#getting-the-quota-count-for-a-user)
- - [Updating the quota count for a user](#updating-the-quota-count-for-a-user)
- - [Deleting the quota count for a user](#deleting-the-quota-count-for-a-user)
- - [Getting the quota size for a user](#getting-the-quota-size-for-a-user)
- - [Updating the quota size for a user](#updating-the-quota-size-for-a-user)
- - [Deleting the quota size for a user](#deleting-the-quota-size-for-a-user)
- - [Searching user by quota ratio](#searching-user-by-quota-ratio)
+ - [Getting the quota for a user](#Getting_the_quota_for_a_user)
+ - [Updating the quota for a user](#Updating_the_quota_for_a_user)
+ - [Getting the quota count for a user](#Getting_the_quota_count_for_a_user)
+ - [Updating the quota count for a user](#Updating_the_quota_count_for_a_user)
+ - [Deleting the quota count for a user](#Deleting_the_quota_count_for_a_user)
+ - [Getting the quota size for a user](#Getting_the_quota_size_for_a_user)
+ - [Updating the quota size for a user](#Updating_the_quota_size_for_a_user)
+ - [Deleting the quota size for a user](#Deleting_the_quota_size_for_a_user)
+ - [Searching user by quota ratio](#Searching_user_by_quota_ratio)
 
 ### Getting the quota for a user
 
@@ -539,14 +539,14 @@ Response codes:
 
 ## Administrating quotas by domains
 
- - [Getting the quota for a domain](#getting-the-quota-for-a-domain)
- - [Updating the quota for a domain](#updating-the-quota-for-a-domain)
- - [Getting the quota count for a domain](#getting-the-quota-count-for-a-domain)
- - [Updating the quota count for a domain](#updating-the-quota-count-for-a-domain)
- - [Deleting the quota count for a domain](#deleting-the-quota-count-for-a-domain)
- - [Getting the quota size for a domain](#getting-the-quota-size-for-a-domain)
- - [Updating the quota size for a domain](#updating-the-quota-size-for-a-domain)
- - [Deleting the quota size for a domain](#deleting-the-quota-size-for-a-domain)
+ - [Getting the quota for a domain](#Getting_the_quota_for_a_domain)
+ - [Updating the quota for a domain](#Updating_the_quota_for_a_domain)
+ - [Getting the quota count for a domain](#Getting_the_quota_count_for_a_domain)
+ - [Updating the quota count for a domain](#Updating_the_quota_count_for_a_domain)
+ - [Deleting the quota count for a domain](#Deleting_the_quota_count_for_a_domain)
+ - [Getting the quota size for a domain](#Getting_the_quota_size_for_a_domain)
+ - [Updating the quota size for a domain](#Updating_the_quota_size_for_a_domain)
+ - [Deleting the quota size for a domain](#Deleting_the_quota_size_for_a_domain)
 
 ### Getting the quota for a domain
 
@@ -727,14 +727,14 @@ Response codes:
 
 ## Administrating global quotas
 
- - [Getting the global quota](#getting-the-global-quota)
- - [Updating global quota](#updating-global-quota)
- - [Getting the global quota count](#getting-the-global-quota-count)
- - [Updating the global quota count](#updating-the-global-quota-count)
- - [Deleting the global quota count](#deleting-the-global-quota-count)
- - [Getting the global quota size](#getting-the-global-quota-size)
- - [Updating the global quota size](#updating-the-global-quota-size)
- - [Deleting the global quota size](#deleting-the-global-quota-size)
+ - [Getting the global quota](#Getting_the_global_quota)
+ - [Updating global quota](#Updating_global_quota)
+ - [Getting the global quota count](#Getting_the_global_quota_count)
+ - [Updating the global quota count](#Updating_the_global_quota_count)
+ - [Deleting the global quota count](#Deleting_the_global_quota_count)
+ - [Getting the global quota size](#Getting_the_global_quota_size)
+ - [Updating the global quota size](#Updating_the_global_quota_size)
+ - [Deleting the global quota size](#Deleting_the_global_quota_size)
 
 ### Getting the global quota
 
@@ -910,10 +910,10 @@ These schema updates can be triggered by webadmin using the Cassandra backend.
 
 Note that currently the progress can be tracked by logs.
 
- - [Retrieving current Cassandra schema version](#retrieving-current-cassandra-schema-version)
- - [Retrieving latest available Cassandra schema version](#retrieving-latest-available-cassandra-schema-version)
- - [Upgrading to a specific version](#upgrading-to-a-specific-version)
- - [Upgrading to the latest version](#upgrading-to-the-latest-version)
+ - [Retrieving current Cassandra schema version](#Retrieving_current_cassandra_schema_version)
+ - [Retrieving latest available Cassandra schema version](#Retrieving_latest_available_cassandra_schema_version)
+ - [Upgrading to a specific version](#Upgrading_to_a_specific_version)
+ - [Upgrading to the latest version](#Upgrading_to_the_latest_version)
 
 ### Retrieving current Cassandra schema version
 
@@ -1082,10 +1082,10 @@ to be configured.
 
 Note that email addresses are restricted to ASCII character set. Mail addresses not matching this criteria will be rejected.
 
- - [Listing groups](#listing-groups)
- - [Listing members of a group](#listing-members-of-a-group)
- - [Adding a group member](#adding-a-group-member)
- - [Removing a group member](#removing-a-group-member)
+ - [Listing groups](#Listing_groups)
+ - [Listing members of a group](#Listing_members_of_a_group)
+ - [Adding a group member](#Adding_a_group_member)
+ - [Removing a group member](#Removing_a_group_member)
 
 ### Listing groups
 
@@ -1170,10 +1170,10 @@ to be configured.
 
 Note that email addresses are restricted to ASCII character set. Mail addresses not matching this criteria will be rejected.
 
- - [Listing Forwards](#listing-forwards)
- - [Listing destinations in a forward](#listing-destinations-in-a-forward)
- - [Adding a new destination to a forward](#adding-a-new-destination-to-a-forward)
- - [Removing a destination of a forward](#removing-a-destination-of-a-forward)
+ - [Listing Forwards](#Listing_forwards)
+ - [Listing destinations in a forward](#Listing_destinations_in_a_forward)
+ - [Adding a new destination to a forward](#Adding_a_new_destination_to_a_forward)
+ - [Removing a destination of a forward](#Removing_a_destination_of_a_forward)
 
 ### Listing Forwards
 
@@ -1246,14 +1246,32 @@ Response codes:
 
 ## Administrating mail repositories
 
- - [Listing mail repositories](#listing-mail-repositories)
- - [Getting additional information for a mail repository](#getting-additional-information-for-a-mail-repository)
- - [Listing mails contained in a mail repository](#listing-mails-contained-in-a-mail-repository)
- - [Reading a mail details](#reading-a-mail-details)
- - [Removing a mail from a mail repository](#removing-a-mail-from-a-mail-repository)
- - [Removing all mails from a mail repository](#removing-all-mails-from-a-mail-repository)
- - [Reprocessing mails from a mail repository](#reprocessing-mails-from-a-mail-repository)
- - [Reprocessing a specific mail from a mail repository](#reprocessing-a-specific-mail-from-a-mail-repository)
+ - [Create a mail repository](#Create_a_mail_repository)
+ - [Listing mail repositories](#Listing_mail_repositories)
+ - [Getting additional information for a mail repository](#Getting_additional_information_for_a_mail_repository)
+ - [Listing mails contained in a mail repository](#Listing_mails_contained_in_a_mail_repository)
+ - [Reading a mail details](#Reading_a_mail_details)
+ - [Removing a mail from a mail repository](#Removing_a_mail_from_a_mail_repository)
+ - [Removing all mails from a mail repository](#Removing_all_mails_from_a_mail_repository)
+ - [Reprocessing mails from a mail repository](#Reprocessing_mails_from_a_mail_repository)
+ - [Reprocessing a specific mail from a mail repository](#Reprocessing_a_specific_mail_from_a_mail_repository)
+
+### Create a mail repository
+
+```
+curl -XPUT http://ip:port/mailRepositories/encodedUrlOfTheRepository
+```
+
+Resource name `encodedUrlOfTheRepository` should be the resource id of the created mail repository. Example:
+
+```
+curl -XPUT http://ip:port/mailRepositories/file%3A%2F%2FmailRepo
+```
+
+Response codes:
+
+ - 204: The repository is created
+ - 500: Internal error
 
 ### Listing mail repositories
 
@@ -1580,12 +1598,12 @@ The scheduled task will have the following type `reprocessingOneTask` and the fo
 
 ## Administrating mail queues
 
- - [Listing mail queues](#listing-mail-queues)
- - [Getting a mail queue details](#getting-a-mail-queue-details)
- - [Listing the mails of a mail queue](#listing-the-mails-of-a-mail-queue)
- - [Deleting mails from a mail queue](#deleting-mails-from-a-mail-queue)
- - [Clearing a mail queue](#clearing-a-mail-queue)
- - [Flushing mails from a mail queue](#flushing-mails-from-a-mail-queue)
+ - [Listing mail queues](#Listing_mail_queues)
+ - [Getting a mail queue details](#Getting_a_mail_queue_details)
+ - [Listing the mails of a mail queue](#Listing_the_mails_of_a_mail_queue)
+ - [Deleting mails from a mail queue](#Deleting_mails_from_a_mail_queue)
+ - [Clearing a mail queue](#Clearing_a_mail_queue)
+ - [Flushing mails from a mail queue](#Flushing_mails_from_a_mail_queue)
 
 ### Listing mail queues
 
@@ -1742,10 +1760,10 @@ Some webadmin features schedules tasks. The task management API allow to monitor
 
 Note that the `taskId` used in the following APIs is returned by other WebAdmin APIs scheduling tasks.
 
- - [Getting a task details](#getting-a-task-details)
- - [Awaiting a task](#awaiting-a-task)
- - [Cancelling a task](#cancelling-a-task)
- - [Listing tasks](#listing-tasks)
+ - [Getting a task details](#Getting_a_task_details)
+ - [Awaiting a task](#Awaiting_a_task)
+ - [Cancelling a task](#Cancelling_a_task)
+ - [Listing tasks](#Listing_tasks)
 
 ### Getting a task details
 


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