You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2019/03/01 08:46:50 UTC

[james-project] 02/04: MAILBOX-381 MailRepository URL & Path should support appending suffixes

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 2ce42f651e8688ae64ea9a87ad0a34405841299d
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed Feb 27 14:36:46 2019 +0700

    MAILBOX-381 MailRepository URL & Path should support appending suffixes
---
 .../mailets/ToSenderDomainRepository.java          |  5 +-
 .../mailrepository/api/MailRepositoryPath.java     | 28 +++++++--
 .../mailrepository/api/MailRepositoryUrl.java      | 37 ++++++------
 ...oryUrlTest.java => MailRepositoryPathTest.java} | 67 +++++++++++-----------
 .../mailrepository/api/MailRepositoryUrlTest.java  | 24 ++++++++
 .../integration/WebAdminServerIntegrationTest.java | 14 ++---
 6 files changed, 111 insertions(+), 64 deletions(-)

diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
index b3b3b7f..7f954ba 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
@@ -72,7 +72,7 @@ public class ToSenderDomainRepository extends GenericMailet {
     private static final boolean DEFAULT_ALLOW_REPOSITORY_CREATION = true;
 
     private final MailRepositoryStore mailRepositoryStore;
-    private String urlPrefix;
+    private MailRepositoryUrl urlPrefix;
     private boolean passThrough;
     private boolean allowRepositoryCreation;
 
@@ -84,6 +84,7 @@ public class ToSenderDomainRepository extends GenericMailet {
     @Override
     public void init() throws MessagingException {
         urlPrefix = Optional.ofNullable(getInitParameter(URL_PREFIX))
+            .map(MailRepositoryUrl::from)
             .orElseThrow(() -> new MessagingException("'urlPrefix' is a mandatory configuration property"));
         passThrough = getInitParameter(PASS_THROUGH, DEFAULT_CONSUME);
         allowRepositoryCreation = getInitParameter(ALLOW_REPOSITORY_CREATION, DEFAULT_ALLOW_REPOSITORY_CREATION);
@@ -97,7 +98,7 @@ public class ToSenderDomainRepository extends GenericMailet {
             .map(Domain::asString)
             .orElse("");
 
-        MailRepositoryUrl repositoryUrl = MailRepositoryUrl.from(urlPrefix + domain);
+        MailRepositoryUrl repositoryUrl = urlPrefix.subUrl(domain);
         store(mail, repositoryUrl);
         if (!passThrough) {
             mail.setState(Mail.GHOST);
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
index 31d549d..5bb9d79 100644
--- 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
@@ -25,25 +25,45 @@ import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.util.Objects;
 
+import org.apache.commons.lang3.StringUtils;
+
 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()));
+
+    private static final String PATH_DELIMITER = "/";
+
+    public static MailRepositoryPath fromEncoded(String encodedPath) throws UnsupportedEncodingException {
+        Preconditions.checkNotNull(encodedPath, "Supplied MailRepositoryPath value is null");
+
+        return from(URLDecoder.decode(encodedPath, StandardCharsets.UTF_8.displayName()));
     }
 
-    public static final MailRepositoryPath from(String path) {
-        return new MailRepositoryPath(path);
+    public static MailRepositoryPath from(String path) {
+        Preconditions.checkNotNull(path, "Supplied MailRepositoryPath value is null");
+
+        return new MailRepositoryPath(sanitizePath(path));
+    }
+
+    private static String sanitizePath(String path) {
+        return StringUtils.stripEnd(path, "/");
     }
 
     private final String value;
 
     private MailRepositoryPath(String value) {
         Preconditions.checkNotNull(value);
+
         this.value = value;
     }
 
+    public MailRepositoryPath subPath(String suffix) {
+        Preconditions.checkArgument(!suffix.startsWith(PATH_DELIMITER), "The suffix used can not start by the path delimiter");
+
+        return from(value + PATH_DELIMITER + suffix);
+    }
+
     public String asString() {
         return value;
     }
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 f88ca2a..2a62aff 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
@@ -38,38 +38,37 @@ public class MailRepositoryUrl {
     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()));
+        return from(URLDecoder.decode(encodedUrl, StandardCharsets.UTF_8.displayName()));
     }
 
     public static MailRepositoryUrl from(String url) {
-        return new MailRepositoryUrl(url);
+        Preconditions.checkNotNull(url);
+        Preconditions.checkArgument(url.contains(PROTOCOL_SEPARATOR), "The expected format is: <protocol> \"" + PROTOCOL_SEPARATOR + "\" <path>");
+
+        List<String> urlParts = Splitter.on(PROTOCOL_SEPARATOR).splitToList(url);
+
+        Protocol protocol = new Protocol(urlParts.get(PROTOCOL_PART));
+        MailRepositoryPath path = MailRepositoryPath.from(
+            Joiner.on(PROTOCOL_SEPARATOR)
+                .join(Iterables.skip(urlParts, SKIP_PROTOCOL)));
+
+        return new MailRepositoryUrl(path, protocol);
     }
 
     public static MailRepositoryUrl fromPathAndProtocol(MailRepositoryPath path, String protocol) {
-        return new MailRepositoryUrl(path, protocol);
+        return new MailRepositoryUrl(path, new Protocol(protocol));
     }
 
     private final String value;
     private final MailRepositoryPath path;
     private final Protocol protocol;
 
-    private MailRepositoryUrl(String value) {
-        Preconditions.checkNotNull(value);
-        Preconditions.checkArgument(value.contains(PROTOCOL_SEPARATOR), "The expected format is: <protocol> \"" + PROTOCOL_SEPARATOR + "\" <path>");
-        this.value = value;
-        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) {
+    private MailRepositoryUrl(MailRepositoryPath path, Protocol protocol) {
         Preconditions.checkNotNull(path);
         Preconditions.checkNotNull(protocol);
         this.path = path;
-        this.protocol = new Protocol(protocol);
-        this.value = protocol + PROTOCOL_SEPARATOR + path.asString();
+        this.protocol = protocol;
+        this.value = protocol.getValue()  + PROTOCOL_SEPARATOR + path.asString();
     }
 
     public String asString() {
@@ -80,6 +79,10 @@ public class MailRepositoryUrl {
         return path;
     }
 
+    public MailRepositoryUrl subUrl(String suffix) {
+        return new MailRepositoryUrl(path.subPath(suffix), protocol);
+    }
+
     public String urlEncoded() throws UnsupportedEncodingException {
         return URLEncoder.encode(value, StandardCharsets.UTF_8.displayName());
     }
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/MailRepositoryPathTest.java
similarity index 51%
copy from server/mailrepository/mailrepository-api/src/test/java/org/apache/james/mailrepository/api/MailRepositoryUrlTest.java
copy to server/mailrepository/mailrepository-api/src/test/java/org/apache/james/mailrepository/api/MailRepositoryPathTest.java
index 64a6d5e..bb16d0f 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/MailRepositoryPathTest.java
@@ -26,71 +26,70 @@ import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
 
-public class MailRepositoryUrlTest {
+class MailRepositoryPathTest {
     @Test
     void shouldMatchBeanContract() {
-        EqualsVerifier.forClass(MailRepositoryUrl.class)
-            .withIgnoredFields("protocol", "path")
+        EqualsVerifier.forClass(MailRepositoryPath.class)
             .verify();
     }
 
     @Test
-    void constructorShouldThrowWhenNull() {
-        assertThatThrownBy(() -> MailRepositoryUrl.from(null))
-            .isInstanceOf(NullPointerException.class);
+    void fromShouldRemoveTrailingSlash() {
+        assertThat(MailRepositoryPath.from("abc/def/"))
+            .isEqualTo(MailRepositoryPath.from("abc/def"));
     }
 
     @Test
-    void constructorShouldThrowWhenNoSeparator() {
-        assertThatThrownBy(() -> MailRepositoryUrl.from("invalid"))
-            .isInstanceOf(IllegalArgumentException.class);
+    void fromShouldRemoveTrailingSlashes() {
+        assertThat(MailRepositoryPath.from("abc/def//"))
+            .isEqualTo(MailRepositoryPath.from("abc/def"));
     }
 
     @Test
-    void getProtocolShouldReturnValue() {
-        assertThat(MailRepositoryUrl.from("proto://abc").getProtocol())
-            .isEqualTo(new Protocol("proto"));
+    void fromShouldAcceptEmptyString() {
+        assertThat(MailRepositoryPath.from("").asString())
+            .isEqualTo("");
     }
 
     @Test
-    void getProtocolShouldReturnValueWhenEmpty() {
-        assertThat(MailRepositoryUrl.from("://abc").getProtocol())
-            .isEqualTo(new Protocol(""));
+    void fromShouldAcceptRemoveTrailingSlashesWhenOnlySlashes() {
+        assertThat(MailRepositoryPath.from("//"))
+            .isEqualTo(MailRepositoryPath.from(""));
     }
 
     @Test
-    void fromEncodedShouldReturnDecodedValue() throws Exception {
-        assertThat(MailRepositoryUrl.fromEncoded("url%3A%2F%2FmyRepo"))
-            .isEqualTo(MailRepositoryUrl.from("url://myRepo"));
+    void subPathShouldAppendSuffix() {
+        assertThat(MailRepositoryPath.from("abc/def").subPath("ghi"))
+            .isEqualTo(MailRepositoryPath.from("abc/def/ghi"));
     }
 
     @Test
-    void fromPathAndProtocolShouldReturnTheFullValue() {
-        assertThat(MailRepositoryUrl.fromPathAndProtocol(MailRepositoryPath.from("myRepo"), "url"))
-            .isEqualTo(MailRepositoryUrl.from("url://myRepo"));
+    void subPathShouldBeANoopWhenEmptySuffix() {
+        assertThat(MailRepositoryPath.from("abc/def").subPath(""))
+            .isEqualTo(MailRepositoryPath.from("abc/def"));
     }
 
     @Test
-    void encodedValueShouldEncodeUnderlyingValue() throws Exception {
-        assertThat(MailRepositoryUrl.from("url://myRepo").urlEncoded())
-            .isEqualTo("url%3A%2F%2FmyRepo");
+    void fromEncodedShouldDecodeInput() throws Exception {
+        assertThat(MailRepositoryPath.fromEncoded("abc%2Fdef"))
+            .isEqualTo(MailRepositoryPath.from("abc/def"));
     }
 
     @Test
-    void getPathShouldReturnValue() {
-        assertThat(MailRepositoryUrl.from("proto://abc").getPath())
-            .isEqualTo(MailRepositoryPath.from("abc"));
+    void fromShouldRejectNull() {
+        assertThatThrownBy(() -> MailRepositoryPath.from(null))
+            .isInstanceOf(NullPointerException.class);
     }
 
     @Test
-    void getPathShouldReturnValueWhenEmtpyPath() {
-        assertThat(MailRepositoryUrl.from("proto://").getPath())
-            .isEqualTo(MailRepositoryPath.from(""));
+    void fromEncodedShouldRejectNull() {
+        assertThatThrownBy(() -> MailRepositoryPath.fromEncoded(null))
+            .isInstanceOf(NullPointerException.class);
     }
 
     @Test
-    void getPathShouldReturnValueWhenSeveralProtocolSeparators() {
-        assertThat(MailRepositoryUrl.from("proto://abc://def").getPath())
-            .isEqualTo(MailRepositoryPath.from("abc://def"));
+    void subPathShouldRejectSlashPrefixedSuffixes() {
+        assertThatThrownBy(() -> MailRepositoryPath.from("abc").subPath("/def"))
+            .isInstanceOf(IllegalArgumentException.class);
     }
-}
+}
\ No newline at end of file
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 64a6d5e..f0842c3 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
@@ -93,4 +93,28 @@ public class MailRepositoryUrlTest {
         assertThat(MailRepositoryUrl.from("proto://abc://def").getPath())
             .isEqualTo(MailRepositoryPath.from("abc://def"));
     }
+
+    @Test
+    void subUrlShouldAppendSuffix() {
+        assertThat(MailRepositoryUrl.from("proto://abc://def").subUrl("ghi"))
+            .isEqualTo(MailRepositoryUrl.from("proto://abc://def/ghi"));
+    }
+
+    @Test
+    void subUrlShouldAppendSuffixWhenMultipleParts() {
+        assertThat(MailRepositoryUrl.from("proto://abc://def").subUrl("ghi/jkl"))
+            .isEqualTo(MailRepositoryUrl.from("proto://abc://def/ghi/jkl"));
+    }
+
+    @Test
+    void subUrlShouldBeANoopWhenEmptySuffix() {
+        assertThat(MailRepositoryUrl.from("proto://abc://def").subUrl(""))
+            .isEqualTo(MailRepositoryUrl.from("proto://abc://def"));
+    }
+
+    @Test
+    void subUrlShouldRejectSuffixesStartingBySlash() {
+        assertThatThrownBy(() -> MailRepositoryUrl.from("proto://abc://def").subUrl("/ghi"))
+            .isInstanceOf(IllegalArgumentException.class);
+    }
 }
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 85a68c5..4ccd742 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
@@ -129,24 +129,24 @@ public class WebAdminServerIntegrationTest {
         .then()
             .statusCode(HttpStatus.OK_200)
             .body("repository", containsInAnyOrder(
-                "var/mail/error/",
-                "var/mail/relay-denied/",
-                "var/mail/address-error/"));
+                "var/mail/error",
+                "var/mail/relay-denied",
+                "var/mail/address-error"));
     }
 
     @Test
     public void gettingANonExistingMailRepositoryShouldNotCreateIt() {
         given()
-            .get(MailRepositoriesRoutes.MAIL_REPOSITORIES + "file%3A%2F%2Fvar%2Fmail%2Fcustom%2F");
+            .get(MailRepositoriesRoutes.MAIL_REPOSITORIES + "file%3A%2F%2Fvar%2Fmail%2Fcustom");
 
         when()
             .get(MailRepositoriesRoutes.MAIL_REPOSITORIES)
         .then()
             .statusCode(HttpStatus.OK_200)
             .body("repository", containsInAnyOrder(
-                "var/mail/error/",
-                "var/mail/relay-denied/",
-                "var/mail/address-error/"));
+                "var/mail/error",
+                "var/mail/relay-denied",
+                "var/mail/address-error"));
     }
 
     @Test


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