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 ro...@apache.org on 2018/06/27 13:51:04 UTC

[1/2] james-project git commit: JAMES-2425 Do not leak protocol over webadmin

Repository: james-project
Updated Branches:
  refs/heads/master c9f8c9c72 -> ee71575a6


http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/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 4f752c9..c451ff4 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
@@ -59,6 +59,7 @@ import org.apache.james.core.MailAddress;
 import org.apache.james.core.builder.MimeMessageBuilder;
 import org.apache.james.core.builder.MimeMessageBuilder.BodyPartBuilder;
 import org.apache.james.mailrepository.api.MailKey;
+import org.apache.james.mailrepository.api.MailRepositoryPath;
 import org.apache.james.mailrepository.api.MailRepositoryStore;
 import org.apache.james.mailrepository.api.MailRepositoryUrl;
 import org.apache.james.mailrepository.memory.MemoryMailRepository;
@@ -86,6 +87,7 @@ import org.eclipse.jetty.http.HttpStatus;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.stubbing.Answer;
 
 import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableList;
@@ -97,14 +99,17 @@ import com.jayway.restassured.parsing.Parser;
 public class MailRepositoriesRoutesTest {
 
     private static final MailRepositoryUrl URL_MY_REPO = MailRepositoryUrl.from("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 MailRepositoryPath PATH_MY_REPO = MailRepositoryPath.from("myRepo");
+    private static final String PATH_ESCAPED_MY_REPO = "myRepo";
+    private static final String MY_REPO_MAILS = "myRepo/mails";
     private static final String CUSTOM_QUEUE = "customQueue";
     private static final String NAME_1 = "name1";
     private static final String NAME_2 = "name2";
+    private static final Answer<?> RETURN_NO_MAIL_REPOSITORY = (invocation) -> Stream.empty();
     private WebAdminServer webAdminServer;
     private MailRepositoryStore mailRepositoryStore;
     private MemoryMailRepository mailRepository;
+    private Answer<?> returnMailRepository;
     private ManageableMailQueue spoolQueue;
     private ManageableMailQueue customQueue;
 
@@ -112,6 +117,7 @@ public class MailRepositoriesRoutesTest {
     public void setUp() throws Exception {
         mailRepositoryStore = mock(MailRepositoryStore.class);
         mailRepository = new MemoryMailRepository();
+        returnMailRepository = (invocation) -> Stream.of(mailRepository);
 
         MemoryTaskManager taskManager = new MemoryTaskManager();
         JsonTransformer jsonTransformer = new JsonTransformer();
@@ -144,8 +150,10 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void putMailRepositoryShouldReturnOkWhenRepositoryIsCreated() throws Exception {
-        when()
-            .put(URL_ESCAPED_MY_REPO)
+        given()
+            .parameters("protocol", "url")
+        .when()
+            .put(PATH_ESCAPED_MY_REPO)
         .then()
             .statusCode(HttpStatus.NO_CONTENT_204);
 
@@ -155,13 +163,17 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void putMailRepositoryShouldReturnOkWhenRepositoryAlreadyExists() throws Exception {
-        when()
-            .put(URL_ESCAPED_MY_REPO)
+        given()
+            .parameters("protocol", "url")
+        .when()
+            .put(PATH_ESCAPED_MY_REPO)
         .then()
             .statusCode(HttpStatus.NO_CONTENT_204);
 
-        when()
-            .put(URL_ESCAPED_MY_REPO)
+        given()
+            .parameters("protocol", "url")
+        .when()
+            .put(PATH_ESCAPED_MY_REPO)
         .then()
             .statusCode(HttpStatus.NO_CONTENT_204);
 
@@ -174,19 +186,21 @@ public class MailRepositoriesRoutesTest {
         when(mailRepositoryStore.create(any()))
             .thenThrow(new MailRepositoryStore.MailRepositoryStoreException("Error while selecting repository url://myRepo"));
 
-        when()
-            .put(URL_ESCAPED_MY_REPO)
+        given()
+            .parameters("protocol", "url")
+        .when()
+            .put(PATH_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("message", is("Error while creating a mail repository with path 'myRepo' and protocol 'url'"))
             .body("details", is("Error while selecting repository url://myRepo"));
     }
 
     @Test
     public void getMailRepositoriesShouldReturnEmptyWhenEmpty() {
-        when(mailRepositoryStore.getUrls()).thenReturn(Stream.empty());
+        when(mailRepositoryStore.getPaths()).thenAnswer(RETURN_NO_MAIL_REPOSITORY);
 
         List<Object> mailRepositories =
             when()
@@ -204,22 +218,22 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void getMailRepositoriesShouldReturnRepositoryWhenOne() {
-        when(mailRepositoryStore.getUrls())
-            .thenReturn(Stream.of(URL_MY_REPO));
+        when(mailRepositoryStore.getPaths())
+            .thenAnswer((invocation) -> Stream.of(PATH_MY_REPO));
 
         when()
             .get()
         .then()
             .statusCode(HttpStatus.OK_200)
             .body("", hasSize(1))
-            .body("[0].repository", is(URL_MY_REPO.asString()))
-            .body("[0].id", is(URL_ESCAPED_MY_REPO));
+            .body("[0].repository", is(PATH_MY_REPO.asString()))
+            .body("[0].path", is(PATH_ESCAPED_MY_REPO));
     }
 
     @Test
     public void getMailRepositoriesShouldReturnTwoRepositoriesWhenTwo() {
-        ImmutableList<MailRepositoryUrl> myRepositories = ImmutableList.of(URL_MY_REPO, MailRepositoryUrl.from("url://mySecondRepo"));
-        when(mailRepositoryStore.getUrls())
+        ImmutableList<MailRepositoryPath> myRepositories = ImmutableList.of(PATH_MY_REPO, MailRepositoryPath.from("mySecondRepo"));
+        when(mailRepositoryStore.getPaths())
             .thenReturn(myRepositories.stream());
 
         List<String> mailRepositories =
@@ -235,24 +249,24 @@ public class MailRepositoriesRoutesTest {
 
         assertThat(mailRepositories)
             .containsOnlyElementsOf(myRepositories.stream()
-                .map(MailRepositoryUrl::asString)
+                .map(MailRepositoryPath::asString)
                 .collect(Guavate.toImmutableList()));
     }
 
     @Test
     public void listingKeysShouldReturnNotFoundWhenNoRepository() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.empty());
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(RETURN_NO_MAIL_REPOSITORY);
 
         when()
             .get(MY_REPO_MAILS)
         .then()
             .statusCode(HttpStatus.NOT_FOUND_404)
-            .body("message", is("The repository 'url%3A%2F%2FmyRepo' (decoded value: 'url://myRepo') does not exist"));
+            .body("message", is("myRepo does not exist"));
     }
 
     @Test
     public void listingKeysShouldReturnEmptyWhenNoMail() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         when()
             .get(MY_REPO_MAILS)
@@ -263,7 +277,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void listingKeysShouldReturnContainedKeys() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         mailRepository.store(FakeMail.builder()
             .name("name1")
@@ -282,7 +296,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void listingKeysShouldApplyLimitAndOffset() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         mailRepository.store(FakeMail.builder()
             .name("name1")
@@ -307,7 +321,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void listingKeysShouldHandleErrorGracefully() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO))
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO))
             .thenThrow(new MailRepositoryStore.MailRepositoryStoreException("message"));
 
         when()
@@ -348,7 +362,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void listingKeysShouldReturnEmptyWhenOffsetExceedsSize() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         mailRepository.store(FakeMail.builder()
             .name("name1")
@@ -397,7 +411,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void listingKeysShouldIgnoreZeroedOffset() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         mailRepository.store(FakeMail.builder()
             .name(NAME_1)
@@ -431,33 +445,33 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void retrievingRepositoryShouldReturnNotFoundWhenNone() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.empty());
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(RETURN_NO_MAIL_REPOSITORY);
 
         given()
-            .get(URL_ESCAPED_MY_REPO)
+            .get(PATH_ESCAPED_MY_REPO)
         .then()
             .statusCode(HttpStatus.NOT_FOUND_404);
     }
 
     @Test
     public void retrievingRepositoryShouldReturnBasicInformation() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         given()
-            .get(URL_ESCAPED_MY_REPO)
+            .get(PATH_ESCAPED_MY_REPO)
         .then()
             .statusCode(HttpStatus.OK_200)
             .contentType(ContentType.JSON)
-            .body("repository", is(URL_MY_REPO.asString()))
-            .body("id", is(URL_ESCAPED_MY_REPO));
+            .body("repository", is(PATH_MY_REPO.asString()))
+            .body("path", is(PATH_ESCAPED_MY_REPO));
     }
 
     @Test
     public void retrievingRepositorySizeShouldReturnZeroWhenEmpty() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         given()
-            .get(URL_ESCAPED_MY_REPO)
+            .get(PATH_ESCAPED_MY_REPO)
         .then()
             .statusCode(HttpStatus.OK_200)
             .contentType(ContentType.JSON)
@@ -466,14 +480,14 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void retrievingRepositorySizeShouldReturnNumberOfContainedMails() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         mailRepository.store(FakeMail.builder()
             .name(NAME_1)
             .build());
 
         given()
-            .get(URL_ESCAPED_MY_REPO)
+            .get(PATH_ESCAPED_MY_REPO)
         .then()
             .statusCode(HttpStatus.OK_200)
             .contentType(ContentType.JSON)
@@ -482,7 +496,8 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void retrievingAMailShouldDisplayItsInformation() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
+
         String name = NAME_1;
         String sender = "sender@domain";
         String recipient1 = "recipient1@domain";
@@ -504,7 +519,7 @@ public class MailRepositoriesRoutesTest {
             .build());
 
         when()
-            .get(URL_ESCAPED_MY_REPO + "/mails/" + name)
+            .get(PATH_ESCAPED_MY_REPO + "/mails/" + name)
         .then()
             .statusCode(HttpStatus.OK_200)
             .body("name", is(name))
@@ -520,7 +535,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void retrievingAMailShouldDisplayAllAdditionalFieldsWhenRequested() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         String name = NAME_1;
 
         BodyPartBuilder textMessage = MimeMessageBuilder.bodyPartBuilder()
@@ -571,7 +586,7 @@ public class MailRepositoriesRoutesTest {
             given()
                 .parameters("additionalFields", "attributes,headers,textBody,htmlBody,messageSize,perRecipientsHeaders")
             .when()
-                .get(URL_ESCAPED_MY_REPO + "/mails/" + name)
+            .get(PATH_ESCAPED_MY_REPO + "/mails/" + NAME_1)
             .then()
             .extract()
                 .body()
@@ -623,7 +638,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void retrievingAMailShouldDisplayAllValidAdditionalFieldsWhenRequested() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         String name = NAME_1;
         String sender = "sender@domain";
         String recipient1 = "recipient1@domain";
@@ -638,7 +653,7 @@ public class MailRepositoriesRoutesTest {
         given()
             .parameters("additionalFields", ",,,messageSize")
         .when()
-            .get(URL_ESCAPED_MY_REPO + "/mails/" + name)
+            .get(PATH_ESCAPED_MY_REPO + "/mails/" + NAME_1)
         .then()
             .statusCode(HttpStatus.OK_200)
             .body("name", is(name))
@@ -653,7 +668,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void retrievingAMailShouldDisplayCorrectlyEncodedHeadersInValidAdditionalFieldsWhenRequested() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         String name = NAME_1;
         String sender = "sender@domain";
         String recipient1 = "recipient1@domain";
@@ -671,7 +686,7 @@ public class MailRepositoriesRoutesTest {
         given()
             .parameters("additionalFields", "headers")
         .when()
-            .get(URL_ESCAPED_MY_REPO + "/mails/" + name)
+            .get(PATH_ESCAPED_MY_REPO + "/mails/" + NAME_1)
         .then()
             .statusCode(HttpStatus.OK_200)
             .body("name", is(name))
@@ -681,7 +696,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void retrievingAMailShouldDisplayAllValidAdditionalFieldsEvenTheDuplicatedOnesWhenRequested() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         String name = NAME_1;
         String sender = "sender@domain";
         String recipient1 = "recipient1@domain";
@@ -696,7 +711,7 @@ public class MailRepositoriesRoutesTest {
         given()
             .parameters("additionalFields", "messageSize,messageSize")
         .when()
-            .get(URL_ESCAPED_MY_REPO + "/mails/" + name)
+            .get(PATH_ESCAPED_MY_REPO + "/mails/" + NAME_1)
         .then()
             .statusCode(HttpStatus.OK_200)
             .body("name", is(name))
@@ -711,7 +726,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void retrievingAMailShouldFailWhenAnUnknownFieldIsRequested() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         String name = NAME_1;
         String sender = "sender@domain";
         String recipient1 = "recipient1@domain";
@@ -726,7 +741,7 @@ public class MailRepositoriesRoutesTest {
         given()
             .parameters("additionalFields", "nonExistingField")
         .when()
-            .get(URL_ESCAPED_MY_REPO + "/mails/" + name)
+            .get(PATH_ESCAPED_MY_REPO + "/mails/" + NAME_1)
         .then()
             .statusCode(HttpStatus.BAD_REQUEST_400)
             .body("statusCode", is(400))
@@ -736,14 +751,14 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void retrievingAMailShouldNotFailWhenOnlyNameProperty() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         mailRepository.store(FakeMail.builder()
             .name(NAME_1)
             .build());
 
         when()
-            .get(URL_ESCAPED_MY_REPO + "/mails/" + NAME_1)
+            .get(PATH_ESCAPED_MY_REPO + "/mails/" + NAME_1)
         .then()
             .statusCode(HttpStatus.OK_200)
             .body("name", is(NAME_1))
@@ -755,11 +770,11 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void retrievingAMailShouldFailWhenUnknown() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         String name = "name";
         when()
-            .get(URL_ESCAPED_MY_REPO + "/mails/" + name)
+            .get(PATH_ESCAPED_MY_REPO + "/mails/" + name)
         .then()
             .statusCode(HttpStatus.NOT_FOUND_404)
             .body("statusCode", is(404))
@@ -774,7 +789,7 @@ public class MailRepositoriesRoutesTest {
                 .build();
         RestAssured.registerParser(Constants.RFC822_CONTENT_TYPE, Parser.TEXT);
 
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         String name = NAME_1;
         FakeMail mail = FakeMail.builder()
@@ -788,7 +803,7 @@ public class MailRepositoriesRoutesTest {
         String actualContent = given()
             .accept(Constants.RFC822_CONTENT_TYPE)
         .when()
-            .get(URL_ESCAPED_MY_REPO + "/mails/" + name)
+            .get(PATH_ESCAPED_MY_REPO + "/mails/" + name)
         .then()
             .statusCode(HttpStatus.OK_200)
             .header("Content-Length", "471")
@@ -807,13 +822,13 @@ public class MailRepositoriesRoutesTest {
             .build();
         RestAssured.registerParser(Constants.RFC822_CONTENT_TYPE, Parser.TEXT);
 
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         String name = "name";
         given()
             .accept(Constants.RFC822_CONTENT_TYPE)
         .when()
-            .get(URL_ESCAPED_MY_REPO + "/mails/" + name)
+            .get(PATH_ESCAPED_MY_REPO + "/mails/" + name)
         .then()
             .statusCode(HttpStatus.NOT_FOUND_404)
             .body("statusCode", is(404))
@@ -823,7 +838,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void deletingAMailShouldRemoveIt() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         mailRepository.store(FakeMail.builder()
             .name(NAME_1)
@@ -833,10 +848,10 @@ public class MailRepositoriesRoutesTest {
             .build());
 
         given()
-            .delete(URL_ESCAPED_MY_REPO + "/mails/" + NAME_1);
+            .delete(PATH_ESCAPED_MY_REPO + "/mails/" + NAME_1);
 
         when()
-            .get(URL_ESCAPED_MY_REPO + "/mails")
+            .get(PATH_ESCAPED_MY_REPO + "/mails")
             .then()
             .statusCode(HttpStatus.OK_200)
             .body("", hasSize(1))
@@ -845,34 +860,34 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void deletingAMailShouldReturnOkWhenExist() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         mailRepository.store(FakeMail.builder()
             .name(NAME_1)
             .build());
 
         when()
-            .delete(URL_ESCAPED_MY_REPO + "/mails/" + NAME_1)
+            .delete(PATH_ESCAPED_MY_REPO + "/mails/" + NAME_1)
         .then()
             .statusCode(HttpStatus.NO_CONTENT_204);
     }
 
     @Test
     public void deletingAMailShouldReturnOkWhenNotExist() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         when()
-            .delete(URL_ESCAPED_MY_REPO + "/mails/name")
+            .delete(PATH_ESCAPED_MY_REPO + "/mails/name")
         .then()
             .statusCode(HttpStatus.NO_CONTENT_204);
     }
 
     @Test
     public void deletingAllMailsShouldCreateATask() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         when()
-            .delete(URL_ESCAPED_MY_REPO + "/mails")
+            .delete(PATH_ESCAPED_MY_REPO + "/mails")
         .then()
             .statusCode(HttpStatus.CREATED_201)
             .header("Location", is(notNullValue()))
@@ -881,7 +896,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void clearTaskShouldHaveDetails() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         mailRepository.store(FakeMail.builder()
             .name(NAME_1)
@@ -891,7 +906,7 @@ public class MailRepositoriesRoutesTest {
             .build());
 
         String taskId = with()
-            .delete(URL_ESCAPED_MY_REPO + "/mails")
+            .delete(PATH_ESCAPED_MY_REPO + "/mails")
             .jsonPath()
             .get("taskId");
 
@@ -903,7 +918,7 @@ public class MailRepositoriesRoutesTest {
             .body("status", is("completed"))
             .body("taskId", is(notNullValue()))
             .body("type", is(ClearMailRepositoryTask.TYPE))
-            .body("additionalInformation.repositoryUrl", is(URL_MY_REPO.asString()))
+            .body("additionalInformation.repositoryPath", is(PATH_MY_REPO.asString()))
             .body("additionalInformation.initialCount", is(2))
             .body("additionalInformation.remainingCount", is(0))
             .body("startedDate", is(notNullValue()))
@@ -913,7 +928,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void clearTaskShouldRemoveAllTheMailsFromTheMailRepository() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         mailRepository.store(FakeMail.builder()
             .name(NAME_1)
@@ -923,7 +938,7 @@ public class MailRepositoriesRoutesTest {
             .build());
 
         String taskId = with()
-            .delete(URL_ESCAPED_MY_REPO + "/mails")
+            .delete(PATH_ESCAPED_MY_REPO + "/mails")
             .jsonPath()
             .get("taskId");
 
@@ -932,7 +947,7 @@ public class MailRepositoriesRoutesTest {
             .get(taskId + "/await");
 
         when()
-            .get(URL_ESCAPED_MY_REPO + "/mails")
+            .get(PATH_ESCAPED_MY_REPO + "/mails")
         .then()
             .statusCode(HttpStatus.OK_200)
             .body("", hasSize(0));
@@ -940,38 +955,38 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void patchShouldReturnNotFoundWhenNoMailRepository() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.empty());
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(RETURN_NO_MAIL_REPOSITORY);
 
         when()
-            .delete(URL_ESCAPED_MY_REPO + "/mails")
+            .delete(PATH_ESCAPED_MY_REPO + "/mails")
         .then()
             .statusCode(HttpStatus.NOT_FOUND_404)
             .body("statusCode", is(404))
             .body("type", is(ErrorResponder.ErrorType.NOT_FOUND.getType()))
-            .body("message", is(URL_MY_REPO.asString() + " does not exist"));
+            .body("message", is(PATH_MY_REPO.asString() + " does not exist"));
     }
 
     @Test
     public void deleteShouldReturnNotFoundWhenNoMailRepository() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.empty());
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(RETURN_NO_MAIL_REPOSITORY);
 
         when()
-            .delete(URL_ESCAPED_MY_REPO + "/mails/any")
+            .delete(PATH_ESCAPED_MY_REPO + "/mails/any")
         .then()
             .statusCode(HttpStatus.NOT_FOUND_404)
             .body("statusCode", is(404))
             .body("type", is(ErrorResponder.ErrorType.NOT_FOUND.getType()))
-            .body("message", is(URL_MY_REPO.asString() + " does not exist"));
+            .body("message", is(PATH_MY_REPO.asString() + " does not exist"));
     }
 
     @Test
     public void reprocessingAllTaskShouldCreateATask() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
 
         given()
             .param("action", "reprocess")
         .when()
-            .patch(URL_ESCAPED_MY_REPO + "/mails")
+            .patch(PATH_ESCAPED_MY_REPO + "/mails")
         .then()
             .statusCode(HttpStatus.CREATED_201)
             .header("Location", is(notNullValue()))
@@ -985,7 +1000,7 @@ public class MailRepositoriesRoutesTest {
         given()
             .param("action", "invalid")
         .when()
-            .patch(URL_ESCAPED_MY_REPO + "/mails")
+            .patch(PATH_ESCAPED_MY_REPO + "/mails")
         .then()
             .statusCode(HttpStatus.BAD_REQUEST_400)
             .body("statusCode", is(400))
@@ -998,7 +1013,7 @@ public class MailRepositoriesRoutesTest {
         when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
 
         when()
-            .patch(URL_ESCAPED_MY_REPO + "/mails")
+            .patch(PATH_ESCAPED_MY_REPO + "/mails")
         .then()
             .statusCode(HttpStatus.BAD_REQUEST_400)
             .body("statusCode", is(400))
@@ -1008,7 +1023,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void reprocessingAllTaskShouldIncludeDetailsWhenDefaultValues() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         mailRepository.store(FakeMail.builder()
             .name(NAME_1)
             .build());
@@ -1018,7 +1033,7 @@ public class MailRepositoriesRoutesTest {
 
         String taskId = with()
             .param("action", "reprocess")
-            .patch(URL_ESCAPED_MY_REPO + "/mails")
+            .patch(PATH_ESCAPED_MY_REPO + "/mails")
             .jsonPath()
             .get("taskId");
 
@@ -1030,7 +1045,7 @@ public class MailRepositoriesRoutesTest {
             .body("status", is("completed"))
             .body("taskId", is(notNullValue()))
             .body("type", is(ReprocessingAllMailsTask.TYPE))
-            .body("additionalInformation.repositoryUrl", is(URL_MY_REPO.asString()))
+            .body("additionalInformation.repositoryPath", is(PATH_MY_REPO.asString()))
             .body("additionalInformation.initialCount", is(2))
             .body("additionalInformation.remainingCount", is(0))
             .body("additionalInformation.targetProcessor", isEmptyOrNullString())
@@ -1042,7 +1057,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void reprocessingAllTaskShouldIncludeDetails() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         String name1 = "name1";
         String name2 = "name2";
         mailRepository.store(FakeMail.builder()
@@ -1057,7 +1072,7 @@ public class MailRepositoriesRoutesTest {
             .param("action", "reprocess")
             .param("queue", CUSTOM_QUEUE)
             .param("processor", transport)
-            .patch(URL_ESCAPED_MY_REPO + "/mails")
+            .patch(PATH_ESCAPED_MY_REPO + "/mails")
             .jsonPath()
             .get("taskId");
 
@@ -1069,7 +1084,7 @@ public class MailRepositoriesRoutesTest {
             .body("status", is("completed"))
             .body("taskId", is(notNullValue()))
             .body("type", is(ReprocessingAllMailsTask.TYPE))
-            .body("additionalInformation.repositoryUrl", is(URL_MY_REPO.asString()))
+            .body("additionalInformation.repositoryPath", is(PATH_MY_REPO.asString()))
             .body("additionalInformation.initialCount", is(2))
             .body("additionalInformation.remainingCount", is(0))
             .body("additionalInformation.targetProcessor", is(transport))
@@ -1081,7 +1096,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void reprocessingAllTaskShouldClearMailRepository() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         String name1 = "name1";
         String name2 = "name2";
         mailRepository.store(FakeMail.builder()
@@ -1096,7 +1111,7 @@ public class MailRepositoriesRoutesTest {
             .param("action", "reprocess")
             .param("queue", CUSTOM_QUEUE)
             .param("processor", transport)
-            .patch(URL_ESCAPED_MY_REPO + "/mails")
+            .patch(PATH_ESCAPED_MY_REPO + "/mails")
             .jsonPath()
             .get("taskId");
 
@@ -1109,7 +1124,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void reprocessingAllTaskShouldEnqueueMailsOnDefaultQueue() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         mailRepository.store(FakeMail.builder()
             .name(NAME_1)
             .build());
@@ -1119,7 +1134,7 @@ public class MailRepositoriesRoutesTest {
 
         String taskId = with()
             .param("action", "reprocess")
-            .patch(URL_ESCAPED_MY_REPO + "/mails")
+            .patch(PATH_ESCAPED_MY_REPO + "/mails")
             .jsonPath()
             .get("taskId");
 
@@ -1135,7 +1150,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void reprocessingAllTaskShouldPreserveStateWhenProcessorIsNotSpecified() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         String state1 = "state1";
         String state2 = "state2";
         mailRepository.store(FakeMail.builder()
@@ -1149,7 +1164,7 @@ public class MailRepositoriesRoutesTest {
 
         String taskId = with()
             .param("action", "reprocess")
-            .patch(URL_ESCAPED_MY_REPO + "/mails")
+            .patch(PATH_ESCAPED_MY_REPO + "/mails")
             .jsonPath()
             .get("taskId");
 
@@ -1165,7 +1180,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void reprocessingAllTaskShouldOverWriteStateWhenProcessorSpecified() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         String state1 = "state1";
         String state2 = "state2";
         mailRepository.store(FakeMail.builder()
@@ -1181,7 +1196,7 @@ public class MailRepositoriesRoutesTest {
         String taskId = with()
             .param("action", "reprocess")
             .param("processor", transport)
-            .patch(URL_ESCAPED_MY_REPO + "/mails")
+            .patch(PATH_ESCAPED_MY_REPO + "/mails")
             .jsonPath()
             .get("taskId");
 
@@ -1197,7 +1212,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void reprocessingAllTaskShouldEnqueueMailsOnSpecifiedQueue() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         mailRepository.store(FakeMail.builder()
             .name(NAME_1)
             .build());
@@ -1208,7 +1223,7 @@ public class MailRepositoriesRoutesTest {
         String taskId = with()
             .param("action", "reprocess")
             .param("queue", CUSTOM_QUEUE)
-            .patch(URL_ESCAPED_MY_REPO + "/mails")
+            .patch(PATH_ESCAPED_MY_REPO + "/mails")
             .jsonPath()
             .get("taskId");
 
@@ -1233,7 +1248,7 @@ public class MailRepositoriesRoutesTest {
         given()
             .param("action", "reprocess")
         .when()
-            .patch(URL_ESCAPED_MY_REPO + "/mails/name1")
+            .patch(PATH_ESCAPED_MY_REPO + "/mails/name1")
         .then()
             .statusCode(HttpStatus.CREATED_201)
             .header("Location", is(notNullValue()))
@@ -1251,7 +1266,7 @@ public class MailRepositoriesRoutesTest {
         given()
             .param("action", "invalid")
         .when()
-            .patch(URL_ESCAPED_MY_REPO + "/mails/" + NAME_1)
+            .patch(PATH_ESCAPED_MY_REPO + "/mails/" + NAME_1)
         .then()
             .statusCode(HttpStatus.BAD_REQUEST_400)
             .body("statusCode", is(400))
@@ -1268,7 +1283,7 @@ public class MailRepositoriesRoutesTest {
             .build());
 
         when()
-            .patch(URL_ESCAPED_MY_REPO + "/mails/" + NAME_1)
+            .patch(PATH_ESCAPED_MY_REPO + "/mails/" + NAME_1)
         .then()
             .statusCode(HttpStatus.BAD_REQUEST_400)
             .body("statusCode", is(400))
@@ -1278,7 +1293,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void reprocessingOneTaskShouldIncludeDetailsWhenDefaultValues() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         String name1 = "name1";
         String name2 = "name2";
         mailRepository.store(FakeMail.builder()
@@ -1290,7 +1305,7 @@ public class MailRepositoriesRoutesTest {
 
         String taskId = with()
             .param("action", "reprocess")
-            .patch(URL_ESCAPED_MY_REPO + "/mails/" + NAME_1)
+            .patch(PATH_ESCAPED_MY_REPO + "/mails/" + NAME_1)
             .jsonPath()
             .get("taskId");
 
@@ -1302,7 +1317,7 @@ public class MailRepositoriesRoutesTest {
             .body("status", is("completed"))
             .body("taskId", is(notNullValue()))
             .body("type", is(ReprocessingOneMailTask.TYPE))
-            .body("additionalInformation.repositoryUrl", is(URL_MY_REPO.asString()))
+            .body("additionalInformation.repositoryPath", is(PATH_MY_REPO.asString()))
             .body("additionalInformation.mailKey", is(NAME_1))
             .body("additionalInformation.targetProcessor", isEmptyOrNullString())
             .body("additionalInformation.targetQueue", is(MailQueueFactory.SPOOL))
@@ -1313,7 +1328,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void reprocessingOneTaskShouldIncludeDetails() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         String name1 = "name1";
         String name2 = "name2";
         mailRepository.store(FakeMail.builder()
@@ -1328,7 +1343,7 @@ public class MailRepositoriesRoutesTest {
             .param("action", "reprocess")
             .param("queue", CUSTOM_QUEUE)
             .param("processor", transport)
-            .patch(URL_ESCAPED_MY_REPO + "/mails/" + NAME_1)
+            .patch(PATH_ESCAPED_MY_REPO + "/mails/" + NAME_1)
             .jsonPath()
             .get("taskId");
 
@@ -1340,7 +1355,7 @@ public class MailRepositoriesRoutesTest {
             .body("status", is("completed"))
             .body("taskId", is(notNullValue()))
             .body("type", is(ReprocessingOneMailTask.TYPE))
-            .body("additionalInformation.repositoryUrl", is(URL_MY_REPO.asString()))
+            .body("additionalInformation.repositoryPath", is(PATH_MY_REPO.asString()))
             .body("additionalInformation.mailKey", is(NAME_1))
             .body("additionalInformation.targetProcessor", is(transport))
             .body("additionalInformation.targetQueue", is(CUSTOM_QUEUE))
@@ -1351,7 +1366,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void reprocessingOneTaskShouldRemoveMailFromRepository() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         String name1 = "name1";
         String name2 = "name2";
         mailRepository.store(FakeMail.builder()
@@ -1366,7 +1381,7 @@ public class MailRepositoriesRoutesTest {
             .param("action", "reprocess")
             .param("queue", CUSTOM_QUEUE)
             .param("processor", transport)
-            .patch(URL_ESCAPED_MY_REPO + "/mails/" + NAME_1)
+            .patch(PATH_ESCAPED_MY_REPO + "/mails/" + NAME_1)
             .jsonPath()
             .get("taskId");
 
@@ -1380,7 +1395,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void reprocessingOneTaskShouldEnqueueMailsOnDefaultQueue() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         mailRepository.store(FakeMail.builder()
             .name(NAME_1)
             .build());
@@ -1390,7 +1405,7 @@ public class MailRepositoriesRoutesTest {
 
         String taskId = with()
             .param("action", "reprocess")
-            .patch(URL_ESCAPED_MY_REPO + "/mails/" + NAME_1)
+            .patch(PATH_ESCAPED_MY_REPO + "/mails/" + NAME_1)
             .jsonPath()
             .get("taskId");
 
@@ -1406,7 +1421,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void reprocessingOneTaskShouldPreserveStateWhenProcessorIsNotSpecified() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         String state1 = "state1";
         String state2 = "state2";
         mailRepository.store(FakeMail.builder()
@@ -1420,7 +1435,7 @@ public class MailRepositoriesRoutesTest {
 
         String taskId = with()
             .param("action", "reprocess")
-            .patch(URL_ESCAPED_MY_REPO + "/mails/" + NAME_1)
+            .patch(PATH_ESCAPED_MY_REPO + "/mails/" + NAME_1)
             .jsonPath()
             .get("taskId");
 
@@ -1436,7 +1451,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void reprocessingOneTaskShouldOverWriteStateWhenProcessorSpecified() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         String state1 = "state1";
         String state2 = "state2";
         mailRepository.store(FakeMail.builder()
@@ -1452,7 +1467,7 @@ public class MailRepositoriesRoutesTest {
         String taskId = with()
             .param("action", "reprocess")
             .param("processor", transport)
-            .patch(URL_ESCAPED_MY_REPO + "/mails/" + NAME_1)
+            .patch(PATH_ESCAPED_MY_REPO + "/mails/" + NAME_1)
             .jsonPath()
             .get("taskId");
 
@@ -1468,7 +1483,7 @@ public class MailRepositoriesRoutesTest {
 
     @Test
     public void reprocessingOneTaskShouldEnqueueMailsOnSpecifiedQueue() throws Exception {
-        when(mailRepositoryStore.get(URL_MY_REPO)).thenReturn(Optional.of(mailRepository));
+        when(mailRepositoryStore.getByPath(PATH_MY_REPO)).thenAnswer(returnMailRepository);
         mailRepository.store(FakeMail.builder()
             .name(NAME_1)
             .build());
@@ -1479,7 +1494,7 @@ public class MailRepositoriesRoutesTest {
         String taskId = with()
             .param("action", "reprocess")
             .param("queue", CUSTOM_QUEUE)
-            .patch(URL_ESCAPED_MY_REPO + "/mails/" + NAME_1)
+            .patch(PATH_ESCAPED_MY_REPO + "/mails/" + NAME_1)
             .jsonPath()
             .get("taskId");
 
@@ -1506,7 +1521,7 @@ public class MailRepositoriesRoutesTest {
         String taskId = with()
             .param("action", "reprocess")
             .param("queue", CUSTOM_QUEUE)
-            .patch(URL_ESCAPED_MY_REPO + "/mails/" + "unknown")
+            .patch(PATH_ESCAPED_MY_REPO + "/mails/" + "unknown")
             .jsonPath()
             .get("taskId");
 
@@ -1531,7 +1546,7 @@ public class MailRepositoriesRoutesTest {
         String taskId = with()
             .param("action", "reprocess")
             .param("queue", CUSTOM_QUEUE)
-            .patch(URL_ESCAPED_MY_REPO + "/mails/" + "unknown")
+            .patch(PATH_ESCAPED_MY_REPO + "/mails/" + "unknown")
             .jsonPath()
             .get("taskId");
 
@@ -1556,7 +1571,7 @@ public class MailRepositoriesRoutesTest {
         String taskId = with()
             .param("action", "reprocess")
             .param("queue", CUSTOM_QUEUE)
-            .patch(URL_ESCAPED_MY_REPO + "/mails/" + "unknown")
+            .patch(PATH_ESCAPED_MY_REPO + "/mails/" + "unknown")
             .jsonPath()
             .get("taskId");
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/MailRepositoryStoreServiceTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/MailRepositoryStoreServiceTest.java b/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/MailRepositoryStoreServiceTest.java
index b505244..6fac837 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/MailRepositoryStoreServiceTest.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/MailRepositoryStoreServiceTest.java
@@ -31,22 +31,22 @@ import javax.mail.internet.MimeMessage;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.james.mailrepository.api.MailKey;
+import org.apache.james.mailrepository.api.MailRepositoryPath;
 import org.apache.james.mailrepository.api.MailRepositoryStore;
-import org.apache.james.mailrepository.api.MailRepositoryUrl;
 import org.apache.james.mailrepository.memory.MemoryMailRepository;
 import org.apache.james.server.core.MimeMessageInputStream;
 import org.apache.james.util.ClassLoaderUtils;
 import org.apache.james.util.streams.Limit;
 import org.apache.james.util.streams.Offset;
 import org.apache.james.webadmin.dto.MailKeyDTO;
-import org.apache.james.webadmin.dto.MailRepositoryResponse;
+import org.apache.james.webadmin.dto.SingleMailRepositoryResponse;
 import org.apache.mailet.base.test.FakeMail;
 import org.junit.Before;
 import org.junit.Test;
 
 public class MailRepositoryStoreServiceTest {
-    private static final MailRepositoryUrl FIRST_REPOSITORY = MailRepositoryUrl.from("url://repository");
-    private static final MailRepositoryUrl SECOND_REPOSITORY = MailRepositoryUrl.from("url://repository2");
+    private static final MailRepositoryPath FIRST_REPOSITORY_PATH = MailRepositoryPath.from("repository");
+    private static final MailRepositoryPath SECOND_REPOSITORY_PATH = MailRepositoryPath.from("repository2");
     private static final MailKey NAME_1 = new MailKey("name1");
     private static final MailKey NAME_2 = new MailKey("name2");
 
@@ -63,49 +63,49 @@ public class MailRepositoryStoreServiceTest {
 
     @Test
     public void listMailRepositoriesShouldReturnEmptyWhenEmpty() {
-        when(mailRepositoryStore.getUrls()).thenReturn(Stream.empty());
+        when(mailRepositoryStore.getPaths()).thenReturn(Stream.empty());
 
         assertThat(testee.listMailRepositories()).isEmpty();
     }
 
     @Test
     public void listMailRepositoriesShouldReturnOneRepositoryWhenOne() {
-        when(mailRepositoryStore.getUrls())
-            .thenReturn(Stream.of(FIRST_REPOSITORY));
+        when(mailRepositoryStore.getPaths())
+            .thenReturn(Stream.of(FIRST_REPOSITORY_PATH));
         assertThat(testee.listMailRepositories())
-            .extracting(MailRepositoryResponse::getRepository)
-            .containsOnly(FIRST_REPOSITORY.asString());
+            .extracting(SingleMailRepositoryResponse::getRepository)
+            .containsOnly(FIRST_REPOSITORY_PATH.asString());
     }
 
     @Test
     public void listMailRepositoriesShouldReturnTwoRepositoriesWhentwo() {
-        when(mailRepositoryStore.getUrls())
-            .thenReturn(Stream.of(FIRST_REPOSITORY, SECOND_REPOSITORY));
+        when(mailRepositoryStore.getPaths())
+            .thenReturn(Stream.of(FIRST_REPOSITORY_PATH, SECOND_REPOSITORY_PATH));
         assertThat(testee.listMailRepositories())
-            .extracting(MailRepositoryResponse::getRepository)
-            .containsOnly(FIRST_REPOSITORY.asString(), SECOND_REPOSITORY.asString());
+            .extracting(SingleMailRepositoryResponse::getRepository)
+            .containsOnly(FIRST_REPOSITORY_PATH.asString(), SECOND_REPOSITORY_PATH.asString());
     }
 
     @Test
     public void listMailsShouldThrowWhenMailRepositoryStoreThrows() throws Exception {
-        when(mailRepositoryStore.get(FIRST_REPOSITORY))
+        when(mailRepositoryStore.getByPath(FIRST_REPOSITORY_PATH))
             .thenThrow(new MailRepositoryStore.MailRepositoryStoreException("message"));
 
-        assertThatThrownBy(() -> testee.listMails(FIRST_REPOSITORY, Offset.none(), Limit.unlimited()))
+        assertThatThrownBy(() -> testee.listMails(FIRST_REPOSITORY_PATH, Offset.none(), Limit.unlimited()))
             .isInstanceOf(MailRepositoryStore.MailRepositoryStoreException.class);
     }
 
     @Test
     public void listMailsShouldReturnEmptyWhenMailRepositoryIsEmpty() throws Exception {
-        when(mailRepositoryStore.get(FIRST_REPOSITORY)).thenReturn(Optional.of(repository));
+        when(mailRepositoryStore.getByPath(FIRST_REPOSITORY_PATH)).thenReturn(Stream.of(repository));
 
-        assertThat(testee.listMails(FIRST_REPOSITORY, Offset.none(), Limit.unlimited()).get())
+        assertThat(testee.listMails(FIRST_REPOSITORY_PATH, Offset.none(), Limit.unlimited()).get())
             .isEmpty();
     }
 
     @Test
     public void listMailsShouldReturnContainedMailKeys() throws Exception {
-        when(mailRepositoryStore.get(FIRST_REPOSITORY)).thenReturn(Optional.of(repository));
+        when(mailRepositoryStore.getByPath(FIRST_REPOSITORY_PATH)).thenReturn(Stream.of(repository));
 
         repository.store(FakeMail.builder()
             .name(NAME_1.asString())
@@ -114,13 +114,13 @@ public class MailRepositoryStoreServiceTest {
             .name(NAME_2.asString())
             .build());
 
-        assertThat(testee.listMails(FIRST_REPOSITORY, Offset.none(), Limit.unlimited()).get())
+        assertThat(testee.listMails(FIRST_REPOSITORY_PATH, Offset.none(), Limit.unlimited()).get())
             .containsOnly(new MailKeyDTO(NAME_1), new MailKeyDTO(NAME_2));
     }
 
     @Test
     public void listMailsShouldApplyLimitAndOffset() throws Exception {
-        when(mailRepositoryStore.get(FIRST_REPOSITORY)).thenReturn(Optional.of(repository));
+        when(mailRepositoryStore.getByPath(FIRST_REPOSITORY_PATH)).thenReturn(Stream.of(repository));
 
         repository.store(FakeMail.builder()
             .name(NAME_1.asString())
@@ -132,38 +132,38 @@ public class MailRepositoryStoreServiceTest {
             .name("name3")
             .build());
 
-        assertThat(testee.listMails(FIRST_REPOSITORY, Offset.from(1), Limit.from(1)).get())
+        assertThat(testee.listMails(FIRST_REPOSITORY_PATH, Offset.from(1), Limit.from(1)).get())
             .containsOnly(new MailKeyDTO(NAME_2));
     }
 
     @Test
     public void retrieveMessageShouldThrownWhenUnknownRepository() throws Exception {
-        when(mailRepositoryStore.get(MailRepositoryUrl.from("proto://unkown"))).thenReturn(Optional.empty());
+        when(mailRepositoryStore.getByPath(FIRST_REPOSITORY_PATH)).thenReturn(Stream.of());
 
-        assertThatThrownBy(() -> testee.retrieveMessage(FIRST_REPOSITORY, NAME_1))
-            .isInstanceOf(NullPointerException.class);
+        assertThatThrownBy(() -> testee.retrieveMessage(FIRST_REPOSITORY_PATH, NAME_1))
+            .isNotInstanceOf(NullPointerException.class);
     }
 
     @Test
     public void retrieveMessageShouldThrowWhenMailRepositoryStoreThrows() throws Exception {
-        when(mailRepositoryStore.get(FIRST_REPOSITORY))
+        when(mailRepositoryStore.getByPath(FIRST_REPOSITORY_PATH))
             .thenThrow(new MailRepositoryStore.MailRepositoryStoreException("message"));
 
-        assertThatThrownBy(() -> testee.retrieveMessage(FIRST_REPOSITORY, NAME_1))
+        assertThatThrownBy(() -> testee.retrieveMessage(FIRST_REPOSITORY_PATH, NAME_1))
             .isInstanceOf(MailRepositoryStore.MailRepositoryStoreException.class);
     }
 
     @Test
     public void retrieveMessageShouldReturnEmptyWhenMailNotFound() throws Exception {
-        when(mailRepositoryStore.get(FIRST_REPOSITORY)).thenReturn(Optional.of(repository));
+        when(mailRepositoryStore.getByPath(FIRST_REPOSITORY_PATH)).thenReturn(Stream.of(repository));
 
-        assertThat(testee.retrieveMessage(FIRST_REPOSITORY, NAME_1))
+        assertThat(testee.retrieveMessage(FIRST_REPOSITORY_PATH, NAME_1))
             .isEmpty();
     }
 
     @Test
     public void retrieveMessageShouldReturnTheMessageWhenMailExists() throws Exception {
-        when(mailRepositoryStore.get(FIRST_REPOSITORY)).thenReturn(Optional.of(repository));
+        when(mailRepositoryStore.getByPath(FIRST_REPOSITORY_PATH)).thenReturn(Stream.of(repository));
 
         FakeMail mail = FakeMail.builder()
             .name(NAME_1.asString())
@@ -171,7 +171,7 @@ public class MailRepositoryStoreServiceTest {
             .build();
         repository.store(mail);
 
-        Optional<MimeMessage> mimeMessage = testee.retrieveMessage(FIRST_REPOSITORY, NAME_1);
+        Optional<MimeMessage> mimeMessage = testee.retrieveMessage(FIRST_REPOSITORY_PATH, NAME_1);
         assertThat(mimeMessage).isNotEmpty();
 
         String eml = IOUtils.toString(new MimeMessageInputStream(mimeMessage.get()), StandardCharsets.UTF_8);

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/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 6708a26..a161a97 100644
--- a/src/site/markdown/server/manage-webadmin.md
+++ b/src/site/markdown/server/manage-webadmin.md
@@ -1220,13 +1220,13 @@ Response codes:
 ### Create a mail repository
 
 ```
-curl -XPUT http://ip:port/mailRepositories/encodedUrlOfTheRepository
+curl -XPUT http://ip:port/mailRepositories/encodedPathOfTheRepository?protocol=someProtocol
 ```
 
-Resource name `encodedUrlOfTheRepository` should be the resource id of the created mail repository. Example:
+Resource name `encodedPathOfTheRepository` should be the resource path of the created mail repository. Example:
 
 ```
-curl -XPUT http://ip:port/mailRepositories/file%3A%2F%2FmailRepo
+curl -XPUT http://ip:port/mailRepositories/mailRepo?protocol=file
 ```
 
 Response codes:
@@ -1244,20 +1244,20 @@ The answer looks like:
 ```
 [
     {
-        "repository": "file://var/mail/error/",
-        "id": "file%3A%2F%2Fvar%2Fmail%2Ferror%2F"
+        "repository": "var/mail/error/",
+        "path": "var%2Fmail%2Ferror%2F"
     },
     {
-        "repository": "file://var/mail/relay-denied/",
-        "id": "file%3A%2F%2Fvar%2Fmail%2Frelay-denied%2F"
+        "repository": "var/mail/relay-denied/",
+        "path": "var%2Fmail%2Frelay-denied%2F"
     },
     {
-        "repository": "file://var/mail/spam/",
-        "id": "file%3A%2F%2Fvar%2Fmail%2Fspam%2F"
+        "repository": "var/mail/spam/",
+        "path": "var%2Fmail%2Fspam%2F"
     },
     {
-        "repository": "file://var/mail/address-error/",
-        "id": "file%3A%2F%2Fvar%2Fmail%2Faddress-error%2F"
+        "repository": "var/mail/address-error/",
+        "path": "var%2Fmail%2Faddress-error%2F"
     }
 ]
 ```
@@ -1271,21 +1271,21 @@ Response codes:
 ### Getting additional information for a mail repository
 
 ```
-curl -XGET http://ip:port/mailRepositories/encodedUrlOfTheRepository/
+curl -XGET http://ip:port/mailRepositories/encodedPathOfTheRepository/
 ```
 
-Resource name `encodedUrlOfTheRepository` should be the resource id of an existing mail repository. Example:
+Resource name `encodedPathOfTheRepository` should be the resource path of an existing mail repository. Example:
 
 ```
-curl -XGET http://ip:port/mailRepositories/file%3A%2F%2Fvar%2Fmail%2Ferror%2F/
+curl -XGET http://ip:port/mailRepositories/var%2Fmail%2Ferror%2F/
 ```
 
 The answer looks like:
 
 ```
 {
-   "repository": "file://var/mail/error/",
-   "id": "file%3A%2F%2Fvar%2Fmail%2Ferror%2F",
+   "repository": "var/mail/error/",
+   "path": "mail%2Ferror%2F",
    "size": 243
 }
 ```
@@ -1298,13 +1298,13 @@ Response codes:
 ### Listing mails contained in a mail repository
 
 ```
-curl -XGET http://ip:port/mailRepositories/encodedUrlOfTheRepository/mails
+curl -XGET http://ip:port/mailRepositories/encodedPathOfTheRepository/mails
 ```
 
-Resource name `encodedUrlOfTheRepository` should be the resource id of an existing mail repository. Example:
+Resource name `encodedPathOfTheRepository` should be the resource path of an existing mail repository. Example:
 
 ```
-curl -XGET http://ip:port/mailRepositories/file%3A%2F%2Fvar%2Fmail%2Ferror%2F/mails
+curl -XGET http://ip:port/mailRepositories/var%2Fmail%2Ferror%2F/mails
 ```
 
 The answer will contains all mailKey contained in that repository.
@@ -1326,7 +1326,7 @@ You can pass additional URL parameters to this call in order to limit the output
 Example:
 
 ```
-curl -XGET http://ip:port/mailRepositories/file%3A%2F%2Fvar%2Fmail%2Ferror%2F/mails?limit=100&offset=500
+curl -XGET http://ip:port/mailRepositories/var%2Fmail%2Ferror%2F/mails?limit=100&offset=500
 ```
 
 Response codes:
@@ -1338,13 +1338,13 @@ Response codes:
 ### Reading/downloading a mail details
 
 ```
-curl -XGET http://ip:port/mailRepositories/encodedUrlOfTheRepository/mails/mailKey
+curl -XGET http://ip:port/mailRepositories/encodedPathOfTheRepository/mails/mailKey
 ```
 
-Resource name `encodedUrlOfTheRepository` should be the resource id of an existing mail repository. Resource name `mailKey` should be the key of a mail stored in that repository. Example:
+Resource name `encodedPathOfTheRepository` should be the resource path of an existing mail repository. Resource name `mailKey` should be the key of a mail stored in that repository. Example:
 
 ```
-curl -XGET http://ip:port/mailRepositories/file%3A%2F%2Fvar%2Fmail%2Ferror%2F/mails/mail-key-1
+curl -XGET http://ip:port/mailRepositories/var%2Fmail%2Ferror%2F/mails/mail-key-1
 ```
 
 If the Accept header in the request is "application/json", then the response looks like:
@@ -1427,13 +1427,13 @@ Response codes:
 ### Removing a mail from a mail repository
 
 ```
-curl -XDELETE http://ip:port/mailRepositories/encodedUrlOfTheRepository/mails/mailKey
+curl -XDELETE http://ip:port/mailRepositories/encodedPathOfTheRepository/mails/mailKey
 ```
 
-Resource name `encodedUrlOfTheRepository` should be the resource id of an existing mail repository. Resource name `mailKey` should be the key of a mail stored in that repository. Example:
+Resource name `encodedPathOfTheRepository` should be the resource path of an existing mail repository. Resource name `mailKey` should be the key of a mail stored in that repository. Example:
 
 ```
-curl -XDELETE http://ip:port/mailRepositories/file%3A%2F%2Fvar%2Fmail%2Ferror%2F/mails/mail-key-1
+curl -XDELETE http://ip:port/mailRepositories/var%2Fmail%2Ferror%2F/mails/mail-key-1
 ```
 
 Response codes:
@@ -1445,13 +1445,13 @@ Response codes:
 
 
 ```
-curl -XDELETE http://ip:port/mailRepositories/encodedUrlOfTheRepository/mails
+curl -XDELETE http://ip:port/mailRepositories/encodedPathOfTheRepository/mails
 ```
 
-Resource name `encodedUrlOfTheRepository` should be the resource id of an existing mail repository. Example:
+Resource name `encodedPathOfTheRepository` should be the resource path of an existing mail repository. Example:
 
 ```
-curl -XDELETE http://ip:port/mailRepositories/file%3A%2F%2Fvar%2Fmail%2Ferror%2F/mails
+curl -XDELETE http://ip:port/mailRepositories/var%2Fmail%2Ferror%2F/mails
 ```
 
 The response to that request will be the scheduled `taskId` :
@@ -1477,7 +1477,7 @@ The scheduled task will have the following type `clearMailRepository` and the fo
 
 ```
 {
-  "repositoryUrl":"file://var/mail/error/",
+  "repositoryPath":"var/mail/error/",
   "initialCount": 243,
   "remainingCount": 17
 }
@@ -1490,15 +1490,15 @@ Sometime, you want to re-process emails stored in a mail repository. For instanc
 To reprocess mails from a repository:
 
 ```
-curl -XPATCH http://ip:port/mailRepositories/encodedUrlOfTheRepository/mails?action=reprocess
+curl -XPATCH http://ip:port/mailRepositories/encodedPathOfTheRepository/mails?action=reprocess
 ```
 
-Resource name `encodedUrlOfTheRepository` should be the resource id of an existing mail repository. Example:
+Resource name `encodedPathOfTheRepository` should be the resource path of an existing mail repository. Example:
 
 For instance:
 
 ```
-curl -XPATCH http://ip:port/mailRepositories/file%3A%2F%2Fvar%2Fmail%2Ferror%2F/mails?action=reprocess
+curl -XPATCH http://ip:port/mailRepositories/var%2Fmail%2Ferror%2F/mails?action=reprocess
 ```
 
 Additional query paramaters are supported:
@@ -1509,7 +1509,7 @@ Additional query paramaters are supported:
 For instance:
 
 ```
-curl -XPATCH http://ip:port/mailRepositories/file%3A%2F%2Fvar%2Fmail%2Ferror%2F/mails?action=reprocess&processor=transport&queue=spool
+curl -XPATCH http://ip:port/mailRepositories/var%2Fmail%2Ferror%2F/mails?action=reprocess&processor=transport&queue=spool
 ```
 
 Note that the `action` query parameter is compulsary and can only take value `reprocess`.
@@ -1538,7 +1538,7 @@ The scheduled task will have the following type `reprocessingAllTask` and the fo
 
 ```
 {
-  "repositoryUrl":"file://var/mail/error/",
+  "repositoryPath":"var/mail/error/",
   "targetQueue":"spool",
   "targetProcessor":"transport",
   "initialCount": 243,
@@ -1551,15 +1551,15 @@ The scheduled task will have the following type `reprocessingAllTask` and the fo
 To reprocess a specific mail from a mail repository:
 
 ```
-curl -XPATCH http://ip:port/mailRepositories/encodedUrlOfTheRepository/mails/mailKey?action=reprocess
+curl -XPATCH http://ip:port/mailRepositories/encodedPathOfTheRepository/mails/mailKey?action=reprocess
 ```
 
-Resource name `encodedUrlOfTheRepository` should be the resource id of an existing mail repository. Resource name `mailKey` should be the key of a mail stored in that repository. Example:
+Resource name `encodedPathOfTheRepository` should be the resource id of an existing mail repository. Resource name `mailKey` should be the key of a mail stored in that repository. Example:
 
 For instance:
 
 ```
-curl -XPATCH http://ip:port/mailRepositories/file%3A%2F%2Fvar%2Fmail%2Ferror%2F/mails/name1?action=reprocess
+curl -XPATCH http://ip:port/mailRepositories/var%2Fmail%2Ferror%2F/mails/name1?action=reprocess
 ```
 
 Additional query paramaters are supported:
@@ -1570,7 +1570,7 @@ Additional query paramaters are supported:
 For instance:
 
 ```
-curl -XPATCH http://ip:port/mailRepositories/file%3A%2F%2Fvar%2Fmail%2Ferror%2F/mails/name1?action=reprocess&processor=transport&queue=spool
+curl -XPATCH http://ip:port/mailRepositories/var%2Fmail%2Ferror%2F/mails/name1?action=reprocess&processor=transport&queue=spool
 ```
 
 Note that the `action` query parameter is compulsary and can only take value `reprocess`.
@@ -1599,7 +1599,7 @@ The scheduled task will have the following type `reprocessingOneTask` and the fo
 
 ```
 {
-  "repositoryUrl":"file://var/mail/error/",
+  "repositoryPath":"var/mail/error/",
   "targetQueue":"spool",
   "targetProcessor":"transport",
   "mailKey":"name1"


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


[2/2] james-project git commit: JAMES-2425 Do not leak protocol over webadmin

Posted by ro...@apache.org.
JAMES-2425 Do not leak protocol over 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/ee71575a
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/ee71575a
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/ee71575a

Branch: refs/heads/master
Commit: ee71575a69bd6f6817df90267719b7936a7ad0f5
Parents: c9f8c9c
Author: Gautier DI FOLCO <gd...@linagora.com>
Authored: Fri Jun 15 15:19:36 2018 +0200
Committer: Raphael Ouazana <ra...@linagora.com>
Committed: Wed Jun 27 15:50:05 2018 +0200

----------------------------------------------------------------------
 .../utils/InMemoryMailRepositoryStore.java      |  10 +
 .../utils/InMemoryMailRepositoryStoreTest.java  |  65 +++++
 .../MailRepositoryStoreBeanFactory.java         |  11 +
 .../mailrepository/api/MailRepositoryStore.java |  21 +-
 .../mock/MockMailRepositoryStore.java           |  10 +
 .../transport/mailets/DlpIntegrationTest.java   |   8 +-
 .../transport/mailets/ToRepositoryTest.java     |   4 +-
 .../mailrepository/mailrepository-api/pom.xml   |   5 +
 .../mailrepository/api/MailRepositoryPath.java  |  81 ++++++
 .../mailrepository/api/MailRepositoryUrl.java   |  38 ++-
 .../api/MailRepositoryUrlTest.java              |  40 ++-
 .../WebAdminServerIntegrationTest.java          |  16 +-
 .../dto/ExtendedMailRepositoryResponse.java     |  21 +-
 .../webadmin/dto/MailRepositoryResponse.java    |  19 +-
 .../dto/SingleMailRepositoryResponse.java       |  43 ++++
 .../webadmin/routes/MailRepositoriesRoutes.java | 111 ++++----
 .../service/ClearMailRepositoryTask.java        |  39 +--
 .../service/MailRepositoryStoreService.java     |  82 +++---
 .../service/ReprocessingAllMailsTask.java       |  22 +-
 .../service/ReprocessingOneMailTask.java        |  22 +-
 .../webadmin/service/ReprocessingService.java   |  21 +-
 .../routes/MailRepositoriesRoutesTest.java      | 255 ++++++++++---------
 .../service/MailRepositoryStoreServiceTest.java |  60 ++---
 src/site/markdown/server/manage-webadmin.md     |  80 +++---
 24 files changed, 714 insertions(+), 370 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/InMemoryMailRepositoryStore.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/InMemoryMailRepositoryStore.java b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/InMemoryMailRepositoryStore.java
index 06c2cf3..b93ea77 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/InMemoryMailRepositoryStore.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/InMemoryMailRepositoryStore.java
@@ -34,6 +34,7 @@ import org.apache.commons.configuration.DefaultConfigurationBuilder;
 import org.apache.commons.configuration.HierarchicalConfiguration;
 import org.apache.james.lifecycle.api.Configurable;
 import org.apache.james.mailrepository.api.MailRepository;
+import org.apache.james.mailrepository.api.MailRepositoryPath;
 import org.apache.james.mailrepository.api.MailRepositoryStore;
 import org.apache.james.mailrepository.api.MailRepositoryUrl;
 import org.apache.james.mailrepository.api.MailRepositoryUrlStore;
@@ -101,6 +102,15 @@ public class InMemoryMailRepositoryStore implements MailRepositoryStore, Configu
     }
 
     @Override
+    public Stream<MailRepository> getByPath(MailRepositoryPath path) {
+        return destinationToRepositoryAssociations
+                .keySet()
+                .stream()
+                .filter((MailRepositoryUrl key) -> key.getPath().equals(path))
+                .map(destinationToRepositoryAssociations::get);
+    }
+
+    @Override
     public MailRepository select(MailRepositoryUrl mailRepositoryUrl) {
         return Optional.ofNullable(destinationToRepositoryAssociations.get(mailRepositoryUrl))
             .orElseGet(Throwing.supplier(

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/container/guice/guice-common/src/test/java/org/apache/james/utils/InMemoryMailRepositoryStoreTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/test/java/org/apache/james/utils/InMemoryMailRepositoryStoreTest.java b/server/container/guice/guice-common/src/test/java/org/apache/james/utils/InMemoryMailRepositoryStoreTest.java
index f373bbe..5ad89e4 100644
--- a/server/container/guice/guice-common/src/test/java/org/apache/james/utils/InMemoryMailRepositoryStoreTest.java
+++ b/server/container/guice/guice-common/src/test/java/org/apache/james/utils/InMemoryMailRepositoryStoreTest.java
@@ -28,6 +28,7 @@ import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.HierarchicalConfiguration;
 import org.apache.james.core.builder.MimeMessageBuilder;
 import org.apache.james.mailrepository.api.MailRepository;
+import org.apache.james.mailrepository.api.MailRepositoryPath;
 import org.apache.james.mailrepository.api.MailRepositoryStore;
 import org.apache.james.mailrepository.api.MailRepositoryUrl;
 import org.apache.james.mailrepository.file.FileMailRepository;
@@ -46,6 +47,8 @@ import com.google.common.collect.Sets;
 
 public class InMemoryMailRepositoryStoreTest {
     private static final MailRepositoryUrl FILE_REPO = MailRepositoryUrl.from("file://repo");
+    private static final MailRepositoryUrl MEMORY_REPO = MailRepositoryUrl.from("memory://repo");
+    private static final MailRepositoryPath PATH_REPO = MailRepositoryPath.from("repo");
 
     private MemoryMailRepositoryUrlStore urlStore;
 
@@ -150,6 +153,36 @@ public class InMemoryMailRepositoryStoreTest {
     }
 
     @Test
+    public void getPathsShouldBeEmptyIfNoSelectWerePerformed() {
+        assertThat(repositoryStore.getPaths()).isEmpty();
+    }
+
+    @Test
+    public void getPathsShouldReturnUsedUrls() {
+        MailRepositoryPath path1 = MailRepositoryPath.from("repo1");
+        MailRepositoryPath path2 = MailRepositoryPath.from("repo1");
+        MailRepositoryPath path3 = MailRepositoryPath.from("repo1");
+        repositoryStore.select(MailRepositoryUrl.fromPathAndProtocol(path1, "file"));
+        repositoryStore.select(MailRepositoryUrl.fromPathAndProtocol(path2, "file"));
+        repositoryStore.select(MailRepositoryUrl.fromPathAndProtocol(path3, "file"));
+        assertThat(repositoryStore.getPaths()).containsOnly(path1, path2, path3);
+    }
+
+    @Test
+    public void getPathsResultsShouldNotBeDuplicatedWithTheSameProtocol() {
+        repositoryStore.select(FILE_REPO);
+        repositoryStore.select(FILE_REPO);
+        assertThat(repositoryStore.getPaths()).containsExactly(PATH_REPO);
+    }
+
+    @Test
+    public void getPathsResultsShouldNotBeDuplicatedWithDifferentProtocols() {
+        repositoryStore.select(FILE_REPO);
+        repositoryStore.select(MEMORY_REPO);
+        assertThat(repositoryStore.getPaths()).containsExactly(PATH_REPO);
+    }
+
+    @Test
     public void getShouldReturnEmptyWhenUrlNotInUse() {
         assertThat(repositoryStore.get(FILE_REPO))
             .isEmpty();
@@ -172,6 +205,38 @@ public class InMemoryMailRepositoryStoreTest {
     }
 
     @Test
+    public void getByPathShouldReturnEmptyWhenUrlNotInUse() {
+        assertThat(repositoryStore.getByPath(PATH_REPO))
+            .isEmpty();
+    }
+
+    @Test
+    public void getByPathShouldReturnPreviouslyCreatedMatchingMailRepository() {
+        MailRepository mailRepository = repositoryStore.select(FILE_REPO);
+
+        assertThat(repositoryStore.getByPath(PATH_REPO))
+            .contains(mailRepository);
+    }
+
+    @Test
+    public void getByPathShouldReturnPreviouslyCreatedMatchingMailRepositories() {
+        MailRepository mailRepositoryFile = repositoryStore.select(FILE_REPO);
+        MailRepository mailRepositoryArbitrary = repositoryStore.select(MEMORY_REPO);
+
+        assertThat(repositoryStore.getByPath(PATH_REPO))
+            .contains(mailRepositoryFile)
+            .contains(mailRepositoryArbitrary);
+    }
+
+    @Test
+    public void getByPathShouldReturnEmptyWhenNoMailRepositoriesAreMatching() {
+        repositoryStore.select(FILE_REPO);
+
+        assertThat(repositoryStore.getByPath(MailRepositoryPath.from("unknown")))
+            .isEmpty();
+    }
+
+    @Test
     public void selectShouldNotReturnDifferentResultsWhenUsedInAConcurrentEnvironment() throws Exception {
         MailRepositoryUrl url = MailRepositoryUrl.from("memory://repo");
         int threadCount = 10;

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/container/spring/src/main/java/org/apache/james/container/spring/bean/factory/mailrepositorystore/MailRepositoryStoreBeanFactory.java
----------------------------------------------------------------------
diff --git a/server/container/spring/src/main/java/org/apache/james/container/spring/bean/factory/mailrepositorystore/MailRepositoryStoreBeanFactory.java b/server/container/spring/src/main/java/org/apache/james/container/spring/bean/factory/mailrepositorystore/MailRepositoryStoreBeanFactory.java
index a05b3ca..93deae5 100644
--- a/server/container/spring/src/main/java/org/apache/james/container/spring/bean/factory/mailrepositorystore/MailRepositoryStoreBeanFactory.java
+++ b/server/container/spring/src/main/java/org/apache/james/container/spring/bean/factory/mailrepositorystore/MailRepositoryStoreBeanFactory.java
@@ -34,6 +34,7 @@ import org.apache.commons.configuration.HierarchicalConfiguration;
 import org.apache.james.container.spring.bean.factory.AbstractBeanFactory;
 import org.apache.james.lifecycle.api.Configurable;
 import org.apache.james.mailrepository.api.MailRepository;
+import org.apache.james.mailrepository.api.MailRepositoryPath;
 import org.apache.james.mailrepository.api.MailRepositoryStore;
 import org.apache.james.mailrepository.api.MailRepositoryUrl;
 import org.apache.james.mailrepository.api.Protocol;
@@ -94,6 +95,16 @@ public class MailRepositoryStoreBeanFactory extends AbstractBeanFactory implemen
         return Optional.ofNullable(repositories.get(url));
     }
 
+    @Override
+    public Stream<MailRepository> getByPath(MailRepositoryPath path) {
+        return repositories
+                .keySet()
+                .stream()
+                .filter((MailRepositoryUrl key) -> key.getPath().equals(path))
+                .map(repositories::get);
+    }
+
+
     /**
      * <p>
      * Registers a new mail repository type in the mail store's registry based

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/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 1ae2b5d..babc19c 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
@@ -19,7 +19,6 @@
 
 package org.apache.james.mailrepository.api;
 
-import java.util.List;
 import java.util.Optional;
 import java.util.stream.Stream;
 
@@ -49,13 +48,27 @@ public interface MailRepositoryStore {
     Optional<MailRepository> get(MailRepositoryUrl url) throws MailRepositoryStoreException;
 
     /**
-     * Return a {@link List} which contains all urls of the selected
+     * Returns all the {@link MailRepository} for the given path.
+     */
+    Stream<MailRepository> getByPath(MailRepositoryPath path) throws MailRepositoryStoreException;
+
+    /**
+     * Return a {@link Stream} which contains all urls of the selected
      * {@link MailRepository}'s
-     * 
-     * @return urls
      */
     Stream<MailRepositoryUrl> getUrls();
 
+    /**
+     * Return a {@link Stream} which contains all paths of the selected
+     * {@link MailRepository}'s
+     */
+    default Stream<MailRepositoryPath> getPaths() {
+        return getUrls()
+            .map(MailRepositoryUrl::getPath)
+            .sorted()
+            .distinct();
+    }
+
     class MailRepositoryStoreException extends Exception {
         public MailRepositoryStoreException(String msg, Throwable t) {
             super(msg, t);

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/data/data-library/src/test/java/org/apache/james/mailrepository/mock/MockMailRepositoryStore.java
----------------------------------------------------------------------
diff --git a/server/data/data-library/src/test/java/org/apache/james/mailrepository/mock/MockMailRepositoryStore.java b/server/data/data-library/src/test/java/org/apache/james/mailrepository/mock/MockMailRepositoryStore.java
index dc3e1d9..6cd742e 100644
--- a/server/data/data-library/src/test/java/org/apache/james/mailrepository/mock/MockMailRepositoryStore.java
+++ b/server/data/data-library/src/test/java/org/apache/james/mailrepository/mock/MockMailRepositoryStore.java
@@ -25,6 +25,7 @@ import java.util.Optional;
 import java.util.stream.Stream;
 
 import org.apache.james.mailrepository.api.MailRepository;
+import org.apache.james.mailrepository.api.MailRepositoryPath;
 import org.apache.james.mailrepository.api.MailRepositoryStore;
 import org.apache.james.mailrepository.api.MailRepositoryUrl;
 
@@ -47,6 +48,15 @@ public class MockMailRepositoryStore implements MailRepositoryStore {
     }
 
     @Override
+    public Stream<MailRepository> getByPath(MailRepositoryPath path) {
+        return storedObjectMap
+                .keySet()
+                .stream()
+                .filter((MailRepositoryUrl key) -> key.getPath().equals(path))
+                .map(storedObjectMap::get);
+    }
+
+    @Override
     public Stream<MailRepositoryUrl> getUrls() {
         return storedObjectMap.keySet().stream();
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/DlpIntegrationTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/DlpIntegrationTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/DlpIntegrationTest.java
index 0762995..aae098e 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/DlpIntegrationTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/DlpIntegrationTest.java
@@ -174,7 +174,7 @@ public class DlpIntegrationTest {
         MailRepositoryUrl repositoryUrl = MailRepositoryUrl.from(REPOSITORY_PREFIX + DEFAULT_DOMAIN);
         given()
             .spec(specification)
-        .get("/mailRepositories/" + repositoryUrl.urlEncoded() + "/mails")
+        .get("/mailRepositories/" + repositoryUrl.getPath().urlEncoded() + "/mails")
             .then()
             .statusCode(HttpStatus.NOT_FOUND_404);
     }
@@ -223,7 +223,8 @@ public class DlpIntegrationTest {
         MailRepositoryUrl repositoryUrl = MailRepositoryUrl.from(REPOSITORY_PREFIX + DEFAULT_DOMAIN);
         given()
             .spec(specification)
-            .put("/mailRepositories/" + repositoryUrl.urlEncoded());
+            .param("protocol", repositoryUrl.getProtocol().getValue())
+            .put("/mailRepositories/" + repositoryUrl.getPath().urlEncoded());
 
         given()
             .spec(specification)
@@ -253,8 +254,7 @@ public class DlpIntegrationTest {
         try {
             return given()
                 .spec(specification)
-                .get("/mailRepositories/" + repositoryUrl.urlEncoded() + "/mails")
-                .prettyPeek()
+            .get("/mailRepositories/" + repositoryUrl.getPath().urlEncoded() + "/mails")
                 .jsonPath()
                 .getList(".")
                 .size() == 1;

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToRepositoryTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToRepositoryTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToRepositoryTest.java
index 0fecd96..3bcff8c 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToRepositoryTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToRepositoryTest.java
@@ -117,7 +117,7 @@ public class ToRepositoryTest {
             .queryParam("processor", ProcessorConfiguration.STATE_TRANSPORT)
             .queryParam("action", "reprocess")
         .patch(MailRepositoriesRoutes.MAIL_REPOSITORIES
-                + "/" + CUSTOM_REPOSITORY.urlEncoded()
+                + "/" + CUSTOM_REPOSITORY.getPath().urlEncoded()
                 + "/mails")
             .jsonPath()
             .getString("taskId");
@@ -148,7 +148,7 @@ public class ToRepositoryTest {
             .queryParam("processor", ProcessorConfiguration.STATE_TRANSPORT)
             .queryParam("action", "reprocess")
             .patch(MailRepositoriesRoutes.MAIL_REPOSITORIES
-                + "/" + CUSTOM_REPOSITORY.urlEncoded()
+                + "/" + CUSTOM_REPOSITORY.getPath().urlEncoded()
                 + "/mails/" + key.asString())
             .jsonPath()
             .get("taskId");

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/mailrepository/mailrepository-api/pom.xml
----------------------------------------------------------------------
diff --git a/server/mailrepository/mailrepository-api/pom.xml b/server/mailrepository/mailrepository-api/pom.xml
index cd972a7..e11f0c3 100644
--- a/server/mailrepository/mailrepository-api/pom.xml
+++ b/server/mailrepository/mailrepository-api/pom.xml
@@ -68,6 +68,11 @@
             <artifactId>junit-jupiter-engine</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-launcher</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/mailrepository/mailrepository-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryPath.java
----------------------------------------------------------------------
diff --git a/server/mailrepository/mailrepository-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryPath.java b/server/mailrepository/mailrepository-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryPath.java
new file mode 100644
index 0000000..31d549d
--- /dev/null
+++ b/server/mailrepository/mailrepository-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryPath.java
@@ -0,0 +1,81 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailrepository.api;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Objects;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+
+public class MailRepositoryPath implements Comparable<MailRepositoryPath> {
+    public static final MailRepositoryPath fromEncoded(String encodedPath) throws UnsupportedEncodingException {
+        return new MailRepositoryPath(URLDecoder.decode(encodedPath, StandardCharsets.UTF_8.displayName()));
+    }
+
+    public static final MailRepositoryPath from(String path) {
+        return new MailRepositoryPath(path);
+    }
+
+    private final String value;
+
+    private MailRepositoryPath(String value) {
+        Preconditions.checkNotNull(value);
+        this.value = value;
+    }
+
+    public String asString() {
+        return value;
+    }
+
+    public String urlEncoded() throws UnsupportedEncodingException {
+        return URLEncoder.encode(value, StandardCharsets.UTF_8.displayName());
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof MailRepositoryPath) {
+            MailRepositoryPath that = (MailRepositoryPath) o;
+
+            return Objects.equals(this.value, that.value);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(value);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+            .add("value", value)
+            .toString();
+    }
+
+    @Override
+    public int compareTo(MailRepositoryPath that) {
+        return this.value.compareTo(that.value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/mailrepository/mailrepository-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryUrl.java
----------------------------------------------------------------------
diff --git a/server/mailrepository/mailrepository-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryUrl.java b/server/mailrepository/mailrepository-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryUrl.java
index c6e69ec..f88ca2a 100644
--- a/server/mailrepository/mailrepository-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryUrl.java
+++ b/server/mailrepository/mailrepository-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryUrl.java
@@ -23,37 +23,63 @@ import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
+import java.util.List;
 import java.util.Objects;
 
+import com.google.common.base.Joiner;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Splitter;
+import com.google.common.collect.Iterables;
 
 public class MailRepositoryUrl {
-    public static final MailRepositoryUrl fromEncoded(String encodedUrl) throws UnsupportedEncodingException {
+    private static final int PROTOCOL_PART = 0;
+    private static final String PROTOCOL_SEPARATOR = "://";
+    private static final int SKIP_PROTOCOL = 1;
+
+    public static MailRepositoryUrl fromEncoded(String encodedUrl) throws UnsupportedEncodingException {
         return new MailRepositoryUrl(URLDecoder.decode(encodedUrl, StandardCharsets.UTF_8.displayName()));
     }
 
-    public static final MailRepositoryUrl from(String url) {
+    public static MailRepositoryUrl from(String url) {
         return new MailRepositoryUrl(url);
     }
 
+    public static MailRepositoryUrl fromPathAndProtocol(MailRepositoryPath path, String protocol) {
+        return new MailRepositoryUrl(path, protocol);
+    }
+
     private final String value;
+    private final MailRepositoryPath path;
     private final Protocol protocol;
 
     private MailRepositoryUrl(String value) {
         Preconditions.checkNotNull(value);
-        Preconditions.checkArgument(value.contains(":"), "':' is mandatory to delimit protocol");
+        Preconditions.checkArgument(value.contains(PROTOCOL_SEPARATOR), "The expected format is: <protocol> \"" + PROTOCOL_SEPARATOR + "\" <path>");
         this.value = value;
-        this.protocol = new Protocol(Splitter.on(':')
-            .splitToList(value)
-            .get(0));
+        List<String> urlParts = Splitter.on(PROTOCOL_SEPARATOR).splitToList(value);
+        this.protocol = new Protocol(urlParts.get(PROTOCOL_PART));
+        this.path = MailRepositoryPath.from(
+            Joiner.on(PROTOCOL_SEPARATOR)
+                .join(Iterables.skip(urlParts, SKIP_PROTOCOL)));
+    }
+
+    private MailRepositoryUrl(MailRepositoryPath path, String protocol) {
+        Preconditions.checkNotNull(path);
+        Preconditions.checkNotNull(protocol);
+        this.path = path;
+        this.protocol = new Protocol(protocol);
+        this.value = protocol + PROTOCOL_SEPARATOR + path.asString();
     }
 
     public String asString() {
         return value;
     }
 
+    public MailRepositoryPath getPath() {
+        return path;
+    }
+
     public String urlEncoded() throws UnsupportedEncodingException {
         return URLEncoder.encode(value, StandardCharsets.UTF_8.displayName());
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/mailrepository/mailrepository-api/src/test/java/org/apache/james/mailrepository/api/MailRepositoryUrlTest.java
----------------------------------------------------------------------
diff --git a/server/mailrepository/mailrepository-api/src/test/java/org/apache/james/mailrepository/api/MailRepositoryUrlTest.java b/server/mailrepository/mailrepository-api/src/test/java/org/apache/james/mailrepository/api/MailRepositoryUrlTest.java
index 83766b3..64a6d5e 100644
--- a/server/mailrepository/mailrepository-api/src/test/java/org/apache/james/mailrepository/api/MailRepositoryUrlTest.java
+++ b/server/mailrepository/mailrepository-api/src/test/java/org/apache/james/mailrepository/api/MailRepositoryUrlTest.java
@@ -28,45 +28,69 @@ import nl.jqno.equalsverifier.EqualsVerifier;
 
 public class MailRepositoryUrlTest {
     @Test
-    public void shouldMatchBeanContract() {
+    void shouldMatchBeanContract() {
         EqualsVerifier.forClass(MailRepositoryUrl.class)
-            .withIgnoredFields("protocol")
+            .withIgnoredFields("protocol", "path")
             .verify();
     }
 
     @Test
-    public void constructorShouldThrowWhenNull() {
+    void constructorShouldThrowWhenNull() {
         assertThatThrownBy(() -> MailRepositoryUrl.from(null))
             .isInstanceOf(NullPointerException.class);
     }
 
     @Test
-    public void constructorShouldThrowWhenNoSeparator() {
+    void constructorShouldThrowWhenNoSeparator() {
         assertThatThrownBy(() -> MailRepositoryUrl.from("invalid"))
             .isInstanceOf(IllegalArgumentException.class);
     }
 
     @Test
-    public void getProtocolShouldReturnValue() {
+    void getProtocolShouldReturnValue() {
         assertThat(MailRepositoryUrl.from("proto://abc").getProtocol())
             .isEqualTo(new Protocol("proto"));
     }
 
     @Test
-    public void getProtocolShouldReturnValueWhenEmpty() {
+    void getProtocolShouldReturnValueWhenEmpty() {
         assertThat(MailRepositoryUrl.from("://abc").getProtocol())
             .isEqualTo(new Protocol(""));
     }
 
     @Test
-    public void fromEncodedShouldReturnDecodedValue() throws Exception {
+    void fromEncodedShouldReturnDecodedValue() throws Exception {
         assertThat(MailRepositoryUrl.fromEncoded("url%3A%2F%2FmyRepo"))
             .isEqualTo(MailRepositoryUrl.from("url://myRepo"));
     }
 
     @Test
-    public void encodedValueShouldEncodeUnderlyingValue() throws Exception {
+    void fromPathAndProtocolShouldReturnTheFullValue() {
+        assertThat(MailRepositoryUrl.fromPathAndProtocol(MailRepositoryPath.from("myRepo"), "url"))
+            .isEqualTo(MailRepositoryUrl.from("url://myRepo"));
+    }
+
+    @Test
+    void encodedValueShouldEncodeUnderlyingValue() throws Exception {
         assertThat(MailRepositoryUrl.from("url://myRepo").urlEncoded())
             .isEqualTo("url%3A%2F%2FmyRepo");
     }
+
+    @Test
+    void getPathShouldReturnValue() {
+        assertThat(MailRepositoryUrl.from("proto://abc").getPath())
+            .isEqualTo(MailRepositoryPath.from("abc"));
+    }
+
+    @Test
+    void getPathShouldReturnValueWhenEmtpyPath() {
+        assertThat(MailRepositoryUrl.from("proto://").getPath())
+            .isEqualTo(MailRepositoryPath.from(""));
+    }
+
+    @Test
+    void getPathShouldReturnValueWhenSeveralProtocolSeparators() {
+        assertThat(MailRepositoryUrl.from("proto://abc://def").getPath())
+            .isEqualTo(MailRepositoryPath.from("abc://def"));
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java b/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java
index a0b5dde..b385f6f 100644
--- a/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java
@@ -119,10 +119,10 @@ public class WebAdminServerIntegrationTest {
         .then()
             .statusCode(HttpStatus.OK_200)
             .body("repository", containsInAnyOrder(
-                "file://var/mail/error/",
-                "file://var/mail/relay-denied/",
-                "file://var/mail/spam/",
-                "file://var/mail/address-error/"));
+                "var/mail/error/",
+                "var/mail/relay-denied/",
+                "var/mail/spam/",
+                "var/mail/address-error/"));
     }
 
     @Test
@@ -135,10 +135,10 @@ public class WebAdminServerIntegrationTest {
         .then()
             .statusCode(HttpStatus.OK_200)
             .body("repository", containsInAnyOrder(
-                "file://var/mail/error/",
-                "file://var/mail/relay-denied/",
-                "file://var/mail/spam/",
-                "file://var/mail/address-error/"));
+                "var/mail/error/",
+                "var/mail/relay-denied/",
+                "var/mail/spam/",
+                "var/mail/address-error/"));
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/dto/ExtendedMailRepositoryResponse.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/dto/ExtendedMailRepositoryResponse.java b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/dto/ExtendedMailRepositoryResponse.java
index a1775a0..40e1dfa 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/dto/ExtendedMailRepositoryResponse.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/dto/ExtendedMailRepositoryResponse.java
@@ -19,17 +19,30 @@
 
 package org.apache.james.webadmin.dto;
 
-import org.apache.james.mailrepository.api.MailRepositoryUrl;
+import java.io.UnsupportedEncodingException;
 
-public class ExtendedMailRepositoryResponse extends MailRepositoryResponse {
+import org.apache.james.mailrepository.api.MailRepositoryPath;
 
+public class ExtendedMailRepositoryResponse implements MailRepositoryResponse {
+
+    private final MailRepositoryPath repository;
     private final long size;
 
-    public ExtendedMailRepositoryResponse(MailRepositoryUrl repository, long size) {
-        super(repository);
+    public ExtendedMailRepositoryResponse(MailRepositoryPath repository, long size) {
+        this.repository = repository;
         this.size = size;
     }
 
+    @Override
+    public String getRepository() {
+        return repository.asString();
+    }
+
+    @Override
+    public String getPath() throws UnsupportedEncodingException {
+        return repository.urlEncoded();
+    }
+
     public long getSize() {
         return size;
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/dto/MailRepositoryResponse.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/dto/MailRepositoryResponse.java b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/dto/MailRepositoryResponse.java
index 962ffa0..5cb3cd1 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/dto/MailRepositoryResponse.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/dto/MailRepositoryResponse.java
@@ -21,21 +21,10 @@ package org.apache.james.webadmin.dto;
 
 import java.io.UnsupportedEncodingException;
 
-import org.apache.james.mailrepository.api.MailRepositoryUrl;
+public interface MailRepositoryResponse {
 
-public class MailRepositoryResponse {
+    String getRepository();
 
-    private final MailRepositoryUrl repository;
+    String getPath() throws UnsupportedEncodingException;
 
-    public MailRepositoryResponse(MailRepositoryUrl repository) {
-        this.repository = repository;
-    }
-
-    public String getRepository() {
-        return repository.asString();
-    }
-
-    public String getId() throws UnsupportedEncodingException {
-        return repository.urlEncoded();
-    }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/dto/SingleMailRepositoryResponse.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/dto/SingleMailRepositoryResponse.java b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/dto/SingleMailRepositoryResponse.java
new file mode 100644
index 0000000..eb2b5dd
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/dto/SingleMailRepositoryResponse.java
@@ -0,0 +1,43 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.webadmin.dto;
+
+import java.io.UnsupportedEncodingException;
+
+import org.apache.james.mailrepository.api.MailRepositoryPath;
+
+public class SingleMailRepositoryResponse implements MailRepositoryResponse {
+
+    private final MailRepositoryPath repository;
+
+    public SingleMailRepositoryResponse(MailRepositoryPath repository) {
+        this.repository = repository;
+    }
+
+    @Override
+    public String getRepository() {
+        return repository.asString();
+    }
+
+    @Override
+    public String getPath() throws UnsupportedEncodingException {
+        return repository.urlEncoded();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/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 c69f599..a6f9740 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
@@ -38,8 +38,8 @@ import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 
 import org.apache.james.mailrepository.api.MailKey;
+import org.apache.james.mailrepository.api.MailRepositoryPath;
 import org.apache.james.mailrepository.api.MailRepositoryStore;
-import org.apache.james.mailrepository.api.MailRepositoryUrl;
 import org.apache.james.queue.api.MailQueueFactory;
 import org.apache.james.task.Task;
 import org.apache.james.task.TaskId;
@@ -122,17 +122,27 @@ public class MailRepositoriesRoutes implements Routes {
     }
 
     @PUT
-    @Path("/{encodedUrl}")
+    @Path("/{encodedPath}")
     @ApiOperation(value = "Create a repository")
+    @ApiImplicitParams({
+        @ApiImplicitParam(
+                required = true, 
+                dataType = "String", 
+                name = "protocol", 
+                paramType = "query",
+                example = "?protocol=file",
+                value = "Specify the storage protocol to use"),
+    })
     @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) -> {
-            MailRepositoryUrl url = decodedRepositoryUrl(request);
+        service.put(MAIL_REPOSITORIES + "/:encodedPath", (request, response) -> {
+            MailRepositoryPath path = decodedRepositoryPath(request);
+            String protocol = request.queryParams("protocol");
             try {
-                repositoryStoreService.createMailRepository(url);
+                repositoryStoreService.createMailRepository(path, protocol);
                 response.status(HttpStatus.NO_CONTENT_204);
                 return Constants.EMPTY_BODY;
             } catch (MailRepositoryStore.MailRepositoryStoreException e) {
@@ -140,14 +150,14 @@ public class MailRepositoriesRoutes implements Routes {
                     .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.asString()))
+                    .message(String.format("Error while creating a mail repository with path '%s' and protocol '%s'", path.asString(), protocol))
                     .haltError();
             }
         }, jsonTransformer);
     }
 
     @GET
-    @Path("/{encodedUrl}/mails")
+    @Path("/{encodedPath}/mails")
     @ApiOperation(value = "Listing all mails in a repository")
     @ApiImplicitParams({
         @ApiImplicitParam(
@@ -174,14 +184,13 @@ public class MailRepositoriesRoutes implements Routes {
         @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500, message = "Internal server error - Something went bad on the server side.")
     })
     public void defineListMails() {
-        service.get(MAIL_REPOSITORIES + "/:encodedUrl/mails", (request, response) -> {
+        service.get(MAIL_REPOSITORIES + "/:encodedPath/mails", (request, response) -> {
             Offset offset = ParametersExtractor.extractOffset(request);
             Limit limit = ParametersExtractor.extractLimit(request);
-            String encodedUrl = request.params("encodedUrl");
-            MailRepositoryUrl url = MailRepositoryUrl.fromEncoded(encodedUrl);
+            MailRepositoryPath path = decodedRepositoryPath(request);
             try {
-                return repositoryStoreService.listMails(url, offset, limit)
-                    .orElseThrow(() -> repositoryNotFound(encodedUrl, url));
+                return repositoryStoreService.listMails(path, offset, limit)
+                    .orElseThrow(() -> repositoryNotFound(request.params("encodedPath"), path));
 
             } catch (MailRepositoryStore.MailRepositoryStoreException | MessagingException e) {
                 throw ErrorResponder.builder()
@@ -202,13 +211,13 @@ public class MailRepositoriesRoutes implements Routes {
     })
     public void defineGetMailRepositories() {
         service.get(MAIL_REPOSITORIES,
-            (request, response) -> repositoryStoreService.listMailRepositories(),
+            (request, response) -> repositoryStoreService.listMailRepositories().collect(Guavate.toImmutableList()),
             jsonTransformer);
     }
 
     @GET
     @Produces("application/json, message/rfc822")
-    @Path("/{encodedUrl}/mails/{mailKey}")
+    @Path("/{encodedPath}/mails/{mailKey}")
     @ApiOperation(value = "Retrieving a specific mail details (this endpoint can accept both \"application/json\" or \"message/rfc822\")")
     @ApiResponses(value = {
         @ApiResponse(code = HttpStatus.OK_200, message = "The list of all mails in a repository", response = List.class),
@@ -216,15 +225,15 @@ public class MailRepositoriesRoutes implements Routes {
         @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "Not found - Could not retrieve the given mail.")
     })
     public void defineGetMail() {
-        service.get(MAIL_REPOSITORIES + "/:encodedUrl/mails/:mailKey", Constants.JSON_CONTENT_TYPE,
+        service.get(MAIL_REPOSITORIES + "/:encodedPath/mails/:mailKey", Constants.JSON_CONTENT_TYPE,
             (request, response) ->
-                getMailAsJson(decodedRepositoryUrl(request), new MailKey(request.params("mailKey")), request),
+                getMailAsJson(decodedRepositoryPath(request), new MailKey(request.params("mailKey")), request),
             jsonTransformer);
 
-        service.get(MAIL_REPOSITORIES + "/:encodedUrl/mails/:mailKey", Constants.RFC822_CONTENT_TYPE,
+        service.get(MAIL_REPOSITORIES + "/:encodedPath/mails/:mailKey", Constants.RFC822_CONTENT_TYPE,
             (request, response) -> writeMimeMessage(
                 getMailAsMimeMessage(
-                    decodedRepositoryUrl(request),
+                    decodedRepositoryPath(request),
                     new MailKey(request.params("mailKey"))),
                 response.raw()));
     }
@@ -242,18 +251,18 @@ public class MailRepositoriesRoutes implements Routes {
         return byteArrayOutputStream.size();
     }
 
-    private MimeMessage getMailAsMimeMessage(MailRepositoryUrl url, MailKey mailKey) {
+    private MimeMessage getMailAsMimeMessage(MailRepositoryPath path, MailKey mailKey) {
         try {
-            return repositoryStoreService.retrieveMessage(url, mailKey)
+            return repositoryStoreService.retrieveMessage(path, mailKey)
                 .orElseThrow(mailNotFoundError(mailKey));
         } catch (MailRepositoryStore.MailRepositoryStoreException | MessagingException e) {
             throw internalServerError(e);
         }
     }
 
-    private MailDto getMailAsJson(MailRepositoryUrl url, MailKey mailKey, Request request) {
+    private MailDto getMailAsJson(MailRepositoryPath path, MailKey mailKey, Request request) {
         try {
-            return repositoryStoreService.retrieveMail(url, mailKey, extractAdditionalFields(request.queryParamOrDefault("additionalFields", "")))
+            return repositoryStoreService.retrieveMail(path, mailKey, extractAdditionalFields(request.queryParamOrDefault("additionalFields", "")))
                 .orElseThrow(mailNotFoundError(mailKey));
         } catch (MailRepositoryStore.MailRepositoryStoreException | MessagingException e) {
             throw internalServerError(e);
@@ -290,11 +299,11 @@ public class MailRepositoriesRoutes implements Routes {
             .haltError();
     }
 
-    private HaltException repositoryNotFound(String encodedUrl, MailRepositoryUrl url) {
+    private HaltException repositoryNotFound(String encodedPath, MailRepositoryPath path) {
         return ErrorResponder.builder()
             .statusCode(HttpStatus.NOT_FOUND_404)
             .type(ErrorType.NOT_FOUND)
-            .message("The repository '" + encodedUrl + "' (decoded value: '" + url.asString() + "') does not exist")
+            .message("The repository '" + encodedPath + "' (decoded value: '" + path.asString() + "') does not exist")
             .haltError();
     }
 
@@ -308,7 +317,7 @@ public class MailRepositoriesRoutes implements Routes {
     }
 
     @GET
-    @Path("/{encodedUrl}")
+    @Path("/{encodedPath}")
     @ApiOperation(value = "Reading the information of a repository, such as size (can take some time to compute)")
     @ApiResponses(value = {
         @ApiResponse(code = HttpStatus.OK_200, message = "The repository information", response = List.class),
@@ -316,13 +325,12 @@ public class MailRepositoriesRoutes implements Routes {
         @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500, message = "Internal server error - Something went bad on the server side."),
     })
     public void defineGetMailRepository() {
-        service.get(MAIL_REPOSITORIES + "/:encodedUrl", (request, response) -> {
-            String encodedUrl = request.params("encodedUrl");
-            MailRepositoryUrl url = MailRepositoryUrl.fromEncoded(encodedUrl);
+        service.get(MAIL_REPOSITORIES + "/:encodedPath", (request, response) -> {
+            MailRepositoryPath path = decodedRepositoryPath(request);
             try {
-                long size = repositoryStoreService.size(url)
-                    .orElseThrow(() -> repositoryNotFound(encodedUrl, url));
-                return new ExtendedMailRepositoryResponse(url, size);
+                long size = repositoryStoreService.size(path)
+                    .orElseThrow(() -> repositoryNotFound(request.params("encodedPath"), path));
+                return new ExtendedMailRepositoryResponse(path, size);
             } catch (MailRepositoryStore.MailRepositoryStoreException e) {
                 throw ErrorResponder.builder()
                     .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500)
@@ -335,19 +343,19 @@ public class MailRepositoriesRoutes implements Routes {
     }
 
     @DELETE
-    @Path("/{encodedUrl}/mails/{mailKey}")
+    @Path("/{encodedPath}/mails/{mailKey}")
     @ApiOperation(value = "Deleting a specific mail from that mailRepository")
     @ApiResponses(value = {
         @ApiResponse(code = HttpStatus.OK_200, message = "Mail is no more stored in the repository", response = List.class),
         @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500, message = "Internal server error - Something went bad on the server side."),
     })
     public void defineDeleteMail() {
-        service.delete(MAIL_REPOSITORIES + "/:encodedUrl/mails/:mailKey", (request, response) -> {
-            MailRepositoryUrl url = decodedRepositoryUrl(request);
+        service.delete(MAIL_REPOSITORIES + "/:encodedPath/mails/:mailKey", (request, response) -> {
+            MailRepositoryPath path = decodedRepositoryPath(request);
             MailKey mailKey = new MailKey(request.params("mailKey"));
             try {
                 response.status(HttpStatus.NO_CONTENT_204);
-                repositoryStoreService.deleteMail(url, mailKey);
+                repositoryStoreService.deleteMail(path, mailKey);
                 return Constants.EMPTY_BODY;
             } catch (MailRepositoryStore.MailRepositoryStoreException | MessagingException e) {
                 throw ErrorResponder.builder()
@@ -361,7 +369,7 @@ public class MailRepositoriesRoutes implements Routes {
     }
 
     @DELETE
-    @Path("/{encodedUrl}/mails")
+    @Path("/{encodedPath}/mails")
     @ApiOperation(value = "Deleting all mails in that mailRepository")
     @ApiResponses(value = {
         @ApiResponse(code = HttpStatus.CREATED_201, message = "All mails are deleted", response = TaskIdDto.class),
@@ -369,10 +377,10 @@ public class MailRepositoriesRoutes implements Routes {
         @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Bad request - unknown action")
     })
     public void defineDeleteAll() {
-        service.delete(MAIL_REPOSITORIES + "/:encodedUrl/mails", (request, response) -> {
-            MailRepositoryUrl url = decodedRepositoryUrl(request);
+        service.delete(MAIL_REPOSITORIES + "/:encodedPath/mails", (request, response) -> {
+            MailRepositoryPath path = decodedRepositoryPath(request);
             try {
-                Task task = repositoryStoreService.createClearMailRepositoryTask(url);
+                Task task = repositoryStoreService.createClearMailRepositoryTask(path);
                 TaskId taskId = taskManager.submit(task);
                 return TaskIdDto.respond(response, taskId);
             } catch (MailRepositoryStore.MailRepositoryStoreException | MessagingException e) {
@@ -387,7 +395,7 @@ public class MailRepositoriesRoutes implements Routes {
     }
 
     @PATCH
-    @Path("/{encodedUrl}/mails")
+    @Path("/{encodedPath}/mails")
     @ApiOperation(value = "Reprocessing all mails in that mailRepository")
     @ApiImplicitParams({
         @ApiImplicitParam(
@@ -421,7 +429,7 @@ public class MailRepositoriesRoutes implements Routes {
         @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Bad request - unknown action")
     })
     public void defineReprocessAll() {
-        service.patch(MAIL_REPOSITORIES + "/:encodedUrl/mails", (request, response) -> {
+        service.patch(MAIL_REPOSITORIES + "/:encodedPath/mails", (request, response) -> {
             Task task = toAllMailReprocessingTask(request);
             TaskId taskId = taskManager.submit(task);
             return TaskIdDto.respond(response, taskId);
@@ -429,17 +437,17 @@ public class MailRepositoriesRoutes implements Routes {
     }
 
     private Task toAllMailReprocessingTask(Request request) throws UnsupportedEncodingException, MailRepositoryStore.MailRepositoryStoreException, MessagingException {
-        MailRepositoryUrl url = decodedRepositoryUrl(request);
+        MailRepositoryPath path = decodedRepositoryPath(request);
         enforceActionParameter(request);
         Optional<String> targetProcessor = Optional.ofNullable(request.queryParams("processor"));
         String targetQueue = Optional.ofNullable(request.queryParams("queue")).orElse(MailQueueFactory.SPOOL);
 
-        Long repositorySize = repositoryStoreService.size(url).orElse(0L);
-        return new ReprocessingAllMailsTask(reprocessingService, repositorySize, url, targetQueue, targetProcessor);
+        Long repositorySize = repositoryStoreService.size(path).orElse(0L);
+        return new ReprocessingAllMailsTask(reprocessingService, repositorySize, path, targetQueue, targetProcessor);
     }
 
     @PATCH
-    @Path("/{encodedUrl}/mails/{key}")
+    @Path("/{encodedPath}/mails/{key}")
     @ApiOperation(value = "Reprocessing a single mail in that mailRepository")
     @ApiImplicitParams({
         @ApiImplicitParam(
@@ -473,7 +481,7 @@ public class MailRepositoriesRoutes implements Routes {
         @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Bad request - unknown action")
     })
     public void defineReprocessOne() {
-        service.patch(MAIL_REPOSITORIES + "/:encodedUrl/mails/:key", (request, response) -> {
+        service.patch(MAIL_REPOSITORIES + "/:encodedPath/mails/:key", (request, response) -> {
             Task task = toOneMailReprocessingTask(request);
             TaskId taskId = taskManager.submit(task);
             return TaskIdDto.respond(response, taskId);
@@ -481,13 +489,13 @@ public class MailRepositoriesRoutes implements Routes {
     }
 
     private Task toOneMailReprocessingTask(Request request) throws UnsupportedEncodingException {
-        MailRepositoryUrl url = decodedRepositoryUrl(request);
+        MailRepositoryPath path = decodedRepositoryPath(request);
         MailKey key = new MailKey(request.params("key"));
         enforceActionParameter(request);
         Optional<String> targetProcessor = Optional.ofNullable(request.queryParams("processor"));
         String targetQueue = Optional.ofNullable(request.queryParams("queue")).orElse(MailQueueFactory.SPOOL);
 
-        return new ReprocessingOneMailTask(reprocessingService, url, targetQueue, key, targetProcessor);
+        return new ReprocessingOneMailTask(reprocessingService, path, targetQueue, key, targetProcessor);
     }
 
     private void enforceActionParameter(Request request) {
@@ -501,10 +509,6 @@ public class MailRepositoriesRoutes implements Routes {
         }
     }
 
-    private MailRepositoryUrl decodedRepositoryUrl(Request request) throws UnsupportedEncodingException {
-        return MailRepositoryUrl.fromEncoded(request.params("encodedUrl"));
-    }
-
     private Set<AdditionalField> extractAdditionalFields(String additionalFieldsParam) throws IllegalArgumentException {
         return Splitter
             .on(',')
@@ -516,4 +520,7 @@ public class MailRepositoriesRoutes implements Routes {
             .collect(Guavate.toImmutableSet());
     }
 
+    private MailRepositoryPath decodedRepositoryPath(Request request) throws UnsupportedEncodingException {
+        return MailRepositoryPath.fromEncoded(request.params("encodedPath"));
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ClearMailRepositoryTask.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ClearMailRepositoryTask.java b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ClearMailRepositoryTask.java
index 853e530..406330f 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ClearMailRepositoryTask.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ClearMailRepositoryTask.java
@@ -19,33 +19,36 @@
 
 package org.apache.james.webadmin.service;
 
+import java.util.List;
 import java.util.Optional;
 import java.util.function.Supplier;
 
 import javax.mail.MessagingException;
 
 import org.apache.james.mailrepository.api.MailRepository;
-import org.apache.james.mailrepository.api.MailRepositoryUrl;
+import org.apache.james.mailrepository.api.MailRepositoryPath;
 import org.apache.james.task.Task;
 import org.apache.james.task.TaskExecutionDetails;
 
+import com.github.fge.lambdas.Throwing;
+
 public class ClearMailRepositoryTask implements Task {
 
     public static final String TYPE = "clearMailRepository";
 
     public static class AdditionalInformation implements TaskExecutionDetails.AdditionalInformation {
-        private final MailRepositoryUrl repositoryUrl;
+        private final MailRepositoryPath repositoryPath;
         private final Supplier<Long> countSupplier;
         private final long initialCount;
 
-        public AdditionalInformation(MailRepositoryUrl repositoryUrl, Supplier<Long> countSupplier) {
-            this.repositoryUrl = repositoryUrl;
+        public AdditionalInformation(MailRepositoryPath repositoryPath, Supplier<Long> countSupplier) {
+            this.repositoryPath = repositoryPath;
             this.initialCount = countSupplier.get();
             this.countSupplier = countSupplier;
         }
 
-        public String getRepositoryUrl() {
-            return repositoryUrl.asString();
+        public String getRepositoryPath() {
+            return repositoryPath.asString();
         }
 
         public long getRemainingCount() {
@@ -57,18 +60,18 @@ public class ClearMailRepositoryTask implements Task {
         }
     }
 
-    private final MailRepository mailRepository;
+    private final List<MailRepository> mailRepositories;
     private final AdditionalInformation additionalInformation;
 
-    public ClearMailRepositoryTask(MailRepository mailRepository, MailRepositoryUrl url) {
-        this.mailRepository = mailRepository;
-        this.additionalInformation = new AdditionalInformation(url, this::getRemainingSize);
+    public ClearMailRepositoryTask(List<MailRepository> mailRepositories, MailRepositoryPath path) {
+        this.mailRepositories = mailRepositories;
+        this.additionalInformation = new AdditionalInformation(path, this::getRemainingSize);
     }
 
     @Override
     public Result run() {
         try {
-            mailRepository.removeAll();
+            removeAllInAllRepositories();
             return Result.COMPLETED;
         } catch (MessagingException e) {
             LOGGER.error("Encountered error while clearing repository", e);
@@ -76,6 +79,10 @@ public class ClearMailRepositoryTask implements Task {
         }
     }
 
+    private void removeAllInAllRepositories() throws MessagingException {
+        mailRepositories.forEach(Throwing.consumer(MailRepository::removeAll));
+    }
+
     @Override
     public String type() {
         return TYPE;
@@ -87,10 +94,10 @@ public class ClearMailRepositoryTask implements Task {
     }
 
     public long getRemainingSize() {
-        try {
-            return mailRepository.size();
-        } catch (MessagingException e) {
-            throw new RuntimeException(e);
-        }
+        return mailRepositories
+                .stream()
+                .map(Throwing.function(MailRepository::size).sneakyThrow())
+                .mapToLong(Long::valueOf)
+                .sum();
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/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 6efce69..ff4ee76 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
@@ -22,6 +22,8 @@ package org.apache.james.webadmin.service;
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import javax.inject.Inject;
 import javax.mail.MessagingException;
@@ -29,6 +31,7 @@ import javax.mail.internet.MimeMessage;
 
 import org.apache.james.mailrepository.api.MailKey;
 import org.apache.james.mailrepository.api.MailRepository;
+import org.apache.james.mailrepository.api.MailRepositoryPath;
 import org.apache.james.mailrepository.api.MailRepositoryStore;
 import org.apache.james.mailrepository.api.MailRepositoryUrl;
 import org.apache.james.task.Task;
@@ -39,7 +42,7 @@ import org.apache.james.webadmin.dto.InaccessibleFieldException;
 import org.apache.james.webadmin.dto.MailDto;
 import org.apache.james.webadmin.dto.MailDto.AdditionalField;
 import org.apache.james.webadmin.dto.MailKeyDTO;
-import org.apache.james.webadmin.dto.MailRepositoryResponse;
+import org.apache.james.webadmin.dto.SingleMailRepositoryResponse;
 import org.apache.james.webadmin.utils.ErrorResponder;
 import org.apache.mailet.Mail;
 import org.eclipse.jetty.http.HttpStatus;
@@ -56,56 +59,54 @@ public class MailRepositoryStoreService {
         this.mailRepositoryStore = mailRepositoryStore;
     }
 
-    public List<MailRepositoryResponse> listMailRepositories() {
-        return mailRepositoryStore.getUrls()
-            .map(MailRepositoryResponse::new)
-            .collect(Guavate.toImmutableList());
+    public Stream<SingleMailRepositoryResponse> listMailRepositories() {
+        return mailRepositoryStore
+            .getPaths()
+            .map(SingleMailRepositoryResponse::new);
     }
 
-    public MailRepository createMailRepository(MailRepositoryUrl repositoryUrl) throws MailRepositoryStore.MailRepositoryStoreException {
-        return mailRepositoryStore.create(repositoryUrl);
+    public MailRepository createMailRepository(MailRepositoryPath repositoryPath, String protocol) throws MailRepositoryStore.MailRepositoryStoreException {
+        return mailRepositoryStore.create(MailRepositoryUrl.fromPathAndProtocol(repositoryPath, protocol));
     }
 
-    public Optional<List<MailKeyDTO>> listMails(MailRepositoryUrl url, Offset offset, Limit limit) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {
-        Optional<MailRepository> mailRepository = mailRepositoryStore.get(url);
-        ThrowingFunction<MailRepository, List<MailKeyDTO>> list = repository -> list(repository, offset, limit);
-        return mailRepository.map(Throwing.function(list).sneakyThrow());
+    public Optional<List<MailKeyDTO>> listMails(MailRepositoryPath path, Offset offset, Limit limit) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {
+        ThrowingFunction<MailRepository, Stream<MailKeyDTO>> list = repository -> list(repository, offset, limit);
+        return Optional.of(getRepositories(path)
+                .flatMap(Throwing.function(list).sneakyThrow())
+                .collect(Guavate.toImmutableList()));
     }
 
-    private List<MailKeyDTO> list(MailRepository mailRepository, Offset offset, Limit limit) throws MessagingException {
+    private Stream<MailKeyDTO> list(MailRepository mailRepository, Offset offset, Limit limit) throws MessagingException {
         return limit.applyOnStream(
                 Iterators.toStream(mailRepository.list())
                     .skip(offset.getOffset()))
-                .map(MailKeyDTO::new)
-                .collect(Guavate.toImmutableList());
+                .map(MailKeyDTO::new);
     }
 
-    public Optional<Long> size(MailRepositoryUrl url) throws MailRepositoryStore.MailRepositoryStoreException {
-        Optional<MailRepository> mailRepository = mailRepositoryStore.get(url);
-        return mailRepository.map(Throwing.function(MailRepository::size).sneakyThrow());
+    public Optional<Long> size(MailRepositoryPath path) throws MailRepositoryStore.MailRepositoryStoreException {
+        return Optional.of(getRepositories(path)
+                .map(Throwing.function(MailRepository::size).sneakyThrow())
+                .mapToLong(Long::valueOf)
+                .sum());
     }
 
-    public Optional<MailDto> retrieveMail(MailRepositoryUrl url, MailKey mailKey, Set<AdditionalField> additionalAttributes) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException, InaccessibleFieldException {
-        MailRepository mailRepository = getRepository(url);
-
-        return Optional.ofNullable(mailRepository.retrieve(mailKey))
+    public Optional<MailDto> retrieveMail(MailRepositoryPath path, MailKey mailKey, Set<AdditionalField> additionalAttributes) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException, InaccessibleFieldException {
+        return fecthMail(path, mailKey)
             .map(Throwing.function((Mail mail) -> MailDto.fromMail(mail, additionalAttributes)).sneakyThrow());
     }
 
-    public Optional<MimeMessage> retrieveMessage(MailRepositoryUrl url, MailKey mailKey) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {
-        MailRepository mailRepository = getRepository(url);
-
-        return Optional.ofNullable(mailRepository.retrieve(mailKey))
+    public Optional<MimeMessage> retrieveMessage(MailRepositoryPath path, MailKey mailKey) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {
+        return fecthMail(path, mailKey)
             .map(Throwing.function(Mail::getMessage).sneakyThrow());
     }
 
-    public void deleteMail(MailRepositoryUrl url, MailKey mailKey) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {
-        getRepository(url)
-            .remove(mailKey);
+    public void deleteMail(MailRepositoryPath path, MailKey mailKey) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {
+        getRepositories(path)
+            .forEach(Throwing.consumer((MailRepository repository) -> repository.remove(mailKey)).sneakyThrow());
     }
 
-    public Task createClearMailRepositoryTask(MailRepositoryUrl url) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {
-        return new ClearMailRepositoryTask(getRepository(url), url);
+    public Task createClearMailRepositoryTask(MailRepositoryPath path) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {
+        return new ClearMailRepositoryTask(getRepositories(path).collect(Guavate.toImmutableList()), path);
     }
 
     public MailRepository getRepository(MailRepositoryUrl url) throws MailRepositoryStore.MailRepositoryStoreException {
@@ -117,4 +118,25 @@ public class MailRepositoryStoreService {
                 .haltError());
     }
 
+    public Stream<MailRepository> getRepositories(MailRepositoryPath path) throws MailRepositoryStore.MailRepositoryStoreException {
+        Stream<MailRepository> byPath = mailRepositoryStore.getByPath(path);
+        List<MailRepository> repositories = byPath.collect(Collectors.toList());
+        if (repositories.isEmpty()) {
+            ErrorResponder.builder()
+                .statusCode(HttpStatus.NOT_FOUND_404)
+                .type(ErrorResponder.ErrorType.NOT_FOUND)
+                .message(path.asString() + " does not exist")
+                .haltError();
+        }
+
+        return repositories.stream();
+    }
+
+    private Optional<Mail> fecthMail(MailRepositoryPath path, MailKey mailKey) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {
+        return getRepositories(path)
+                .map(Throwing.function((MailRepository repository) -> Optional.ofNullable(repository.retrieve(mailKey))).sneakyThrow())
+                .filter(Optional::isPresent)
+                .findFirst()
+                .orElse(Optional.empty());
+        }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ReprocessingAllMailsTask.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ReprocessingAllMailsTask.java b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ReprocessingAllMailsTask.java
index 26ad50d..05b8ea1 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ReprocessingAllMailsTask.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ReprocessingAllMailsTask.java
@@ -25,8 +25,8 @@ import java.util.concurrent.atomic.AtomicLong;
 import javax.mail.MessagingException;
 
 import org.apache.james.mailrepository.api.MailKey;
+import org.apache.james.mailrepository.api.MailRepositoryPath;
 import org.apache.james.mailrepository.api.MailRepositoryStore;
-import org.apache.james.mailrepository.api.MailRepositoryUrl;
 import org.apache.james.task.Task;
 import org.apache.james.task.TaskExecutionDetails;
 
@@ -37,14 +37,14 @@ public class ReprocessingAllMailsTask implements Task {
     public static final String TYPE = "reprocessingAllTask";
 
     public static class AdditionalInformation implements TaskExecutionDetails.AdditionalInformation {
-        private final MailRepositoryUrl repositoryUrl;
+        private final MailRepositoryPath repositoryPath;
         private final String targetQueue;
         private final Optional<String> targetProcessor;
         private final long initialCount;
         private final AtomicLong processedCount;
 
-        public AdditionalInformation(MailRepositoryUrl repositoryUrl, String targetQueue, Optional<String> targetProcessor, long initialCount) {
-            this.repositoryUrl = repositoryUrl;
+        public AdditionalInformation(MailRepositoryPath repositoryPath, String targetQueue, Optional<String> targetProcessor, long initialCount) {
+            this.repositoryPath = repositoryPath;
             this.targetQueue = targetQueue;
             this.targetProcessor = targetProcessor;
             this.initialCount = initialCount;
@@ -59,8 +59,8 @@ public class ReprocessingAllMailsTask implements Task {
             return targetProcessor;
         }
 
-        public String getRepositoryUrl() {
-            return repositoryUrl.asString();
+        public String getRepositoryPath() {
+            return repositoryPath.asString();
         }
 
         public long getRemainingCount() {
@@ -78,25 +78,25 @@ public class ReprocessingAllMailsTask implements Task {
     }
 
     private final ReprocessingService reprocessingService;
-    private final MailRepositoryUrl repositoryUrl;
+    private final MailRepositoryPath repositoryPath;
     private final String targetQueue;
     private final Optional<String> targetProcessor;
     private final AdditionalInformation additionalInformation;
 
     public ReprocessingAllMailsTask(ReprocessingService reprocessingService, long repositorySize,
-                                    MailRepositoryUrl repositoryUrl, String targetQueue, Optional<String> targetProcessor) {
+                                    MailRepositoryPath repositoryPath, String targetQueue, Optional<String> targetProcessor) {
         this.reprocessingService = reprocessingService;
-        this.repositoryUrl = repositoryUrl;
+        this.repositoryPath = repositoryPath;
         this.targetQueue = targetQueue;
         this.targetProcessor = targetProcessor;
         this.additionalInformation = new AdditionalInformation(
-            repositoryUrl, targetQueue, targetProcessor, repositorySize);
+            repositoryPath, targetQueue, targetProcessor, repositorySize);
     }
 
     @Override
     public Result run() {
         try {
-            reprocessingService.reprocessAll(repositoryUrl, targetProcessor, targetQueue, additionalInformation::notifyProgress);
+            reprocessingService.reprocessAll(repositoryPath, targetProcessor, targetQueue, additionalInformation::notifyProgress);
             return Result.COMPLETED;
         } catch (MessagingException | MailRepositoryStore.MailRepositoryStoreException e) {
             LOGGER.error("Encountered error while reprocessing repository", e);

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ReprocessingOneMailTask.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ReprocessingOneMailTask.java b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ReprocessingOneMailTask.java
index 453ff8b..550b59a 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ReprocessingOneMailTask.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ReprocessingOneMailTask.java
@@ -24,8 +24,8 @@ import java.util.Optional;
 import javax.mail.MessagingException;
 
 import org.apache.james.mailrepository.api.MailKey;
+import org.apache.james.mailrepository.api.MailRepositoryPath;
 import org.apache.james.mailrepository.api.MailRepositoryStore;
-import org.apache.james.mailrepository.api.MailRepositoryUrl;
 import org.apache.james.task.Task;
 import org.apache.james.task.TaskExecutionDetails;
 
@@ -34,13 +34,13 @@ public class ReprocessingOneMailTask implements Task {
     public static final String TYPE = "reprocessingOneTask";
 
     public static class AdditionalInformation implements TaskExecutionDetails.AdditionalInformation {
-        private final MailRepositoryUrl repositoryUrl;
+        private final MailRepositoryPath repositoryPath;
         private final String targetQueue;
         private final MailKey mailKey;
         private final Optional<String> targetProcessor;
 
-        public AdditionalInformation(MailRepositoryUrl repositoryUrl, String targetQueue, MailKey mailKey, Optional<String> targetProcessor) {
-            this.repositoryUrl = repositoryUrl;
+        public AdditionalInformation(MailRepositoryPath repositoryPath, String targetQueue, MailKey mailKey, Optional<String> targetProcessor) {
+            this.repositoryPath = repositoryPath;
             this.targetQueue = targetQueue;
             this.mailKey = mailKey;
             this.targetProcessor = targetProcessor;
@@ -58,32 +58,32 @@ public class ReprocessingOneMailTask implements Task {
             return targetProcessor;
         }
 
-        public String getRepositoryUrl() {
-            return repositoryUrl.asString();
+        public String getRepositoryPath() {
+            return repositoryPath.asString();
         }
     }
 
     private final ReprocessingService reprocessingService;
-    private final MailRepositoryUrl repositoryUrl;
+    private final MailRepositoryPath repositoryPath;
     private final String targetQueue;
     private final MailKey mailKey;
     private final Optional<String> targetProcessor;
     private final AdditionalInformation additionalInformation;
 
     public ReprocessingOneMailTask(ReprocessingService reprocessingService,
-                                   MailRepositoryUrl repositoryUrl, String targetQueue, MailKey mailKey, Optional<String> targetProcessor) {
+                                   MailRepositoryPath repositoryPath, String targetQueue, MailKey mailKey, Optional<String> targetProcessor) {
         this.reprocessingService = reprocessingService;
-        this.repositoryUrl = repositoryUrl;
+        this.repositoryPath = repositoryPath;
         this.targetQueue = targetQueue;
         this.mailKey = mailKey;
         this.targetProcessor = targetProcessor;
-        this.additionalInformation = new AdditionalInformation(repositoryUrl, targetQueue, mailKey, targetProcessor);
+        this.additionalInformation = new AdditionalInformation(repositoryPath, targetQueue, mailKey, targetProcessor);
     }
 
     @Override
     public Result run() {
         try {
-            reprocessingService.reprocess(repositoryUrl, mailKey, targetProcessor, targetQueue);
+            reprocessingService.reprocess(repositoryPath, mailKey, targetProcessor, targetQueue);
             return Result.COMPLETED;
         } catch (MessagingException | MailRepositoryStore.MailRepositoryStoreException e) {
             LOGGER.error("Encountered error while reprocessing repository", e);

http://git-wip-us.apache.org/repos/asf/james-project/blob/ee71575a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ReprocessingService.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ReprocessingService.java b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ReprocessingService.java
index fbe68a4..f02bd3f 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ReprocessingService.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/ReprocessingService.java
@@ -27,8 +27,8 @@ import javax.mail.MessagingException;
 
 import org.apache.james.mailrepository.api.MailKey;
 import org.apache.james.mailrepository.api.MailRepository;
+import org.apache.james.mailrepository.api.MailRepositoryPath;
 import org.apache.james.mailrepository.api.MailRepositoryStore;
-import org.apache.james.mailrepository.api.MailRepositoryUrl;
 import org.apache.james.queue.api.MailQueue;
 import org.apache.james.queue.api.MailQueueFactory;
 import org.apache.james.util.streams.Iterators;
@@ -48,20 +48,23 @@ public class ReprocessingService {
         this.mailRepositoryStoreService = mailRepositoryStoreService;
     }
 
-    public void reprocessAll(MailRepositoryUrl url, Optional<String> targetProcessor, String targetQueue, Consumer<MailKey> keyListener) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {
-        MailRepository repository = mailRepositoryStoreService.getRepository(url);
+    public void reprocessAll(MailRepositoryPath path, Optional<String> targetProcessor, String targetQueue, Consumer<MailKey> keyListener) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {
         MailQueue mailQueue = getMailQueue(targetQueue);
 
-        Iterators.toStream(repository.list())
-            .peek(keyListener)
-            .forEach(Throwing.consumer(key -> reprocess(repository, mailQueue, key, targetProcessor)));
+        mailRepositoryStoreService
+            .getRepositories(path)
+            .forEach(Throwing.consumer((MailRepository repository) ->
+                Iterators.toStream(repository.list())
+                    .peek(keyListener)
+                    .forEach(Throwing.consumer(key -> reprocess(repository, mailQueue, key, targetProcessor)))).sneakyThrow());
     }
 
-    public void reprocess(MailRepositoryUrl url, MailKey key, Optional<String> targetProcessor, String targetQueue) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {
-        MailRepository repository = mailRepositoryStoreService.getRepository(url);
+    public void reprocess(MailRepositoryPath path, MailKey key, Optional<String> targetProcessor, String targetQueue) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {
         MailQueue mailQueue = getMailQueue(targetQueue);
 
-        reprocess(repository, mailQueue, key, targetProcessor);
+        mailRepositoryStoreService
+            .getRepositories(path)
+            .forEach(Throwing.consumer((MailRepository repository) -> reprocess(repository, mailQueue, key, targetProcessor)).sneakyThrow());
     }
 
     private void reprocess(MailRepository repository, MailQueue mailQueue, MailKey key, Optional<String> targetProcessor) throws MessagingException {


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