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/01/11 03:01:11 UTC

[01/10] james-project git commit: JAMES-2636 refactoring mapping types

Repository: james-project
Updated Branches:
  refs/heads/master 7e2a49a0d -> 2b5c162ef


JAMES-2636 refactoring mapping types


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

Branch: refs/heads/master
Commit: 14e264c66be28752e3e34abe2ad877057d842ec3
Parents: ca7818e
Author: Rene Cordier <rc...@linagora.com>
Authored: Thu Jan 10 10:14:33 2019 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Fri Jan 11 09:48:33 2019 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/rrt/lib/Mapping.java  | 111 +++++++------------
 .../org/apache/james/rrt/lib/MappingsImpl.java  |  24 +---
 2 files changed, 42 insertions(+), 93 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/14e264c6/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java
----------------------------------------------------------------------
diff --git a/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java b/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java
index e8d1198..379c9e7 100644
--- a/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java
+++ b/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java
@@ -45,42 +45,7 @@ public interface Mapping {
     }
 
     static Mapping of(Type type, String mapping) {
-        UserRewritter.MappingUserRewriter rewriter = selectRewriter(type);
-        IdentityMappingPolicy identityMappingPolicy = selectIdentityPolicy(type);
-        MailAddressConversionPolicy mailAddressConversionPolicy = selectMailAddressConversionPolicy(type);
-        return new Impl(type, mapping, rewriter.generateUserRewriter(mapping), identityMappingPolicy, mailAddressConversionPolicy);
-    }
-
-    static UserRewritter.MappingUserRewriter selectRewriter(Type type) {
-        switch (type) {
-            case Regex:
-                return new UserRewritter.RegexRewriter();
-            case Domain:
-                return new UserRewritter.DomainRewriter();
-            case Error:
-                return new UserRewritter.ThrowingRewriter();
-            case Forward:
-            case Group:
-            case Alias:
-            case Address:
-                return new UserRewritter.ReplaceRewriter();
-        }
-        throw new IllegalStateException("unhandle enum type");
-    }
-
-    static IdentityMappingPolicy selectIdentityPolicy(Type type) {
-        switch (type) {
-            case Regex:
-            case Domain:
-            case Error:
-            case Group:
-            case Address:
-            case Alias:
-                return IdentityMappingPolicy.Throw;
-            case Forward:
-                return IdentityMappingPolicy.ReturnIdentity;
-        }
-        throw new IllegalStateException("unhandle enum type");
+        return new Impl(type, mapping);
     }
 
     enum MailAddressConversionPolicy {
@@ -104,21 +69,6 @@ public interface Mapping {
         abstract Optional<MailAddress> convert(String mapping);
     }
 
-    static MailAddressConversionPolicy selectMailAddressConversionPolicy(Type type) {
-        switch (type) {
-            case Regex:
-            case Domain:
-            case Error:
-                return MailAddressConversionPolicy.ToEmpty;
-            case Forward:
-            case Group:
-            case Alias:
-            case Address:
-                return MailAddressConversionPolicy.ToMailAddress;
-            }
-        throw new IllegalStateException("unhandle enum type");
-    }
-
     static Mapping address(String mapping) {
         return of(Type.Address, mapping);
     }
@@ -155,25 +105,52 @@ public interface Mapping {
             .orElse(Type.Address);
     }
 
+    enum TypeOrder {
+        TYPE_ORDER_1,
+        TYPE_ORDER_2,
+        TYPE_ORDER_3,
+        TYPE_ORDER_4
+    }
+
     enum Type {
-        Regex("regex:"),
-        Domain("domain:"),
-        Error("error:"),
-        Forward("forward:"),
-        Group("group:"),
-        Alias("alias:"),
-        Address("");
+        Regex("regex:", new UserRewritter.RegexRewriter(), IdentityMappingPolicy.Throw,
+            MailAddressConversionPolicy.ToEmpty, TypeOrder.TYPE_ORDER_4),
+        Domain("domain:", new UserRewritter.DomainRewriter(), IdentityMappingPolicy.Throw,
+            MailAddressConversionPolicy.ToEmpty, TypeOrder.TYPE_ORDER_1),
+        Error("error:", new UserRewritter.ThrowingRewriter(), IdentityMappingPolicy.Throw,
+            MailAddressConversionPolicy.ToEmpty, TypeOrder.TYPE_ORDER_4),
+        Forward("forward:", new UserRewritter.ReplaceRewriter(), IdentityMappingPolicy.ReturnIdentity,
+            MailAddressConversionPolicy.ToMailAddress, TypeOrder.TYPE_ORDER_3),
+        Group("group:", new UserRewritter.ReplaceRewriter(), IdentityMappingPolicy.Throw,
+            MailAddressConversionPolicy.ToMailAddress, TypeOrder.TYPE_ORDER_2),
+        Alias("alias:", new UserRewritter.ReplaceRewriter(), IdentityMappingPolicy.Throw,
+            MailAddressConversionPolicy.ToMailAddress, TypeOrder.TYPE_ORDER_3),
+        Address("", new UserRewritter.ReplaceRewriter(), IdentityMappingPolicy.Throw,
+            MailAddressConversionPolicy.ToMailAddress, TypeOrder.TYPE_ORDER_4);
 
         private final String asPrefix;
+        private final UserRewritter.MappingUserRewriter rewriter;
+        private final IdentityMappingPolicy identityMappingPolicy;
+        private final MailAddressConversionPolicy mailAddressConversionPolicy;
+        private final TypeOrder typeOrder;
 
-        Type(String asPrefix) {
+        Type(String asPrefix, UserRewritter.MappingUserRewriter rewriter, IdentityMappingPolicy identityMappingPolicy,
+             MailAddressConversionPolicy mailAddressConversionPolicy, TypeOrder typeOrder) {
             this.asPrefix = asPrefix;
+            this.rewriter = rewriter;
+            this.identityMappingPolicy = identityMappingPolicy;
+            this.mailAddressConversionPolicy = mailAddressConversionPolicy;
+            this.typeOrder = typeOrder;
         }
 
         public String asPrefix() {
             return asPrefix;
         }
 
+        public int getTypeOrder() {
+            return typeOrder.ordinal();
+        }
+
         public String withoutPrefix(String input) {
             Preconditions.checkArgument(input.startsWith(asPrefix));
             return input.substring(asPrefix.length());
@@ -217,21 +194,13 @@ public interface Mapping {
         private final Type type;
         private final String mapping;
         private final UserRewritter rewriter;
-        private final IdentityMappingPolicy identityMappingPolicy;
-        private final MailAddressConversionPolicy mailAddressConversionPolicy;
 
-        private Impl(Type type,
-                     String mapping,
-                     UserRewritter rewriter,
-                     IdentityMappingPolicy identityMappingBehaviour,
-                     MailAddressConversionPolicy mailAddressConversionPolicy) {
+        private Impl(Type type, String mapping) {
             Preconditions.checkNotNull(type);
             Preconditions.checkNotNull(mapping);
             this.type = type;
             this.mapping = mapping;
-            this.rewriter = rewriter;
-            this.identityMappingPolicy = identityMappingBehaviour;
-            this.mailAddressConversionPolicy = mailAddressConversionPolicy;
+            this.rewriter = type.rewriter.generateUserRewriter(mapping);
         }
 
         @Override
@@ -284,12 +253,12 @@ public interface Mapping {
 
         @Override
         public Stream<Mapping> handleIdentity(Stream<Mapping> nonRecursiveResult) {
-            return identityMappingPolicy.handleIdentity(nonRecursiveResult);
+            return type.identityMappingPolicy.handleIdentity(nonRecursiveResult);
         }
 
         @Override
         public Optional<MailAddress> asMailAddress() {
-            return mailAddressConversionPolicy.convert(mapping);
+            return type.mailAddressConversionPolicy.convert(mapping);
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/14e264c6/server/data/data-api/src/main/java/org/apache/james/rrt/lib/MappingsImpl.java
----------------------------------------------------------------------
diff --git a/server/data/data-api/src/main/java/org/apache/james/rrt/lib/MappingsImpl.java b/server/data/data-api/src/main/java/org/apache/james/rrt/lib/MappingsImpl.java
index 9065626..7f58e24 100644
--- a/server/data/data-api/src/main/java/org/apache/james/rrt/lib/MappingsImpl.java
+++ b/server/data/data-api/src/main/java/org/apache/james/rrt/lib/MappingsImpl.java
@@ -48,31 +48,11 @@ public class MappingsImpl implements Mappings, Serializable {
     private static class DefaultMappingOrderingPolicy {
 
         private static final Comparator<Mapping> MAPPING_COMPARATOR = Comparator
-            .<Mapping, Integer>comparing(DefaultMappingOrderingPolicy::typeOrder)
+            .comparing(DefaultMappingOrderingPolicy::typeOrder)
             .thenComparing(Mapping::asString);
 
         private static int typeOrder(Mapping mapping) {
-            return typeOrder(mapping.getType());
-        }
-
-        private static int typeOrder(Mapping.Type type) {
-            switch (type) {
-                case Domain:
-                    return 1;
-                case Group:
-                    return 2;
-                case Forward:
-                    return 3;
-                case Alias:
-                    return 3;
-                case Regex:
-                    return 4;
-                case Error:
-                    return 4;
-                case Address:
-                    return 4;
-            }
-            throw new IllegalArgumentException("missing enum handling");
+            return mapping.getType().getTypeOrder();
         }
 
         public Comparator<Mapping> comparator() {


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


[08/10] james-project git commit: JAMES-2636 getUserDomainMappings should return empty object consistently when there is no mappings

Posted by bt...@apache.org.
JAMES-2636 getUserDomainMappings should return empty object consistently when there is no mappings


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

Branch: refs/heads/master
Commit: 106a284be1c4e4ea1d003f93ed709ac8e299dd43
Parents: 760a411
Author: Rene Cordier <rc...@linagora.com>
Authored: Fri Jan 4 15:52:20 2019 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Fri Jan 11 09:48:33 2019 +0700

----------------------------------------------------------------------
 .../apache/james/rrt/api/RecipientRewriteTable.java   |  9 +++++----
 .../rrt/cassandra/CassandraRecipientRewriteTable.java |  2 +-
 .../james/rrt/file/XMLRecipientRewriteTable.java      | 14 ++++----------
 .../james/rrt/file/XMLRecipientRewriteTableTest.java  | 14 +++++++-------
 .../james/rrt/jdbc/JDBCRecipientRewriteTable.java     |  6 +++---
 .../james/rrt/lib/AbstractRecipientRewriteTable.java  |  2 +-
 .../james/user/lib/AbstractJamesUsersRepository.java  |  2 +-
 .../rrt/lib/AbstractRecipientRewriteTableTest.java    | 12 ++++++++++--
 .../james/rrt/memory/MemoryRecipientRewriteTable.java |  2 +-
 .../james/webadmin/routes/DomainMappingsRoutes.java   |  2 +-
 .../apache/james/webadmin/routes/ForwardRoutes.java   |  4 +---
 .../apache/james/webadmin/routes/GroupsRoutes.java    |  4 +---
 12 files changed, 36 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/106a284b/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java
----------------------------------------------------------------------
diff --git a/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java b/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java
index 7efc0bd..96f62d3 100644
--- a/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java
+++ b/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java
@@ -49,7 +49,8 @@ public interface RecipientRewriteTable {
     EnumSet<Mapping.Type> listSourcesSupportedType = EnumSet.of(
         Mapping.Type.Group,
         Mapping.Type.Forward,
-        Mapping.Type.Address);
+        Mapping.Type.Address,
+        Mapping.Type.Alias);
 
     void addMapping(MappingSource source, Mapping mapping) throws RecipientRewriteTableException;
 
@@ -80,7 +81,7 @@ public interface RecipientRewriteTable {
     void removeGroupMapping(MappingSource source, String address) throws RecipientRewriteTableException;
 
     /**
-     * Return the Mappings for the given source. Return null if no
+     * Return the Mappings for the given source. Return empty object if no
      * matched mapping was found
      *
      * @throws ErrorMappingException
@@ -89,8 +90,8 @@ public interface RecipientRewriteTable {
     Mappings getResolvedMappings(String user, Domain domain) throws ErrorMappingException, RecipientRewriteTableException;
 
     /**
-     * Return the explicit mapping stored for the given user and domain. Return
-     * null if no mapping was found
+     * Return the explicit mapping stored for the given user and domain. Return empty object
+     * if no matched mapping was found
      * 
      * @return the collection which holds the mappings.
      * @throws RecipientRewriteTableException

http://git-wip-us.apache.org/repos/asf/james-project/blob/106a284b/server/data/data-cassandra/src/main/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTable.java
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTable.java b/server/data/data-cassandra/src/main/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTable.java
index ffefd98..332ec43 100644
--- a/server/data/data-cassandra/src/main/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTable.java
+++ b/server/data/data-cassandra/src/main/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTable.java
@@ -115,7 +115,7 @@ public class CassandraRecipientRewriteTable extends AbstractRecipientRewriteTabl
     @Override
     public Mappings getStoredMappings(MappingSource source) {
         return retrieveMappings(source)
-            .orElse(null);
+            .orElse(MappingsImpl.empty());
     }
 
     private Optional<Mappings> retrieveMappings(MappingSource source) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/106a284b/server/data/data-file/src/main/java/org/apache/james/rrt/file/XMLRecipientRewriteTable.java
----------------------------------------------------------------------
diff --git a/server/data/data-file/src/main/java/org/apache/james/rrt/file/XMLRecipientRewriteTable.java b/server/data/data-file/src/main/java/org/apache/james/rrt/file/XMLRecipientRewriteTable.java
index c192dbe..66b4bb8 100644
--- a/server/data/data-file/src/main/java/org/apache/james/rrt/file/XMLRecipientRewriteTable.java
+++ b/server/data/data-file/src/main/java/org/apache/james/rrt/file/XMLRecipientRewriteTable.java
@@ -69,16 +69,10 @@ public class XMLRecipientRewriteTable extends AbstractRecipientRewriteTable {
 
     @Override
     public Mappings getStoredMappings(MappingSource source) {
-        if (mappings == null) {
-            return null;
-        } else {
-            String maps = mappings.get(source);
-            if (maps != null) {
-                return MappingsImpl.fromRawString(maps);
-            } else {
-                return null;
-            }
-        }
+        return Optional.ofNullable(mappings)
+                .map(mappings -> mappings.get(source))
+                .map(MappingsImpl::fromRawString)
+                .orElse(MappingsImpl.empty());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/106a284b/server/data/data-file/src/test/java/org/apache/james/rrt/file/XMLRecipientRewriteTableTest.java
----------------------------------------------------------------------
diff --git a/server/data/data-file/src/test/java/org/apache/james/rrt/file/XMLRecipientRewriteTableTest.java b/server/data/data-file/src/test/java/org/apache/james/rrt/file/XMLRecipientRewriteTableTest.java
index aaa0820..16591e2 100644
--- a/server/data/data-file/src/test/java/org/apache/james/rrt/file/XMLRecipientRewriteTableTest.java
+++ b/server/data/data-file/src/test/java/org/apache/james/rrt/file/XMLRecipientRewriteTableTest.java
@@ -80,8 +80,7 @@ public class XMLRecipientRewriteTableTest extends AbstractRecipientRewriteTableT
     }
 
     protected void addMappingToConfiguration(MappingSource source, String mapping, Type type) throws RecipientRewriteTableException {
-        Mappings mappings = Optional.ofNullable(virtualUserTable.getStoredMappings(source))
-            .orElse(MappingsImpl.empty());
+        Mappings mappings = virtualUserTable.getStoredMappings(source);
 
         Mappings updatedMappings = MappingsImpl.from(mappings)
             .add(Mapping.of(type, mapping))
@@ -91,8 +90,11 @@ public class XMLRecipientRewriteTableTest extends AbstractRecipientRewriteTableT
     }
 
     protected void removeMappingFromConfiguration(MappingSource source, String mapping, Type type) throws RecipientRewriteTableException {
-        Mappings oldMappings = Optional.ofNullable(virtualUserTable.getStoredMappings(source))
-            .orElseThrow(() -> new RecipientRewriteTableException("Cannot remove from null mappings"));
+        Mappings oldMappings = virtualUserTable.getStoredMappings(source);
+
+        if (oldMappings.isEmpty()) {
+            throw new RecipientRewriteTableException("Cannot remove from null mappings");
+        }
 
         Mappings updatedMappings = oldMappings.remove(Mapping.of(type, mapping));
 
@@ -100,9 +102,7 @@ public class XMLRecipientRewriteTableTest extends AbstractRecipientRewriteTableT
     }
 
     private void updateConfiguration(MappingSource source, Mappings oldMappings, Mappings updatedMappings) throws RecipientRewriteTableException {
-        if (oldMappings != null) {
-            removeMappingsFromConfig(source, oldMappings);
-        }
+        removeMappingsFromConfig(source, oldMappings);
 
         if (!updatedMappings.isEmpty()) {
             defaultConfiguration.addProperty("mapping", source.getFixedUser() + "@" + source.getFixedDomain() + "=" + updatedMappings.serialize());

http://git-wip-us.apache.org/repos/asf/james-project/blob/106a284b/server/data/data-jdbc/src/main/java/org/apache/james/rrt/jdbc/JDBCRecipientRewriteTable.java
----------------------------------------------------------------------
diff --git a/server/data/data-jdbc/src/main/java/org/apache/james/rrt/jdbc/JDBCRecipientRewriteTable.java b/server/data/data-jdbc/src/main/java/org/apache/james/rrt/jdbc/JDBCRecipientRewriteTable.java
index d6d5920..fdf8625 100644
--- a/server/data/data-jdbc/src/main/java/org/apache/james/rrt/jdbc/JDBCRecipientRewriteTable.java
+++ b/server/data/data-jdbc/src/main/java/org/apache/james/rrt/jdbc/JDBCRecipientRewriteTable.java
@@ -190,7 +190,7 @@ public class JDBCRecipientRewriteTable extends AbstractRecipientRewriteTable {
     @Override
     public void addMapping(MappingSource source, Mapping mapping) throws RecipientRewriteTableException {
         Mappings map = getStoredMappings(source);
-        if (map != null && map.size() != 0) {
+        if (!map.isEmpty()) {
             Mappings updatedMappings = MappingsImpl.from(map).add(mapping).build();
             doUpdateMapping(source, updatedMappings.serialize());
         }
@@ -252,7 +252,7 @@ public class JDBCRecipientRewriteTable extends AbstractRecipientRewriteTable {
             theJDBCUtil.closeJDBCStatement(mappingStmt);
             theJDBCUtil.closeJDBCConnection(conn);
         }
-        return null;
+        return MappingsImpl.empty();
     }
 
     @Override
@@ -292,7 +292,7 @@ public class JDBCRecipientRewriteTable extends AbstractRecipientRewriteTable {
     @Override
     public void removeMapping(MappingSource source, Mapping mapping) throws RecipientRewriteTableException {
         Mappings map = getStoredMappings(source);
-        if (map != null && map.size() > 1) {
+        if (map.size() > 1) {
             Mappings updatedMappings = map.remove(mapping);
             doUpdateMapping(source, updatedMappings.serialize());
         } else {

http://git-wip-us.apache.org/repos/asf/james-project/blob/106a284b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java
----------------------------------------------------------------------
diff --git a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java
index 053f053..d6acf8f 100644
--- a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java
+++ b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java
@@ -314,7 +314,7 @@ public abstract class AbstractRecipientRewriteTable implements RecipientRewriteT
 
     private void checkDuplicateMapping(MappingSource source, Mapping mapping) throws RecipientRewriteTableException {
         Mappings mappings = getStoredMappings(source);
-        if (mappings != null && mappings.contains(mapping)) {
+        if (mappings.contains(mapping)) {
             throw new MappingAlreadyExistsException("Mapping " + mapping + " for " + source.asString() + " already exist!");
         }
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/106a284b/server/data/data-library/src/main/java/org/apache/james/user/lib/AbstractJamesUsersRepository.java
----------------------------------------------------------------------
diff --git a/server/data/data-library/src/main/java/org/apache/james/user/lib/AbstractJamesUsersRepository.java b/server/data/data-library/src/main/java/org/apache/james/user/lib/AbstractJamesUsersRepository.java
index 3913533..44f731a 100644
--- a/server/data/data-library/src/main/java/org/apache/james/user/lib/AbstractJamesUsersRepository.java
+++ b/server/data/data-library/src/main/java/org/apache/james/user/lib/AbstractJamesUsersRepository.java
@@ -206,7 +206,7 @@ public abstract class AbstractJamesUsersRepository extends AbstractUsersReposito
     }
 
     @Override
-    public Mappings getStoredMappings(MappingSource source) throws RecipientRewriteTableException {
+    public Mappings getStoredMappings(MappingSource source) {
         return MappingsImpl.empty();
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/106a284b/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java
----------------------------------------------------------------------
diff --git a/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java b/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java
index e6fe5b7..b9bfe0a 100644
--- a/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java
+++ b/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java
@@ -347,7 +347,7 @@ public abstract class AbstractRecipientRewriteTableTest {
         virtualUserTable.addMapping(source, Mapping.alias(ADDRESS));
         virtualUserTable.addMapping(source, Mapping.alias(address2));
 
-        assertThat(virtualUserTable.getUserDomainMappings(source)).hasSize(2);
+        assertThat(virtualUserTable.getStoredMappings(source)).hasSize(2);
     }
 
     @Test
@@ -362,11 +362,19 @@ public abstract class AbstractRecipientRewriteTableTest {
         virtualUserTable.removeMapping(source, Mapping.alias(ADDRESS));
         virtualUserTable.removeMapping(source, Mapping.alias(address2));
 
-        assertThat(virtualUserTable.getUserDomainMappings(source))
+        assertThat(virtualUserTable.getStoredMappings(source))
                 .isEqualTo(MappingsImpl.empty());
     }
 
     @Test
+    public void getUserDomainMappingShouldBeEmptyByDefault() throws Exception {
+        Domain domain = Domain.LOCALHOST;
+        MappingSource source = MappingSource.fromUser(USER, domain);
+
+        assertThat(virtualUserTable.getStoredMappings(source)).isEmpty();
+    }
+
+    @Test
     public void listSourcesShouldReturnWhenHasMapping() throws Exception {
         MappingSource source = MappingSource.fromUser(USER, Domain.LOCALHOST);
         Mapping mapping = Mapping.group(ADDRESS);

http://git-wip-us.apache.org/repos/asf/james-project/blob/106a284b/server/data/data-memory/src/main/java/org/apache/james/rrt/memory/MemoryRecipientRewriteTable.java
----------------------------------------------------------------------
diff --git a/server/data/data-memory/src/main/java/org/apache/james/rrt/memory/MemoryRecipientRewriteTable.java b/server/data/data-memory/src/main/java/org/apache/james/rrt/memory/MemoryRecipientRewriteTable.java
index 8fc2e11..7b782eb 100644
--- a/server/data/data-memory/src/main/java/org/apache/james/rrt/memory/MemoryRecipientRewriteTable.java
+++ b/server/data/data-memory/src/main/java/org/apache/james/rrt/memory/MemoryRecipientRewriteTable.java
@@ -96,7 +96,7 @@ public class MemoryRecipientRewriteTable extends AbstractRecipientRewriteTable {
     @Override
     public Mappings getStoredMappings(MappingSource mappingSource) {
         return retrieveMappings(mappingSource)
-            .orElse(null);
+            .orElse(MappingsImpl.empty());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/106a284b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DomainMappingsRoutes.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DomainMappingsRoutes.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DomainMappingsRoutes.java
index cfd3ac8..800d25f 100644
--- a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DomainMappingsRoutes.java
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DomainMappingsRoutes.java
@@ -160,7 +160,7 @@ public class DomainMappingsRoutes implements Routes {
     public List<String> getMapping(Request request, Response response) throws RecipientRewriteTableException {
         MappingSource mappingSource = mappingSourceFrom(request);
 
-        return Optional.ofNullable(recipientRewriteTable.getStoredMappings(mappingSource).select(Mapping.Type.Domain))
+        return Optional.of(recipientRewriteTable.getStoredMappings(mappingSource).select(Mapping.Type.Domain))
                 .filter(mappings -> !mappings.isEmpty())
                 .filter(mappings -> mappings.contains(Mapping.Type.Domain))
                 .map(this::toDomainList)

http://git-wip-us.apache.org/repos/asf/james-project/blob/106a284b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/ForwardRoutes.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/ForwardRoutes.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/ForwardRoutes.java
index 3be3c42..f75a34b 100644
--- a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/ForwardRoutes.java
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/ForwardRoutes.java
@@ -47,7 +47,6 @@ import org.apache.james.rrt.api.RecipientRewriteTableException;
 import org.apache.james.rrt.lib.Mapping;
 import org.apache.james.rrt.lib.MappingSource;
 import org.apache.james.rrt.lib.Mappings;
-import org.apache.james.rrt.lib.MappingsImpl;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.util.OptionalUtils;
@@ -234,8 +233,7 @@ public class ForwardRoutes implements Routes {
     })
     public ImmutableSet<ForwardDestinationResponse> listForwardDestinations(Request request, Response response) throws RecipientRewriteTableException {
         MailAddress baseAddress = parseMailAddress(request.params(FORWARD_BASE_ADDRESS));
-        Mappings mappings = Optional.ofNullable(recipientRewriteTable.getStoredMappings(MappingSource.fromMailAddress(baseAddress)))
-            .orElse(MappingsImpl.empty())
+        Mappings mappings = recipientRewriteTable.getStoredMappings(MappingSource.fromMailAddress(baseAddress))
             .select(Mapping.Type.Forward);
 
         ensureNonEmptyMappings(mappings);

http://git-wip-us.apache.org/repos/asf/james-project/blob/106a284b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/GroupsRoutes.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/GroupsRoutes.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/GroupsRoutes.java
index 110256b..492b7be 100644
--- a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/GroupsRoutes.java
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/GroupsRoutes.java
@@ -49,7 +49,6 @@ import org.apache.james.rrt.api.RecipientRewriteTableException;
 import org.apache.james.rrt.lib.Mapping;
 import org.apache.james.rrt.lib.MappingSource;
 import org.apache.james.rrt.lib.Mappings;
-import org.apache.james.rrt.lib.MappingsImpl;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.util.OptionalUtils;
@@ -242,8 +241,7 @@ public class GroupsRoutes implements Routes {
     })
     public ImmutableSortedSet<String> listGroupMembers(Request request, Response response) throws RecipientRewriteTableException {
         MailAddress groupAddress = parseMailAddress(request.params(GROUP_ADDRESS));
-        Mappings mappings = Optional.ofNullable(recipientRewriteTable.getStoredMappings(MappingSource.fromMailAddress(groupAddress)))
-            .orElse(MappingsImpl.empty())
+        Mappings mappings = recipientRewriteTable.getStoredMappings(MappingSource.fromMailAddress(groupAddress))
             .select(Mapping.Type.Group);
 
         ensureNonEmptyMappings(mappings);


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


[09/10] james-project git commit: JAMES-2637 add PUT route for aliases routes

Posted by bt...@apache.org.
JAMES-2637 add PUT route for aliases routes


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

Branch: refs/heads/master
Commit: de15eaa6c4178b39d2405c2c944651456ea8b03a
Parents: 14e264c
Author: Rene Cordier <rc...@linagora.com>
Authored: Tue Jan 8 16:28:14 2019 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Fri Jan 11 09:48:34 2019 +0700

----------------------------------------------------------------------
 .../james/modules/server/DataRoutesModules.java |   2 +
 .../integration/UnauthorizedEndpointsTest.java  |   2 +
 .../WebAdminServerIntegrationTest.java          |   1 +
 .../james/webadmin/routes/AliasRoutes.java      | 139 ++++++++
 .../webadmin/routes/MailAddressParser.java      |  60 ++++
 .../james/webadmin/routes/AliasRoutesTest.java  | 348 +++++++++++++++++++
 src/site/markdown/server/manage-webadmin.md     |  31 ++
 7 files changed, 583 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/de15eaa6/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DataRoutesModules.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DataRoutesModules.java b/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DataRoutesModules.java
index ef695fa..a2726af 100644
--- a/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DataRoutesModules.java
+++ b/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DataRoutesModules.java
@@ -20,6 +20,7 @@
 package org.apache.james.modules.server;
 
 import org.apache.james.webadmin.Routes;
+import org.apache.james.webadmin.routes.AliasRoutes;
 import org.apache.james.webadmin.routes.DomainMappingsRoutes;
 import org.apache.james.webadmin.routes.DomainsRoutes;
 import org.apache.james.webadmin.routes.ForwardRoutes;
@@ -34,6 +35,7 @@ public class DataRoutesModules extends AbstractModule {
     @Override
     protected void configure() {
         Multibinder<Routes> routesMultibinder = Multibinder.newSetBinder(binder(), Routes.class);
+        routesMultibinder.addBinding().to(AliasRoutes.class);
         routesMultibinder.addBinding().to(DomainsRoutes.class);
         routesMultibinder.addBinding().to(DomainMappingsRoutes.class);
         routesMultibinder.addBinding().to(ForwardRoutes.class);

http://git-wip-us.apache.org/repos/asf/james-project/blob/de15eaa6/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/UnauthorizedEndpointsTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/UnauthorizedEndpointsTest.java b/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/UnauthorizedEndpointsTest.java
index dc2140f..f20b041 100644
--- a/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/UnauthorizedEndpointsTest.java
+++ b/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/UnauthorizedEndpointsTest.java
@@ -24,6 +24,7 @@ import static io.restassured.RestAssured.when;
 import org.apache.james.GuiceJamesServer;
 import org.apache.james.utils.WebAdminGuiceProbe;
 import org.apache.james.webadmin.WebAdminUtils;
+import org.apache.james.webadmin.routes.AliasRoutes;
 import org.apache.james.webadmin.routes.CassandraMigrationRoutes;
 import org.apache.james.webadmin.routes.DLPConfigurationRoutes;
 import org.apache.james.webadmin.routes.DomainMappingsRoutes;
@@ -127,6 +128,7 @@ class UnauthorizedEndpointsTest {
             UserQuotaRoutes.USERS_QUOTA_ENDPOINT + "/joe@perdu.com/size",
             UserRoutes.USERS + "/user@james.org",
             ForwardRoutes.ROOT_PATH + "/alice@james.org/bob@james.org",
+            AliasRoutes.ROOT_PATH + "/bob@james.org/sources/bob-alias@james.org",
             GlobalQuotaRoutes.QUOTA_ENDPOINT + "/count",
             GlobalQuotaRoutes.QUOTA_ENDPOINT + "/size",
             GlobalQuotaRoutes.QUOTA_ENDPOINT,

http://git-wip-us.apache.org/repos/asf/james-project/blob/de15eaa6/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 61e690b..23c0e2e 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
@@ -326,6 +326,7 @@ public class WebAdminServerIntegrationTest {
             .body(containsString("\"tags\":[\"MailRepositories\"]"))
             .body(containsString("\"tags\":[\"MailQueues\"]"))
             .body(containsString("\"tags\":[\"Address Forwards\"]"))
+            .body(containsString("\"tags\":[\"Address Aliases\"]"))
             .body(containsString("\"tags\":[\"Address Groups\"]"))
             .body(containsString("{\"name\":\"ReIndexing (mailboxes)\"}"))
             .body(containsString("{\"name\":\"MessageIdReIndexing\"}"));

http://git-wip-us.apache.org/repos/asf/james-project/blob/de15eaa6/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/AliasRoutes.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/AliasRoutes.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/AliasRoutes.java
new file mode 100644
index 0000000..583858d
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/AliasRoutes.java
@@ -0,0 +1,139 @@
+/****************************************************************
+ * 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.routes;
+
+import static org.apache.james.webadmin.Constants.SEPARATOR;
+import static spark.Spark.halt;
+
+import javax.inject.Inject;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+
+import org.apache.james.core.MailAddress;
+import org.apache.james.core.User;
+import org.apache.james.rrt.api.MappingAlreadyExistsException;
+import org.apache.james.rrt.api.RecipientRewriteTable;
+import org.apache.james.rrt.api.RecipientRewriteTableException;
+import org.apache.james.rrt.lib.MappingSource;
+import org.apache.james.user.api.UsersRepository;
+import org.apache.james.user.api.UsersRepositoryException;
+import org.apache.james.webadmin.Constants;
+import org.apache.james.webadmin.Routes;
+import org.apache.james.webadmin.utils.ErrorResponder;
+import org.eclipse.jetty.http.HttpStatus;
+
+import com.google.common.annotations.VisibleForTesting;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import spark.HaltException;
+import spark.Request;
+import spark.Response;
+import spark.Service;
+
+@Api(tags = "Address Aliases")
+@Path(AliasRoutes.ROOT_PATH)
+@Produces(Constants.JSON_CONTENT_TYPE)
+public class AliasRoutes implements Routes {
+
+    public static final String ROOT_PATH = "address/aliases";
+
+    private static final String ALIAS_DESTINATION_ADDRESS = "aliasDestinationAddress";
+    private static final String ALIAS_ADDRESS_PATH = ROOT_PATH + SEPARATOR + ":" + ALIAS_DESTINATION_ADDRESS;
+    private static final String ALIAS_SOURCE_ADDRESS = "aliasSourceAddress";
+    private static final String USER_IN_ALIAS_SOURCES_ADDRESSES_PATH = ALIAS_ADDRESS_PATH + SEPARATOR +
+        "sources" + SEPARATOR + ":" + ALIAS_SOURCE_ADDRESS;
+    private static final String MAILADDRESS_ASCII_DISCLAIMER = "Note that email addresses are restricted to ASCII character set. " +
+        "Mail addresses not matching this criteria will be rejected.";
+    private static final String ADDRESS_TYPE = "alias";
+
+    private final UsersRepository usersRepository;
+    private final RecipientRewriteTable recipientRewriteTable;
+
+    @Inject
+    @VisibleForTesting
+    AliasRoutes(RecipientRewriteTable recipientRewriteTable, UsersRepository usersRepository) {
+        this.usersRepository = usersRepository;
+        this.recipientRewriteTable = recipientRewriteTable;
+    }
+
+    @Override
+    public String getBasePath() {
+        return ROOT_PATH;
+    }
+
+    @Override
+    public void define(Service service) {
+        service.put(USER_IN_ALIAS_SOURCES_ADDRESSES_PATH, this::addToAliasSources);
+    }
+
+    @PUT
+    @Path(ROOT_PATH + "/{" + ALIAS_DESTINATION_ADDRESS + "}/sources/{" + ALIAS_SOURCE_ADDRESS + "}")
+    @ApiOperation(value = "adding a source address into an alias")
+    @ApiImplicitParams({
+        @ApiImplicitParam(required = true, dataType = "string", name = ALIAS_DESTINATION_ADDRESS, paramType = "path",
+            value = "Destination mail address of the alias. Sending a mail to the alias source address will send it to " +
+                "that email address.\n" +
+                MAILADDRESS_ASCII_DISCLAIMER),
+        @ApiImplicitParam(required = true, dataType = "string", name = ALIAS_SOURCE_ADDRESS, paramType = "path",
+            value = "Source mail address of the alias. Sending a mail to that address will send it to " +
+                "the email destination address.\n" +
+                MAILADDRESS_ASCII_DISCLAIMER)
+    })
+    @ApiResponses(value = {
+        @ApiResponse(code = HttpStatus.NO_CONTENT_204, message = "OK"),
+        @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = ALIAS_DESTINATION_ADDRESS + " or alias structure format is not valid"),
+        @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "The alias source exists as an user already"),
+        @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
+            message = "Internal server error - Something went bad on the server side.")
+    })
+    public HaltException addToAliasSources(Request request, Response response) throws UsersRepositoryException, RecipientRewriteTableException {
+        MailAddress aliasSourceAddress = MailAddressParser.parseMailAddress(request.params(ALIAS_SOURCE_ADDRESS), ADDRESS_TYPE);
+        ensureUserDoesNotExist(aliasSourceAddress);
+        MailAddress destinationAddress = MailAddressParser.parseMailAddress(request.params(ALIAS_DESTINATION_ADDRESS), ADDRESS_TYPE);
+        MappingSource source = MappingSource.fromUser(User.fromMailAddress(destinationAddress));
+        addAlias(source, aliasSourceAddress);
+        return halt(HttpStatus.NO_CONTENT_204);
+    }
+
+    private void addAlias(MappingSource source, MailAddress aliasSourceAddress) throws RecipientRewriteTableException {
+        try {
+            recipientRewriteTable.addAliasMapping(source, aliasSourceAddress.asString());
+        } catch (MappingAlreadyExistsException e) {
+            // ignore
+        }
+    }
+
+    private void ensureUserDoesNotExist(MailAddress mailAddress) throws UsersRepositoryException {
+        String username = usersRepository.getUser(mailAddress);
+
+        if (usersRepository.contains(username)) {
+            throw ErrorResponder.builder()
+                .statusCode(HttpStatus.BAD_REQUEST_400)
+                .type(ErrorResponder.ErrorType.INVALID_ARGUMENT)
+                .message("The alias source exists as an user already")
+                .haltError();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/de15eaa6/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/MailAddressParser.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/MailAddressParser.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/MailAddressParser.java
new file mode 100644
index 0000000..ff363a0
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/MailAddressParser.java
@@ -0,0 +1,60 @@
+/****************************************************************
+ * 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.routes;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import javax.mail.internet.AddressException;
+
+import org.apache.james.core.MailAddress;
+import org.apache.james.webadmin.utils.ErrorResponder;
+import org.eclipse.jetty.http.HttpStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class MailAddressParser {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(MailAddressParser.class);
+
+    static MailAddress parseMailAddress(String address, String addressType) {
+        try {
+            String decodedAddress = URLDecoder.decode(address, StandardCharsets.UTF_8.displayName());
+            return new MailAddress(decodedAddress);
+        } catch (AddressException e) {
+            LOGGER.error("The " + addressType + " " + address + " is not an email address");
+            throw ErrorResponder.builder()
+                .statusCode(HttpStatus.BAD_REQUEST_400)
+                .type(ErrorResponder.ErrorType.INVALID_ARGUMENT)
+                .message("The " + addressType + " is not an email address")
+                .cause(e)
+                .haltError();
+        } catch (UnsupportedEncodingException e) {
+            LOGGER.error("UTF-8 should be a valid encoding");
+            throw ErrorResponder.builder()
+                .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500)
+                .type(ErrorResponder.ErrorType.SERVER_ERROR)
+                .message("Internal server error - Something went bad on the server side.")
+                .cause(e)
+                .haltError();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/de15eaa6/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/AliasRoutesTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/AliasRoutesTest.java b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/AliasRoutesTest.java
new file mode 100644
index 0000000..9eb0744
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/AliasRoutesTest.java
@@ -0,0 +1,348 @@
+/****************************************************************
+ * 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.routes;
+
+import io.restassured.RestAssured;
+import io.restassured.filter.log.LogDetail;
+import io.restassured.http.ContentType;
+import org.apache.commons.configuration.DefaultConfigurationBuilder;
+import org.apache.james.core.Domain;
+import org.apache.james.dnsservice.api.DNSService;
+import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.domainlist.lib.DomainListConfiguration;
+import org.apache.james.domainlist.memory.MemoryDomainList;
+import org.apache.james.metrics.logger.DefaultMetricFactory;
+import org.apache.james.rrt.api.RecipientRewriteTable;
+import org.apache.james.rrt.api.RecipientRewriteTableException;
+import org.apache.james.rrt.lib.Mapping;
+import org.apache.james.rrt.lib.MappingSource;
+import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
+import org.apache.james.user.api.UsersRepository;
+import org.apache.james.user.memory.MemoryUsersRepository;
+import org.apache.james.webadmin.WebAdminServer;
+import org.apache.james.webadmin.WebAdminUtils;
+import org.eclipse.jetty.http.HttpStatus;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import java.util.Map;
+
+import static io.restassured.RestAssured.given;
+import static io.restassured.RestAssured.when;
+import static io.restassured.RestAssured.with;
+import static org.apache.james.webadmin.Constants.SEPARATOR;
+import static org.apache.james.webadmin.WebAdminServer.NO_CONFIGURATION;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.CoreMatchers.hasItems;
+import static org.hamcrest.CoreMatchers.is;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+
+class AliasRoutesTest {
+
+    private static final Domain DOMAIN = Domain.of("b.com");
+    public static final String BOB = "bob@" + DOMAIN.name();
+    public static final String BOB_WITH_SLASH = "bob/@" + DOMAIN.name();
+    public static final String BOB_WITH_ENCODED_SLASH = "bob%2F@" + DOMAIN.name();
+    public static final String BOB_ALIAS = "bob-alias@" + DOMAIN.name();
+    public static final String BOB_ALIAS_2 = "bob-alias2@" + DOMAIN.name();
+    public static final String BOB_ALIAS_WITH_SLASH = "bob-alias/@" + DOMAIN.name();
+    public static final String BOB_ALIAS_WITH_ENCODED_SLASH = "bob-alias%2F@" + DOMAIN.name();
+    public static final String ALICE = "alice@" + DOMAIN.name();
+    public static final String BOB_PASSWORD = "123456";
+    public static final String BOB_WITH_SLASH_PASSWORD = "abcdef";
+    public static final String ALICE_PASSWORD = "789123";
+
+    private static final MappingSource BOB_SOURCE = MappingSource.fromUser("bob", DOMAIN);
+    private static final MappingSource BOB_WITH_ENCODED_SLASH_SOURCE = MappingSource.fromUser("bob/", DOMAIN);
+    private static final Mapping BOB_MAPPING = Mapping.alias(BOB_ALIAS);
+
+    private WebAdminServer webAdminServer;
+
+    private void createServer(AliasRoutes aliasRoutes) throws Exception {
+        webAdminServer = WebAdminUtils.createWebAdminServer(
+            new DefaultMetricFactory(),
+            aliasRoutes);
+        webAdminServer.configure(NO_CONFIGURATION);
+        webAdminServer.await();
+
+        RestAssured.requestSpecification = WebAdminUtils.buildRequestSpecification(webAdminServer)
+            .setBasePath("address/aliases")
+            .log(LogDetail.METHOD)
+            .build();
+    }
+
+    @AfterEach
+    void stop() {
+        webAdminServer.destroy();
+    }
+
+    @Nested
+    class NormalBehaviour {
+
+        MemoryUsersRepository usersRepository;
+        MemoryDomainList domainList;
+        MemoryRecipientRewriteTable memoryRecipientRewriteTable;
+
+        @BeforeEach
+        void setUp() throws Exception {
+            memoryRecipientRewriteTable = new MemoryRecipientRewriteTable();
+            DNSService dnsService = mock(DNSService.class);
+            domainList = new MemoryDomainList(dnsService);
+            domainList.configure(DomainListConfiguration.builder()
+                .autoDetect(false)
+                .autoDetectIp(false));
+            domainList.addDomain(DOMAIN);
+
+            usersRepository = MemoryUsersRepository.withVirtualHosting();
+            usersRepository.setDomainList(domainList);
+            usersRepository.configure(new DefaultConfigurationBuilder());
+
+            usersRepository.addUser(BOB, BOB_PASSWORD);
+            usersRepository.addUser(BOB_WITH_SLASH, BOB_WITH_SLASH_PASSWORD);
+            usersRepository.addUser(ALICE, ALICE_PASSWORD);
+
+            createServer(new AliasRoutes(memoryRecipientRewriteTable, usersRepository));
+        }
+
+        @Test
+        void putAliasForUserShouldReturnNoContent() {
+            when()
+                .put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS)
+            .then()
+                .statusCode(HttpStatus.NO_CONTENT_204);
+        }
+
+        @Test
+        void putAliasShouldBeIdempotent() {
+            given()
+                .put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
+
+            when()
+                .put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS)
+            .then()
+                .statusCode(HttpStatus.NO_CONTENT_204);
+        }
+
+        @Test
+        void putAliasWithSlashForUserShouldReturnNoContent() {
+            when()
+                .put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS_WITH_ENCODED_SLASH)
+            .then()
+                .statusCode(HttpStatus.NO_CONTENT_204);
+        }
+
+        @Test
+        void putUserForAliasWithEncodedSlashShouldReturnNoContent() {
+            when()
+                .put(BOB_WITH_ENCODED_SLASH + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS)
+            .then()
+                .statusCode(HttpStatus.NO_CONTENT_204);
+        }
+
+        @Test
+        void putExistingUserAsAliasSourceShouldNotBePossible() {
+            Map<String, Object> errors = when()
+                .put(BOB + SEPARATOR + "sources" + SEPARATOR + ALICE)
+            .then()
+                .statusCode(HttpStatus.BAD_REQUEST_400)
+                .contentType(ContentType.JSON)
+                .extract()
+                .body()
+                .jsonPath()
+                .getMap(".");
+
+            assertThat(errors)
+                .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400)
+                .containsEntry("type", "InvalidArgument")
+                .containsEntry("message", "The alias source exists as an user already");
+        }
+
+        @Test
+        void putAliasForUserShouldCreateAlias() {
+            with()
+                .put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
+
+            assertThat(memoryRecipientRewriteTable.getStoredMappings(BOB_SOURCE)).containsOnly(BOB_MAPPING);
+        }
+
+        @Test
+        void putAliasWithEncodedSlashForUserShouldAddItAsADestination() {
+            Mapping mapping = Mapping.alias(BOB_ALIAS_WITH_SLASH);
+
+            with()
+                .put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS_WITH_ENCODED_SLASH);
+
+            assertThat(memoryRecipientRewriteTable.getStoredMappings(BOB_SOURCE)).containsOnly(mapping);
+        }
+
+        @Test
+        void putAliasForUserWithEncodedSlashShouldCreateForward() {
+            with()
+                .put(BOB_WITH_ENCODED_SLASH + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
+
+            assertThat(memoryRecipientRewriteTable.getStoredMappings(BOB_WITH_ENCODED_SLASH_SOURCE)).containsOnly(BOB_MAPPING);
+        }
+
+        @Test
+        void putSameAliasForUserTwiceShouldBeIdempotent() {
+            with()
+                .put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
+
+            with()
+                .put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
+
+            assertThat(memoryRecipientRewriteTable.getStoredMappings(BOB_SOURCE)).containsOnly(BOB_MAPPING);
+        }
+
+        @Test
+        void putAliasForUserShouldAllowSeveralSources() {
+            Mapping mapping2 = Mapping.alias(BOB_ALIAS_2);
+
+            with()
+                .put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
+
+            with()
+                .put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS_2);
+
+            assertThat(memoryRecipientRewriteTable.getStoredMappings(BOB_SOURCE)).containsOnly(BOB_MAPPING, mapping2);
+        }
+    }
+
+    @Nested
+    class FilteringOtherRewriteRuleTypes extends NormalBehaviour {
+
+        @BeforeEach
+        void setup() throws Exception {
+            super.setUp();
+            memoryRecipientRewriteTable.addErrorMapping(MappingSource.fromUser("error", DOMAIN), "disabled");
+            memoryRecipientRewriteTable.addRegexMapping(MappingSource.fromUser("regex", DOMAIN), ".*@b\\.com");
+            memoryRecipientRewriteTable.addAliasDomainMapping(MappingSource.fromDomain(Domain.of("alias")), DOMAIN);
+        }
+
+    }
+
+    @Nested
+    class ExceptionHandling {
+
+        private RecipientRewriteTable memoryRecipientRewriteTable;
+
+        @BeforeEach
+        void setUp() throws Exception {
+            memoryRecipientRewriteTable = mock(RecipientRewriteTable.class);
+            UsersRepository userRepository = mock(UsersRepository.class);
+            DomainList domainList = mock(DomainList.class);
+            Mockito.when(domainList.containsDomain(any())).thenReturn(true);
+            createServer(new AliasRoutes(memoryRecipientRewriteTable, userRepository));
+        }
+
+        @Test
+        void putMalformedUserDestinationShouldReturnBadRequest() {
+            Map<String, Object> errors = when()
+                .put("not-an-address" + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS)
+            .then()
+                .statusCode(HttpStatus.BAD_REQUEST_400)
+                .contentType(ContentType.JSON)
+                .extract()
+                .body()
+                .jsonPath()
+                .getMap(".");
+
+            assertThat(errors)
+                .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400)
+                .containsEntry("type", "InvalidArgument")
+                .containsEntry("message", "The alias is not an email address")
+                .containsEntry("details", "Out of data at position 1 in 'not-an-address'");
+        }
+
+        @Test
+        void putMalformedAliasSourceShouldReturnBadRequest() {
+            Map<String, Object> errors = when()
+                .put(BOB + SEPARATOR + "sources" + SEPARATOR + "not-an-address")
+            .then()
+                .statusCode(HttpStatus.BAD_REQUEST_400)
+                .contentType(ContentType.JSON)
+                .extract()
+                .body()
+                .jsonPath()
+                .getMap(".");
+
+            assertThat(errors)
+                .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400)
+                .containsEntry("type", "InvalidArgument")
+                .containsEntry("message", "The alias is not an email address")
+                .containsEntry("details", "Out of data at position 1 in 'not-an-address'");
+        }
+
+        @Test
+        void putUserDestinationInForwardWithSlashShouldReturnNotFound() {
+            when()
+                .put(BOB_WITH_SLASH + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS)
+            .then()
+                .statusCode(HttpStatus.NOT_FOUND_404);
+        }
+
+        @Test
+        void putAliasSourceWithSlashShouldReturnNotFound() {
+            when()
+                .put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS_WITH_SLASH)
+            .then()
+                .statusCode(HttpStatus.NOT_FOUND_404);
+        }
+
+        @Test
+        void putRequiresTwoPathParams() {
+            when()
+                .put(BOB)
+            .then()
+                .statusCode(HttpStatus.NOT_FOUND_404);
+        }
+
+        @Test
+        void putShouldReturnErrorWhenRecipientRewriteTableExceptionIsThrown() throws Exception {
+            doThrow(RecipientRewriteTableException.class)
+                .when(memoryRecipientRewriteTable)
+                .addAliasMapping(any(), anyString());
+
+            when()
+                .put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS)
+            .then()
+                .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500);
+        }
+
+        @Test
+        void putShouldReturnErrorWhenRuntimeExceptionIsThrown() throws Exception {
+            doThrow(RuntimeException.class)
+                .when(memoryRecipientRewriteTable)
+                .addAliasMapping(any(), anyString());
+
+            when()
+                .put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS)
+            .then()
+                .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/de15eaa6/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 2ba0255..c0a7b8b 100644
--- a/src/site/markdown/server/manage-webadmin.md
+++ b/src/site/markdown/server/manage-webadmin.md
@@ -37,6 +37,7 @@ as exposed above). To avoid information duplication, this is ommited on endpoint
  - [Correcting ghost mailbox](#Correcting_ghost_mailbox)
  - [Creating address group](#Creating_address_group)
  - [Creating address forwards](#Creating_address_forwards)
+ - [Creating address aliases](#Creating_address_aliases)
  - [Administrating mail repositories](#Administrating_mail_repositories)
  - [Administrating mail queues](#Administrating_mail_queues)
  - [Administrating DLP Configuration](#Administrating_dlp_configuration)
@@ -1299,6 +1300,36 @@ Response codes:
  - 204: Success
  - 400: Forward structure or member is not valid
 
+## Creating address aliases
+
+You can use **webadmin** to define aliases for an user.
+
+When a specific email is sent to the alias address, the destination address of the alias will receive it.
+
+Aliases can be defined for existing users.
+
+This feature uses [Recipients rewrite table](/server/config-recipientrewritetable.html) and requires
+the [RecipientRewriteTable mailet](https://github.com/apache/james-project/blob/master/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RecipientRewriteTable.java)
+to be configured.
+
+Note that email addresses are restricted to ASCII character set. Mail addresses not matching this criteria will be rejected.
+
+ - [Adding a new alias to an user](#Adding_a_new_alias_to_an_user)
+
+### Adding a new alias to an user
+
+```
+curl -XPUT http://ip:port/address/aliases/user@domain.com/sources/alias@domain.com
+```
+
+Will add alias@domain.com to user@domain.com, creating the alias if needed
+
+Response codes:
+
+ - 204: OK
+ - 400: Alias structure or member is not valid
+ - 400: The alias source exists as an user already
+
 ## Administrating mail repositories
 
  - [Create a mail repository](#Create_a_mail_repository)


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


[10/10] james-project git commit: JAMES-2637 refactoring group and forward routes

Posted by bt...@apache.org.
JAMES-2637 refactoring group and forward routes


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

Branch: refs/heads/master
Commit: 2b5c162ef5b681a4bb691de160d17df7ed1e98fa
Parents: de15eaa
Author: Rene Cordier <rc...@linagora.com>
Authored: Wed Jan 9 17:32:57 2019 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Fri Jan 11 09:48:34 2019 +0700

----------------------------------------------------------------------
 .../james/webadmin/routes/ForwardRoutes.java    | 47 ++++----------------
 .../james/webadmin/routes/GroupsRoutes.java     | 41 +++--------------
 2 files changed, 14 insertions(+), 74 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/2b5c162e/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/ForwardRoutes.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/ForwardRoutes.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/ForwardRoutes.java
index f75a34b..d69a568 100644
--- a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/ForwardRoutes.java
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/ForwardRoutes.java
@@ -22,16 +22,12 @@ package org.apache.james.webadmin.routes;
 import static org.apache.james.webadmin.Constants.SEPARATOR;
 import static spark.Spark.halt;
 
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 
 import javax.inject.Inject;
-import javax.mail.internet.AddressException;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.PUT;
@@ -40,7 +36,6 @@ import javax.ws.rs.Produces;
 
 import org.apache.james.core.MailAddress;
 import org.apache.james.core.User;
-import org.apache.james.domainlist.api.DomainListException;
 import org.apache.james.rrt.api.MappingAlreadyExistsException;
 import org.apache.james.rrt.api.RecipientRewriteTable;
 import org.apache.james.rrt.api.RecipientRewriteTableException;
@@ -55,11 +50,8 @@ import org.apache.james.webadmin.Routes;
 import org.apache.james.webadmin.dto.ForwardDestinationResponse;
 import org.apache.james.webadmin.utils.ErrorResponder;
 import org.apache.james.webadmin.utils.ErrorResponder.ErrorType;
-import org.apache.james.webadmin.utils.JsonExtractException;
 import org.apache.james.webadmin.utils.JsonTransformer;
 import org.eclipse.jetty.http.HttpStatus;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.github.steveash.guavate.Guavate;
 import com.google.common.annotations.VisibleForTesting;
@@ -84,8 +76,6 @@ public class ForwardRoutes implements Routes {
 
     public static final String ROOT_PATH = "address/forwards";
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(ForwardRoutes.class);
-
     private static final String FORWARD_BASE_ADDRESS = "forwardBaseAddress";
     private static final String FORWARD_ADDRESS_PATH = ROOT_PATH + SEPARATOR + ":" + FORWARD_BASE_ADDRESS;
     private static final String FORWARD_DESTINATION_ADDRESS = "forwardDestinationAddress";
@@ -93,6 +83,7 @@ public class ForwardRoutes implements Routes {
         "targets" + SEPARATOR + ":" + FORWARD_DESTINATION_ADDRESS;
     private static final String MAILADDRESS_ASCII_DISCLAIMER = "Note that email addresses are restricted to ASCII character set. " +
         "Mail addresses not matching this criteria will be rejected.";
+    private static final String ADDRESS_TYPE = "forward";
 
     private final UsersRepository usersRepository;
     private final JsonTransformer jsonTransformer;
@@ -168,10 +159,10 @@ public class ForwardRoutes implements Routes {
         @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
             message = "Internal server error - Something went bad on the server side.")
     })
-    public HaltException addToForwardDestinations(Request request, Response response) throws JsonExtractException, AddressException, RecipientRewriteTableException, UsersRepositoryException, DomainListException {
-        MailAddress forwardBaseAddress = parseMailAddress(request.params(FORWARD_BASE_ADDRESS));
+    public HaltException addToForwardDestinations(Request request, Response response) throws RecipientRewriteTableException, UsersRepositoryException {
+        MailAddress forwardBaseAddress = MailAddressParser.parseMailAddress(request.params(FORWARD_BASE_ADDRESS), ADDRESS_TYPE);
         ensureUserExist(forwardBaseAddress);
-        MailAddress destinationAddress = parseMailAddress(request.params(FORWARD_DESTINATION_ADDRESS));
+        MailAddress destinationAddress = MailAddressParser.parseMailAddress(request.params(FORWARD_DESTINATION_ADDRESS), ADDRESS_TYPE);
         MappingSource source = MappingSource.fromUser(User.fromLocalPartWithDomain(forwardBaseAddress.getLocalPart(), forwardBaseAddress.getDomain()));
         addForward(source, destinationAddress);
         return halt(HttpStatus.NO_CONTENT_204);
@@ -210,9 +201,9 @@ public class ForwardRoutes implements Routes {
         @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
             message = "Internal server error - Something went bad on the server side.")
     })
-    public HaltException removeFromForwardDestination(Request request, Response response) throws JsonExtractException, AddressException, RecipientRewriteTableException {
-        MailAddress baseAddress = parseMailAddress(request.params(FORWARD_BASE_ADDRESS));
-        MailAddress destinationAddressToBeRemoved = parseMailAddress(request.params(FORWARD_DESTINATION_ADDRESS));
+    public HaltException removeFromForwardDestination(Request request, Response response) throws RecipientRewriteTableException {
+        MailAddress baseAddress = MailAddressParser.parseMailAddress(request.params(FORWARD_BASE_ADDRESS), ADDRESS_TYPE);
+        MailAddress destinationAddressToBeRemoved = MailAddressParser.parseMailAddress(request.params(FORWARD_DESTINATION_ADDRESS), ADDRESS_TYPE);
         MappingSource source = MappingSource.fromUser(User.fromLocalPartWithDomain(baseAddress.getLocalPart(), baseAddress.getDomain()));
         recipientRewriteTable.removeForwardMapping(source, destinationAddressToBeRemoved.asString());
         return halt(HttpStatus.NO_CONTENT_204);
@@ -232,7 +223,7 @@ public class ForwardRoutes implements Routes {
             message = "Internal server error - Something went bad on the server side.")
     })
     public ImmutableSet<ForwardDestinationResponse> listForwardDestinations(Request request, Response response) throws RecipientRewriteTableException {
-        MailAddress baseAddress = parseMailAddress(request.params(FORWARD_BASE_ADDRESS));
+        MailAddress baseAddress = MailAddressParser.parseMailAddress(request.params(FORWARD_BASE_ADDRESS), ADDRESS_TYPE);
         Mappings mappings = recipientRewriteTable.getStoredMappings(MappingSource.fromMailAddress(baseAddress))
             .select(Mapping.Type.Forward);
 
@@ -247,28 +238,6 @@ public class ForwardRoutes implements Routes {
                 .collect(Guavate.toImmutableSet());
     }
 
-    private MailAddress parseMailAddress(String address) {
-        try {
-            String decodedAddress = URLDecoder.decode(address, StandardCharsets.UTF_8.displayName());
-            return new MailAddress(decodedAddress);
-        } catch (AddressException e) {
-            throw ErrorResponder.builder()
-                .statusCode(HttpStatus.BAD_REQUEST_400)
-                .type(ErrorType.INVALID_ARGUMENT)
-                .message("The forward is not an email address")
-                .cause(e)
-                .haltError();
-        } catch (UnsupportedEncodingException e) {
-            LOGGER.error("UTF-8 should be a valid encoding");
-            throw ErrorResponder.builder()
-                .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500)
-                .type(ErrorType.SERVER_ERROR)
-                .message("Internal server error - Something went bad on the server side.")
-                .cause(e)
-                .haltError();
-        }
-    }
-
     private void ensureNonEmptyMappings(Mappings mappings) {
         if (mappings == null || mappings.isEmpty()) {
             throw ErrorResponder.builder()

http://git-wip-us.apache.org/repos/asf/james-project/blob/2b5c162e/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/GroupsRoutes.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/GroupsRoutes.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/GroupsRoutes.java
index 492b7be..3ce454e 100644
--- a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/GroupsRoutes.java
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/GroupsRoutes.java
@@ -22,16 +22,12 @@ package org.apache.james.webadmin.routes;
 import static org.apache.james.webadmin.Constants.SEPARATOR;
 import static spark.Spark.halt;
 
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 
 import javax.inject.Inject;
-import javax.mail.internet.AddressException;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.PUT;
@@ -58,8 +54,6 @@ import org.apache.james.webadmin.utils.ErrorResponder;
 import org.apache.james.webadmin.utils.ErrorResponder.ErrorType;
 import org.apache.james.webadmin.utils.JsonTransformer;
 import org.eclipse.jetty.http.HttpStatus;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.github.steveash.guavate.Guavate;
 import com.google.common.annotations.VisibleForTesting;
@@ -83,14 +77,13 @@ public class GroupsRoutes implements Routes {
 
     public static final String ROOT_PATH = "address/groups";
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(GroupsRoutes.class);
-
     private static final String GROUP_ADDRESS = "groupAddress";
     private static final String GROUP_ADDRESS_PATH = ROOT_PATH + SEPARATOR + ":" + GROUP_ADDRESS;
     private static final String USER_ADDRESS = "userAddress";
     private static final String USER_IN_GROUP_ADDRESS_PATH = GROUP_ADDRESS_PATH + SEPARATOR + ":" + USER_ADDRESS;
     private static final String MAILADDRESS_ASCII_DISCLAIMER = "Note that email addresses are restricted to ASCII character set. " +
         "Mail addresses not matching this criteria will be rejected.";
+    private static final String ADDRESS_TYPE = "group";
 
     private final UsersRepository usersRepository;
     private final DomainList domainList;
@@ -163,11 +156,11 @@ public class GroupsRoutes implements Routes {
             message = "Internal server error - Something went bad on the server side.")
     })
     public HaltException addToGroup(Request request, Response response) throws RecipientRewriteTableException, UsersRepositoryException, DomainListException {
-        MailAddress groupAddress = parseMailAddress(request.params(GROUP_ADDRESS));
+        MailAddress groupAddress = MailAddressParser.parseMailAddress(request.params(GROUP_ADDRESS), ADDRESS_TYPE);
         Domain domain = groupAddress.getDomain();
         ensureRegisteredDomain(domain);
         ensureNotShadowingAnotherAddress(groupAddress);
-        MailAddress userAddress = parseMailAddress(request.params(USER_ADDRESS));
+        MailAddress userAddress = MailAddressParser.parseMailAddress(request.params(USER_ADDRESS), ADDRESS_TYPE);
         MappingSource source = MappingSource.fromUser(User.fromLocalPartWithDomain(groupAddress.getLocalPart(), domain));
         addGroupMember(source, userAddress);
         return halt(HttpStatus.NO_CONTENT_204);
@@ -217,8 +210,8 @@ public class GroupsRoutes implements Routes {
             message = "Internal server error - Something went bad on the server side.")
     })
     public HaltException removeFromGroup(Request request, Response response) throws RecipientRewriteTableException {
-        MailAddress groupAddress = parseMailAddress(request.params(GROUP_ADDRESS));
-        MailAddress userAddress = parseMailAddress(request.params(USER_ADDRESS));
+        MailAddress groupAddress = MailAddressParser.parseMailAddress(request.params(GROUP_ADDRESS), ADDRESS_TYPE);
+        MailAddress userAddress = MailAddressParser.parseMailAddress(request.params(USER_ADDRESS), ADDRESS_TYPE);
         MappingSource source = MappingSource
             .fromUser(
                 User.fromLocalPartWithDomain(groupAddress.getLocalPart(), groupAddress.getDomain()));
@@ -240,7 +233,7 @@ public class GroupsRoutes implements Routes {
             message = "Internal server error - Something went bad on the server side.")
     })
     public ImmutableSortedSet<String> listGroupMembers(Request request, Response response) throws RecipientRewriteTableException {
-        MailAddress groupAddress = parseMailAddress(request.params(GROUP_ADDRESS));
+        MailAddress groupAddress = MailAddressParser.parseMailAddress(request.params(GROUP_ADDRESS), ADDRESS_TYPE);
         Mappings mappings = recipientRewriteTable.getStoredMappings(MappingSource.fromMailAddress(groupAddress))
             .select(Mapping.Type.Group);
 
@@ -254,28 +247,6 @@ public class GroupsRoutes implements Routes {
                 .collect(Guavate.toImmutableSortedSet());
     }
 
-    private MailAddress parseMailAddress(String address) {
-        try {
-            String decodedAddress = URLDecoder.decode(address, StandardCharsets.UTF_8.displayName());
-            return new MailAddress(decodedAddress);
-        } catch (AddressException e) {
-            throw ErrorResponder.builder()
-                .statusCode(HttpStatus.BAD_REQUEST_400)
-                .type(ErrorType.INVALID_ARGUMENT)
-                .message("The group is not an email address")
-                .cause(e)
-                .haltError();
-        } catch (UnsupportedEncodingException e) {
-            LOGGER.error("UTF-8 should be a valid encoding");
-            throw ErrorResponder.builder()
-                .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500)
-                .type(ErrorType.SERVER_ERROR)
-                .message("Internal server error - Something went bad on the server side.")
-                .cause(e)
-                .haltError();
-        }
-    }
-
     private void ensureNonEmptyMappings(Mappings mappings) {
         if (mappings == null || mappings.isEmpty()) {
             throw ErrorResponder.builder()


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


[03/10] james-project git commit: JAMES-2636 refactoring some mapping tests

Posted by bt...@apache.org.
JAMES-2636 refactoring some mapping tests


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

Branch: refs/heads/master
Commit: 00dcbd8f9f15f20b725b90b8a2340f3f3bc8ae8d
Parents: 106a284
Author: Rene Cordier <rc...@linagora.com>
Authored: Fri Jan 4 18:03:11 2019 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Fri Jan 11 09:48:33 2019 +0700

----------------------------------------------------------------------
 .../org/apache/james/rrt/lib/MappingTest.java   |  8 +++----
 .../lib/AbstractRecipientRewriteTableTest.java  | 22 ++++++++++----------
 2 files changed, 15 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/00dcbd8f/server/data/data-api/src/test/java/org/apache/james/rrt/lib/MappingTest.java
----------------------------------------------------------------------
diff --git a/server/data/data-api/src/test/java/org/apache/james/rrt/lib/MappingTest.java b/server/data/data-api/src/test/java/org/apache/james/rrt/lib/MappingTest.java
index 8eecd53..5c71bd5 100644
--- a/server/data/data-api/src/test/java/org/apache/james/rrt/lib/MappingTest.java
+++ b/server/data/data-api/src/test/java/org/apache/james/rrt/lib/MappingTest.java
@@ -38,19 +38,19 @@ public class MappingTest {
 
     @Test
     void hasPrefixShouldReturnTrueWhenDomain() {
-        boolean hasPrefix = Mapping.Type.hasPrefix(Type.Domain.asPrefix() + "myRegex");
+        boolean hasPrefix = Mapping.Type.hasPrefix(Type.Domain.asPrefix() + "myDomain");
         assertThat(hasPrefix).isTrue();
     }
 
     @Test
     void hasPrefixShouldReturnTrueWhenError() {
-        boolean hasPrefix = Mapping.Type.hasPrefix(Type.Error.asPrefix() + "myRegex");
+        boolean hasPrefix = Mapping.Type.hasPrefix(Type.Error.asPrefix() + "myError");
         assertThat(hasPrefix).isTrue();
     }
 
     @Test
     void hasPrefixShouldReturnTrueWhenForward() {
-        boolean hasPrefix = Mapping.Type.hasPrefix(Type.Forward.asPrefix() + "myRegex");
+        boolean hasPrefix = Mapping.Type.hasPrefix(Type.Forward.asPrefix() + "myForward");
         assertThat(hasPrefix).isTrue();
     }
 
@@ -62,7 +62,7 @@ public class MappingTest {
 
     @Test
     void hasPrefixShouldReturnFalseWhenAddress() {
-        boolean hasPrefix = Mapping.Type.hasPrefix(Type.Address.asPrefix() + "myRegex");
+        boolean hasPrefix = Mapping.Type.hasPrefix(Type.Address.asPrefix() + "myAddress");
         assertThat(hasPrefix).isFalse();
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/00dcbd8f/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java
----------------------------------------------------------------------
diff --git a/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java b/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java
index b9bfe0a..2974975 100644
--- a/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java
+++ b/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java
@@ -87,12 +87,12 @@ public abstract class AbstractRecipientRewriteTableTest {
         String regex2 = "(.+)@test";
         String invalidRegex = ".*):";
 
-        assertThat(virtualUserTable.getResolvedMappings(USER, domain)).describedAs("No mapping")
+        assertThat(virtualUserTable.getStoredMappings(source)).describedAs("No mapping")
             .isEqualTo(MappingsImpl.empty());
 
         virtualUserTable.addMapping(source, Mapping.regex(regex));
         virtualUserTable.addMapping(source, Mapping.regex(regex2));
-        assertThat(virtualUserTable.getResolvedMappings(USER, domain)).describedAs("Two mappings").hasSize(2);
+        assertThat(virtualUserTable.getStoredMappings(source)).describedAs("Two mappings").hasSize(2);
         assertThat(virtualUserTable.getAllMappings()).describedAs("One mappingline").hasSize(1);
         virtualUserTable.removeMapping(source, Mapping.regex(regex));
 
@@ -104,7 +104,7 @@ public abstract class AbstractRecipientRewriteTableTest {
         virtualUserTable.removeMapping(source, Mapping.regex(regex2));
 
 
-        assertThat(virtualUserTable.getResolvedMappings(USER, domain)).describedAs("No mapping")
+        assertThat(virtualUserTable.getStoredMappings(source)).describedAs("No mapping")
             .isEqualTo(MappingsImpl.empty());
         assertThat(virtualUserTable.getAllMappings()).describedAs("No mapping").isEmpty();
     }
@@ -140,19 +140,19 @@ public abstract class AbstractRecipientRewriteTableTest {
         MappingSource source = MappingSource.fromUser(USER, domain);
         String address2 = "test@james";
 
-        assertThat(virtualUserTable.getResolvedMappings(USER, domain)).describedAs("No mapping")
+        assertThat(virtualUserTable.getStoredMappings(source)).describedAs("No mapping")
             .isEqualTo(MappingsImpl.empty());
 
         virtualUserTable.addMapping(source, Mapping.address(ADDRESS));
         virtualUserTable.addMapping(source, Mapping.address(address2));
 
-        assertThat(virtualUserTable.getResolvedMappings(USER, domain)).describedAs("Two mappings").hasSize(2);
+        assertThat(virtualUserTable.getStoredMappings(source)).describedAs("Two mappings").hasSize(2);
         assertThat(virtualUserTable.getAllMappings()).describedAs("One mappingline").hasSize(1);
 
         virtualUserTable.removeMapping(source, Mapping.address(ADDRESS));
         virtualUserTable.removeMapping(source, Mapping.address(address2));
 
-        assertThat(virtualUserTable.getResolvedMappings(USER, domain)).describedAs("No mapping")
+        assertThat(virtualUserTable.getStoredMappings(source)).describedAs("No mapping")
             .isEqualTo(MappingsImpl.empty());
         assertThat(virtualUserTable.getAllMappings()).describedAs("No mapping").isEmpty();
     }
@@ -279,7 +279,7 @@ public abstract class AbstractRecipientRewriteTableTest {
         virtualUserTable.addMapping(source, Mapping.address(ADDRESS));
         virtualUserTable.addMapping(source, Mapping.regex(ADDRESS));
 
-        assertThat(virtualUserTable.getResolvedMappings(USER, domain)).hasSize(2);
+        assertThat(virtualUserTable.getStoredMappings(source)).hasSize(2);
     }
 
     @Test
@@ -291,7 +291,7 @@ public abstract class AbstractRecipientRewriteTableTest {
         virtualUserTable.addMapping(source, Mapping.forward(ADDRESS));
         virtualUserTable.addMapping(source, Mapping.forward(address2));
 
-        assertThat(virtualUserTable.getResolvedMappings(USER, domain)).hasSize(2);
+        assertThat(virtualUserTable.getStoredMappings(source)).hasSize(2);
     }
 
     @Test
@@ -306,7 +306,7 @@ public abstract class AbstractRecipientRewriteTableTest {
         virtualUserTable.removeMapping(source, Mapping.forward(ADDRESS));
         virtualUserTable.removeMapping(source, Mapping.forward(address2));
 
-        assertThat(virtualUserTable.getResolvedMappings(USER, domain))
+        assertThat(virtualUserTable.getStoredMappings(source))
             .isEqualTo(MappingsImpl.empty());
     }
 
@@ -319,7 +319,7 @@ public abstract class AbstractRecipientRewriteTableTest {
         virtualUserTable.addMapping(source, Mapping.group(ADDRESS));
         virtualUserTable.addMapping(source, Mapping.group(address2));
 
-        assertThat(virtualUserTable.getResolvedMappings(USER, domain)).hasSize(2);
+        assertThat(virtualUserTable.getStoredMappings(source)).hasSize(2);
     }
 
     @Test
@@ -334,7 +334,7 @@ public abstract class AbstractRecipientRewriteTableTest {
         virtualUserTable.removeMapping(source, Mapping.group(ADDRESS));
         virtualUserTable.removeMapping(source, Mapping.group(address2));
 
-        assertThat(virtualUserTable.getResolvedMappings(USER, domain))
+        assertThat(virtualUserTable.getStoredMappings(source))
             .isEqualTo(MappingsImpl.empty());
     }
 


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


[02/10] james-project git commit: JAMES-2636 Refactoring and automating some mapping methods

Posted by bt...@apache.org.
JAMES-2636 Refactoring and automating some mapping methods


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

Branch: refs/heads/master
Commit: 057fbe4575152d2681244ba7d652c08309f97613
Parents: 00dcbd8
Author: Rene Cordier <rc...@linagora.com>
Authored: Mon Jan 7 09:57:45 2019 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Fri Jan 11 09:48:33 2019 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/rrt/lib/Mapping.java  | 38 +++++++-------------
 .../org/apache/james/rrt/lib/MappingTest.java   |  8 ++---
 2 files changed, 17 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/057fbe45/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java
----------------------------------------------------------------------
diff --git a/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java b/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java
index 9e918dc..e8d1198 100644
--- a/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java
+++ b/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java
@@ -21,6 +21,7 @@
 package org.apache.james.rrt.lib;
 
 import java.io.Serializable;
+import java.util.Arrays;
 import java.util.Optional;
 import java.util.function.Supplier;
 import java.util.stream.Stream;
@@ -147,25 +148,11 @@ public interface Mapping {
     }
 
     static Type detectType(String input) {
-        if (input.startsWith(Type.Regex.asPrefix())) {
-            return Type.Regex;
-        }
-        if (input.startsWith(Type.Domain.asPrefix())) {
-            return Type.Domain;
-        }
-        if (input.startsWith(Type.Error.asPrefix())) {
-            return Type.Error;
-        }
-        if (input.startsWith(Type.Forward.asPrefix())) {
-            return Type.Forward;
-        }
-        if (input.startsWith(Type.Group.asPrefix())) {
-            return Type.Group;
-        }
-        if (input.startsWith(Type.Alias.asPrefix())) {
-            return Type.Alias;
-        }
-        return Type.Address;
+        return Arrays.stream(Type.values())
+            .filter(Type::hasPrefix)
+            .filter(type -> input.startsWith(type.asPrefix()))
+            .findAny()
+            .orElse(Type.Address);
     }
 
     enum Type {
@@ -192,13 +179,14 @@ public interface Mapping {
             return input.substring(asPrefix.length());
         }
 
+        public boolean hasPrefix() {
+            return !asPrefix.isEmpty();
+        }
+
         public static boolean hasPrefix(String mapping) {
-            return mapping.startsWith(Regex.asPrefix())
-                || mapping.startsWith(Domain.asPrefix())
-                || mapping.startsWith(Error.asPrefix())
-                || mapping.startsWith(Forward.asPrefix())
-                || mapping.startsWith(Group.asPrefix())
-                || mapping.startsWith(Alias.asPrefix());
+            return Arrays.stream(Type.values())
+                .filter(Type::hasPrefix)
+                .anyMatch(type -> mapping.startsWith(type.asPrefix()));
         }
 
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/057fbe45/server/data/data-api/src/test/java/org/apache/james/rrt/lib/MappingTest.java
----------------------------------------------------------------------
diff --git a/server/data/data-api/src/test/java/org/apache/james/rrt/lib/MappingTest.java b/server/data/data-api/src/test/java/org/apache/james/rrt/lib/MappingTest.java
index 5c71bd5..f500199 100644
--- a/server/data/data-api/src/test/java/org/apache/james/rrt/lib/MappingTest.java
+++ b/server/data/data-api/src/test/java/org/apache/james/rrt/lib/MappingTest.java
@@ -99,7 +99,7 @@ public class MappingTest {
     @Test
     void detectTypeShouldReturnAliasWhenAliasPrefix() {
         assertThat(Mapping.detectType(Type.Alias.asPrefix() + "mapping"))
-                .isEqualTo(Type.Alias);
+            .isEqualTo(Type.Alias);
     }
 
     @Test
@@ -141,7 +141,7 @@ public class MappingTest {
     @Test
     void withoutPrefixShouldRemoveAliasPrefix() {
         assertThat(Type.Alias.withoutPrefix(Type.Alias.asPrefix() + "mapping"))
-                .isEqualTo("mapping");
+            .isEqualTo("mapping");
     }
 
     @Test
@@ -208,7 +208,7 @@ public class MappingTest {
     @Test
     void aliasFactoryMethodShouldThrowOnNull() {
         assertThatThrownBy(() -> Mapping.alias(null))
-                .isInstanceOf(NullPointerException.class);
+            .isInstanceOf(NullPointerException.class);
     }
 
     @Test
@@ -338,7 +338,7 @@ public class MappingTest {
     @Test
     void asMailAddressShouldReturnMappingValueForAlias() throws Exception {
         assertThat(Mapping.alias("value@domain").asMailAddress())
-                .contains(new MailAddress("value@domain"));
+            .contains(new MailAddress("value@domain"));
     }
 
 }


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


[07/10] james-project git commit: JAMES-2636 Refactoring AbstractRecipientRewriteTableTest test class to enhance clarity

Posted by bt...@apache.org.
JAMES-2636 Refactoring AbstractRecipientRewriteTableTest test class to enhance clarity


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

Branch: refs/heads/master
Commit: 516787f9e8daa745cf4407d289e60aa4c79f3aa6
Parents: 057fbe4
Author: Rene Cordier <rc...@linagora.com>
Authored: Mon Jan 7 11:26:48 2019 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Fri Jan 11 09:48:33 2019 +0700

----------------------------------------------------------------------
 .../rrt/file/XMLRecipientRewriteTable.java      |   6 +-
 .../lib/AbstractRecipientRewriteTableTest.java  | 263 +++++++++----------
 2 files changed, 123 insertions(+), 146 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/516787f9/server/data/data-file/src/main/java/org/apache/james/rrt/file/XMLRecipientRewriteTable.java
----------------------------------------------------------------------
diff --git a/server/data/data-file/src/main/java/org/apache/james/rrt/file/XMLRecipientRewriteTable.java b/server/data/data-file/src/main/java/org/apache/james/rrt/file/XMLRecipientRewriteTable.java
index 66b4bb8..700aa5c 100644
--- a/server/data/data-file/src/main/java/org/apache/james/rrt/file/XMLRecipientRewriteTable.java
+++ b/server/data/data-file/src/main/java/org/apache/james/rrt/file/XMLRecipientRewriteTable.java
@@ -70,9 +70,9 @@ public class XMLRecipientRewriteTable extends AbstractRecipientRewriteTable {
     @Override
     public Mappings getStoredMappings(MappingSource source) {
         return Optional.ofNullable(mappings)
-                .map(mappings -> mappings.get(source))
-                .map(MappingsImpl::fromRawString)
-                .orElse(MappingsImpl.empty());
+            .map(mappings -> mappings.get(source))
+            .map(MappingsImpl::fromRawString)
+            .orElse(MappingsImpl.empty());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/516787f9/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java
----------------------------------------------------------------------
diff --git a/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java b/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java
index 2974975..862a15a 100644
--- a/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java
+++ b/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java
@@ -43,6 +43,8 @@ public abstract class AbstractRecipientRewriteTableTest {
 
     private static final String USER = "test";
     private static final String ADDRESS = "test@localhost2";
+    private static final String ADDRESS_2 = "test@james";
+    private static final MappingSource SOURCE = MappingSource.fromUser(USER, Domain.LOCALHOST);
 
     protected abstract AbstractRecipientRewriteTable getRecipientRewriteTable() throws Exception;
 
@@ -79,33 +81,31 @@ public abstract class AbstractRecipientRewriteTableTest {
 
     @Test
     public void testStoreAndRetrieveRegexMapping() throws Exception {
-        Domain domain = Domain.LOCALHOST;
-        MappingSource source = MappingSource.fromUser(USER, domain);
-        // String regex = "(.*):{$1}@localhost";
-        // String regex2 = "(.+):{$1}@test";
         String regex = "(.*)@localhost";
         String regex2 = "(.+)@test";
         String invalidRegex = ".*):";
 
-        assertThat(virtualUserTable.getStoredMappings(source)).describedAs("No mapping")
-            .isEqualTo(MappingsImpl.empty());
+        Mapping mappingRegex = Mapping.regex(regex);
+        Mapping mappingRegex2 = Mapping.regex(regex2);
 
-        virtualUserTable.addMapping(source, Mapping.regex(regex));
-        virtualUserTable.addMapping(source, Mapping.regex(regex2));
-        assertThat(virtualUserTable.getStoredMappings(source)).describedAs("Two mappings").hasSize(2);
+        assertThat(virtualUserTable.getStoredMappings(SOURCE)).describedAs("No mapping").isEmpty();
+
+        virtualUserTable.addMapping(SOURCE, mappingRegex);
+        virtualUserTable.addMapping(SOURCE, mappingRegex2);
+        assertThat(virtualUserTable.getStoredMappings(SOURCE)).describedAs("Two mappings")
+            .containsOnly(mappingRegex, mappingRegex2);
         assertThat(virtualUserTable.getAllMappings()).describedAs("One mappingline").hasSize(1);
-        virtualUserTable.removeMapping(source, Mapping.regex(regex));
+        virtualUserTable.removeMapping(SOURCE, mappingRegex);
 
-        assertThatThrownBy(() -> virtualUserTable.addRegexMapping(source, invalidRegex))
+        assertThatThrownBy(() -> virtualUserTable.addRegexMapping(SOURCE, invalidRegex))
             .describedAs("Invalid Mapping throw exception")
             .isInstanceOf(RecipientRewriteTableException.class);
 
 
-        virtualUserTable.removeMapping(source, Mapping.regex(regex2));
+        virtualUserTable.removeMapping(SOURCE, mappingRegex2);
 
 
-        assertThat(virtualUserTable.getStoredMappings(source)).describedAs("No mapping")
-            .isEqualTo(MappingsImpl.empty());
+        assertThat(virtualUserTable.getStoredMappings(SOURCE)).describedAs("No mapping").isEmpty();
         assertThat(virtualUserTable.getAllMappings()).describedAs("No mapping").isEmpty();
     }
 
@@ -115,95 +115,90 @@ public abstract class AbstractRecipientRewriteTableTest {
         String regex = "(.*)@localhost";
         String regex2 = "(.+)@test";
 
-        MappingSource source1 = MappingSource.fromUser(USER, Domain.LOCALHOST);
+        Mapping mappingAddress = Mapping.address(USER + "@" + Domain.LOCALHOST.asString());
+        Mapping mappingRegex = Mapping.regex(regex);
+        Mapping mappingRegex2 = Mapping.regex(regex2);
         MappingSource source2 = MappingSource.fromUser(user2, Domain.LOCALHOST);
 
-        virtualUserTable.addMapping(source1, Mapping.regex(regex));
-        virtualUserTable.addMapping(source1, Mapping.regex(regex2));
-        virtualUserTable.addMapping(source2, Mapping.address(USER + "@" + Domain.LOCALHOST.asString()));
+        virtualUserTable.addMapping(SOURCE, mappingRegex);
+        virtualUserTable.addMapping(SOURCE, mappingRegex2);
+        virtualUserTable.addMapping(source2, mappingAddress);
 
         assertThat(virtualUserTable.getAllMappings())
             .describedAs("One mappingline")
             .containsOnly(
-                Pair.of(source1, MappingsImpl.builder()
-                    .add(Mapping.regex(regex))
-                    .add(Mapping.regex(regex2))
+                Pair.of(SOURCE, MappingsImpl.builder()
+                    .add(mappingRegex)
+                    .add(mappingRegex2)
                     .build()),
                 Pair.of(source2, MappingsImpl.builder()
-                    .add(Mapping.address(USER + "@" + Domain.LOCALHOST.asString()))
+                    .add(mappingAddress)
                     .build()));
     }
 
     @Test
     public void testStoreAndRetrieveAddressMapping() throws Exception {
-        Domain domain = Domain.LOCALHOST;
-        MappingSource source = MappingSource.fromUser(USER, domain);
-        String address2 = "test@james";
+        Mapping mappingAddress = Mapping.address(ADDRESS);
+        Mapping mappingAddress2 = Mapping.address(ADDRESS_2);
 
-        assertThat(virtualUserTable.getStoredMappings(source)).describedAs("No mapping")
-            .isEqualTo(MappingsImpl.empty());
+        assertThat(virtualUserTable.getStoredMappings(SOURCE)).describedAs("No mapping").isEmpty();
 
-        virtualUserTable.addMapping(source, Mapping.address(ADDRESS));
-        virtualUserTable.addMapping(source, Mapping.address(address2));
+        virtualUserTable.addMapping(SOURCE, mappingAddress);
+        virtualUserTable.addMapping(SOURCE, mappingAddress2);
 
-        assertThat(virtualUserTable.getStoredMappings(source)).describedAs("Two mappings").hasSize(2);
+        assertThat(virtualUserTable.getStoredMappings(SOURCE)).describedAs("Two mappings")
+            .containsOnly(mappingAddress, mappingAddress2);
         assertThat(virtualUserTable.getAllMappings()).describedAs("One mappingline").hasSize(1);
 
-        virtualUserTable.removeMapping(source, Mapping.address(ADDRESS));
-        virtualUserTable.removeMapping(source, Mapping.address(address2));
+        virtualUserTable.removeMapping(SOURCE, mappingAddress);
+        virtualUserTable.removeMapping(SOURCE, mappingAddress2);
 
-        assertThat(virtualUserTable.getStoredMappings(source)).describedAs("No mapping")
-            .isEqualTo(MappingsImpl.empty());
+        assertThat(virtualUserTable.getStoredMappings(SOURCE)).describedAs("No mapping").isEmpty();
         assertThat(virtualUserTable.getAllMappings()).describedAs("No mapping").isEmpty();
     }
 
     @Test
     public void testStoreAndRetrieveErrorMapping() throws Exception {
-        Domain domain = Domain.LOCALHOST;
-        MappingSource source = MappingSource.fromUser(USER, domain);
         String error = "bounce!";
 
-        assertThat(virtualUserTable.getResolvedMappings(USER, domain)).describedAs("No mapping")
-            .isEqualTo(MappingsImpl.empty());
+        assertThat(virtualUserTable.getResolvedMappings(USER, Domain.LOCALHOST)).describedAs("No mapping").isEmpty();
 
-        virtualUserTable.addMapping(source, Mapping.error(error));
+        virtualUserTable.addMapping(SOURCE, Mapping.error(error));
         assertThat(virtualUserTable.getAllMappings()).describedAs("One mappingline").hasSize(1);
 
         assertThatThrownBy(() ->
-            virtualUserTable.getResolvedMappings(USER, domain))
+            virtualUserTable.getResolvedMappings(USER, Domain.LOCALHOST))
             .describedAs("Exception thrown on to many mappings")
             .isInstanceOf(ErrorMappingException.class);
 
-        virtualUserTable.removeMapping(source, Mapping.error(error));
+        virtualUserTable.removeMapping(SOURCE, Mapping.error(error));
 
-        assertThat(virtualUserTable.getResolvedMappings(USER, domain)).describedAs("No mapping")
-            .isEqualTo(MappingsImpl.empty());
+        assertThat(virtualUserTable.getResolvedMappings(USER, Domain.LOCALHOST)).describedAs("No mapping").isEmpty();
         assertThat(virtualUserTable.getAllMappings()).describedAs("No mapping").isEmpty();
     }
 
     @Test
     public void testStoreAndRetrieveWildCardAddressMapping() throws Exception {
         String user2 = "test2";
-        Domain domain = Domain.LOCALHOST;
-        String address2 = "test@james";
-        MappingSource source = MappingSource.fromUser(USER, domain);
 
-        assertThat(virtualUserTable.getResolvedMappings(USER, domain)).describedAs("No mapping")
-            .isEqualTo(MappingsImpl.empty());
+        Mapping mappingAddress = Mapping.address(ADDRESS);
+        Mapping mappingAddress2 = Mapping.address(ADDRESS_2);
+
+        assertThat(virtualUserTable.getResolvedMappings(USER, Domain.LOCALHOST)).describedAs("No mapping").isEmpty();
 
-        virtualUserTable.addMapping(MappingSource.fromDomain(domain), Mapping.address(ADDRESS));
-        virtualUserTable.addMapping(source, Mapping.address(address2));
+        virtualUserTable.addMapping(MappingSource.fromDomain(Domain.LOCALHOST), mappingAddress);
+        virtualUserTable.addMapping(SOURCE, mappingAddress2);
 
-        assertThat(virtualUserTable.getResolvedMappings(USER, domain)).describedAs("One mappings").hasSize(1);
-        assertThat(virtualUserTable.getResolvedMappings(user2, domain)).describedAs("One mappings").hasSize(1);
+        assertThat(virtualUserTable.getResolvedMappings(USER, Domain.LOCALHOST)).describedAs("One mappings")
+            .containsOnly(mappingAddress2);
+        assertThat(virtualUserTable.getResolvedMappings(user2, Domain.LOCALHOST)).describedAs("One mappings")
+            .containsOnly(mappingAddress);
 
-        virtualUserTable.removeMapping(source, Mapping.address(address2));
-        virtualUserTable.removeMapping(MappingSource.fromDomain(domain), Mapping.address(ADDRESS));
+        virtualUserTable.removeMapping(SOURCE, mappingAddress2);
+        virtualUserTable.removeMapping(MappingSource.fromDomain(Domain.LOCALHOST), mappingAddress);
 
-        assertThat(virtualUserTable.getResolvedMappings(USER, domain)).describedAs("No mapping")
-            .isEqualTo(MappingsImpl.empty());
-        assertThat(virtualUserTable.getResolvedMappings(user2, domain)).describedAs("No mapping")
-            .isEqualTo(MappingsImpl.empty());
+        assertThat(virtualUserTable.getResolvedMappings(USER, Domain.LOCALHOST)).describedAs("No mapping").isEmpty();
+        assertThat(virtualUserTable.getResolvedMappings(user2, Domain.LOCALHOST)).describedAs("No mapping").isEmpty();
     }
 
     @Test
@@ -234,7 +229,8 @@ public abstract class AbstractRecipientRewriteTableTest {
 
         // disable recursive mapping
         virtualUserTable.setRecursiveMapping(false);
-        assertThat(virtualUserTable.getResolvedMappings(user1, domain1)).describedAs("Not recursive mapped").containsExactly(Mapping.address(user2 + "@" + domain2.asString()));
+        assertThat(virtualUserTable.getResolvedMappings(user1, domain1)).describedAs("Not recursive mapped")
+            .containsExactly(Mapping.address(user2 + "@" + domain2.asString()));
     }
 
     @Test
@@ -244,143 +240,131 @@ public abstract class AbstractRecipientRewriteTableTest {
         String user = "user";
         String user2 = "user2";
 
+        Mapping mappingAddress = Mapping.address(user2 + "@" + domain);
+        Mapping mappingDomain = Mapping.domain(Domain.of(domain));
+
         assertThat(virtualUserTable.getAllMappings()).describedAs("No mappings").isEmpty();
 
-        virtualUserTable.addMapping(MappingSource.fromDomain(aliasDomain), Mapping.address(user2 + "@" + domain));
-        virtualUserTable.addMapping(MappingSource.fromDomain(aliasDomain), Mapping.domain(Domain.of(domain)));
+        virtualUserTable.addMapping(MappingSource.fromDomain(aliasDomain), mappingAddress);
+        virtualUserTable.addMapping(MappingSource.fromDomain(aliasDomain), mappingDomain);
 
         assertThat(virtualUserTable.getResolvedMappings(user, aliasDomain))
             .describedAs("Domain mapped as first, Address mapped as second")
             .isEqualTo(MappingsImpl.builder()
                 .add(Mapping.address(user + "@" + domain))
-                .add(Mapping.address(user2 + "@" + domain))
+                .add(mappingAddress)
                 .build());
 
-        virtualUserTable.removeMapping(MappingSource.fromDomain(aliasDomain), Mapping.address(user2 + "@" + domain));
-        virtualUserTable.removeMapping(MappingSource.fromDomain(aliasDomain), Mapping.domain(Domain.of(domain)));
+        virtualUserTable.removeMapping(MappingSource.fromDomain(aliasDomain), mappingAddress);
+        virtualUserTable.removeMapping(MappingSource.fromDomain(aliasDomain), mappingDomain);
     }
 
     @Test
     public void addMappingShouldThrowWhenMappingAlreadyExists() throws Exception {
-        Domain domain = Domain.LOCALHOST;
-        MappingSource source = MappingSource.fromUser(USER, domain);
-
         expectedException.expect(RecipientRewriteTableException.class);
 
-        virtualUserTable.addAddressMapping(source, ADDRESS);
-        virtualUserTable.addAddressMapping(source, ADDRESS);
+        virtualUserTable.addAddressMapping(SOURCE, ADDRESS);
+        virtualUserTable.addAddressMapping(SOURCE, ADDRESS);
     }
 
     @Test
     public void addMappingShouldNotThrowWhenMappingAlreadyExistsWithAnOtherType() throws Exception {
-        Domain domain = Domain.LOCALHOST;
-        MappingSource source = MappingSource.fromUser(USER, domain);
+        Mapping mappingAddress = Mapping.address(ADDRESS);
+        Mapping mappingRegex = Mapping.regex(ADDRESS);
 
-        virtualUserTable.addMapping(source, Mapping.address(ADDRESS));
-        virtualUserTable.addMapping(source, Mapping.regex(ADDRESS));
+        virtualUserTable.addMapping(SOURCE, mappingAddress);
+        virtualUserTable.addMapping(SOURCE, mappingRegex);
 
-        assertThat(virtualUserTable.getStoredMappings(source)).hasSize(2);
+        assertThat(virtualUserTable.getStoredMappings(SOURCE)).containsOnly(mappingAddress, mappingRegex);
     }
 
     @Test
     public void addForwardMappingShouldStore() throws Exception {
-        Domain domain = Domain.LOCALHOST;
-        String address2 = "test@james";
-        MappingSource source = MappingSource.fromUser(USER, domain);
+        Mapping mappingForward = Mapping.forward(ADDRESS);
+        Mapping mappingForward2 = Mapping.forward(ADDRESS_2);
 
-        virtualUserTable.addMapping(source, Mapping.forward(ADDRESS));
-        virtualUserTable.addMapping(source, Mapping.forward(address2));
+        virtualUserTable.addMapping(SOURCE, mappingForward);
+        virtualUserTable.addMapping(SOURCE, mappingForward2);
 
-        assertThat(virtualUserTable.getStoredMappings(source)).hasSize(2);
+        assertThat(virtualUserTable.getStoredMappings(SOURCE)).containsOnly(mappingForward, mappingForward2);
     }
 
     @Test
     public void removeForwardMappingShouldDelete() throws Exception {
-        Domain domain = Domain.LOCALHOST;
-        String address2 = "test@james";
-        MappingSource source = MappingSource.fromUser(USER, domain);
+        Mapping mappingForward = Mapping.forward(ADDRESS);
+        Mapping mappingForward2 = Mapping.forward(ADDRESS_2);
+        MappingSource source = MappingSource.fromUser(USER, Domain.LOCALHOST);
 
-        virtualUserTable.addMapping(source, Mapping.forward(ADDRESS));
-        virtualUserTable.addMapping(source, Mapping.forward(address2));
+        virtualUserTable.addMapping(source, mappingForward);
+        virtualUserTable.addMapping(source, mappingForward2);
 
-        virtualUserTable.removeMapping(source, Mapping.forward(ADDRESS));
-        virtualUserTable.removeMapping(source, Mapping.forward(address2));
+        virtualUserTable.removeMapping(source, mappingForward);
+        virtualUserTable.removeMapping(source, mappingForward2);
 
-        assertThat(virtualUserTable.getStoredMappings(source))
-            .isEqualTo(MappingsImpl.empty());
+        assertThat(virtualUserTable.getStoredMappings(source)).isEmpty();
     }
 
     @Test
     public void addGroupMappingShouldStore() throws Exception {
-        Domain domain = Domain.LOCALHOST;
-        String address2 = "test@james";
-        MappingSource source = MappingSource.fromUser(USER, domain);
+        Mapping mappingGroup = Mapping.group(ADDRESS);
+        Mapping mappingGroup2 = Mapping.group(ADDRESS_2);
 
-        virtualUserTable.addMapping(source, Mapping.group(ADDRESS));
-        virtualUserTable.addMapping(source, Mapping.group(address2));
+        virtualUserTable.addMapping(SOURCE, mappingGroup);
+        virtualUserTable.addMapping(SOURCE, mappingGroup2);
 
-        assertThat(virtualUserTable.getStoredMappings(source)).hasSize(2);
+        assertThat(virtualUserTable.getStoredMappings(SOURCE)).containsOnly(mappingGroup, mappingGroup2);
     }
 
     @Test
     public void removeGroupMappingShouldDelete() throws Exception {
-        Domain domain = Domain.LOCALHOST;
-        String address2 = "test@james";
-        MappingSource source = MappingSource.fromUser(USER, domain);
+        Mapping mappingGroup = Mapping.group(ADDRESS);
+        Mapping mappingGroup2 = Mapping.group(ADDRESS_2);
 
-        virtualUserTable.addMapping(source, Mapping.group(ADDRESS));
-        virtualUserTable.addMapping(source, Mapping.group(address2));
+        virtualUserTable.addMapping(SOURCE, mappingGroup);
+        virtualUserTable.addMapping(SOURCE, mappingGroup2);
 
-        virtualUserTable.removeMapping(source, Mapping.group(ADDRESS));
-        virtualUserTable.removeMapping(source, Mapping.group(address2));
+        virtualUserTable.removeMapping(SOURCE, mappingGroup);
+        virtualUserTable.removeMapping(SOURCE, mappingGroup2);
 
-        assertThat(virtualUserTable.getStoredMappings(source))
-            .isEqualTo(MappingsImpl.empty());
+        assertThat(virtualUserTable.getStoredMappings(SOURCE)).isEmpty();
     }
 
     @Test
     public void addAliasMappingShouldStore() throws Exception {
-        Domain domain = Domain.LOCALHOST;
-        String address2 = "test@james";
-        MappingSource source = MappingSource.fromUser(USER, domain);
+        Mapping mappingAlias = Mapping.alias(ADDRESS);
+        Mapping mappingAlias2 = Mapping.alias(ADDRESS_2);
 
-        virtualUserTable.addMapping(source, Mapping.alias(ADDRESS));
-        virtualUserTable.addMapping(source, Mapping.alias(address2));
+        virtualUserTable.addMapping(SOURCE, mappingAlias);
+        virtualUserTable.addMapping(SOURCE, mappingAlias2);
 
-        assertThat(virtualUserTable.getStoredMappings(source)).hasSize(2);
+        assertThat(virtualUserTable.getStoredMappings(SOURCE)).containsOnly(mappingAlias, mappingAlias2);
     }
 
     @Test
     public void removeAliasMappingShouldDelete() throws Exception {
-        Domain domain = Domain.LOCALHOST;
-        String address2 = "test@james";
-        MappingSource source = MappingSource.fromUser(USER, domain);
+        Mapping mappingAlias = Mapping.alias(ADDRESS);
+        Mapping mappingAlias2 = Mapping.alias(ADDRESS_2);
 
-        virtualUserTable.addMapping(source, Mapping.alias(ADDRESS));
-        virtualUserTable.addMapping(source, Mapping.alias(address2));
+        virtualUserTable.addMapping(SOURCE, mappingAlias);
+        virtualUserTable.addMapping(SOURCE, mappingAlias2);
 
-        virtualUserTable.removeMapping(source, Mapping.alias(ADDRESS));
-        virtualUserTable.removeMapping(source, Mapping.alias(address2));
+        virtualUserTable.removeMapping(SOURCE, mappingAlias);
+        virtualUserTable.removeMapping(SOURCE, mappingAlias2);
 
-        assertThat(virtualUserTable.getStoredMappings(source))
-                .isEqualTo(MappingsImpl.empty());
+        assertThat(virtualUserTable.getStoredMappings(SOURCE)).isEmpty();
     }
 
     @Test
     public void getUserDomainMappingShouldBeEmptyByDefault() throws Exception {
-        Domain domain = Domain.LOCALHOST;
-        MappingSource source = MappingSource.fromUser(USER, domain);
-
-        assertThat(virtualUserTable.getStoredMappings(source)).isEmpty();
+        assertThat(virtualUserTable.getStoredMappings(SOURCE)).isEmpty();
     }
 
     @Test
     public void listSourcesShouldReturnWhenHasMapping() throws Exception {
-        MappingSource source = MappingSource.fromUser(USER, Domain.LOCALHOST);
         Mapping mapping = Mapping.group(ADDRESS);
-        virtualUserTable.addMapping(source, mapping);
+        virtualUserTable.addMapping(SOURCE, mapping);
 
-        assertThat(virtualUserTable.listSources(mapping)).contains(source);
+        assertThat(virtualUserTable.listSources(mapping)).contains(SOURCE);
     }
 
     @Test
@@ -397,40 +381,36 @@ public abstract class AbstractRecipientRewriteTableTest {
 
     @Test
     public void listSourcesShouldReturnWhenHasForwardMapping() throws Exception {
-        MappingSource source = MappingSource.fromUser(USER, Domain.LOCALHOST);
         Mapping mapping = Mapping.forward("forward");
 
-        virtualUserTable.addMapping(source, mapping);
+        virtualUserTable.addMapping(SOURCE, mapping);
 
-        assertThat(virtualUserTable.listSources(mapping)).contains(source);
+        assertThat(virtualUserTable.listSources(mapping)).contains(SOURCE);
     }
 
     @Test
     public void listSourcesShouldReturnAliasMappings() throws Exception {
-        MappingSource source = MappingSource.fromUser(USER, Domain.LOCALHOST);
         Mapping mapping = Mapping.alias("alias");
 
-        virtualUserTable.addMapping(source, mapping);
+        virtualUserTable.addMapping(SOURCE, mapping);
 
-        assertThat(virtualUserTable.listSources(mapping)).contains(source);
+        assertThat(virtualUserTable.listSources(mapping)).contains(SOURCE);
     }
 
     @Test
     public void listSourcesShouldReturnWhenHasAddressMapping() throws Exception {
-        MappingSource source = MappingSource.fromUser(USER, Domain.LOCALHOST);
         Mapping mapping = Mapping.address("address");
 
-        virtualUserTable.addMapping(source, mapping);
+        virtualUserTable.addMapping(SOURCE, mapping);
 
-        assertThat(virtualUserTable.listSources(mapping)).contains(source);
+        assertThat(virtualUserTable.listSources(mapping)).contains(SOURCE);
     }
 
     @Test
     public void listSourcesShouldThrowExceptionWhenHasRegexMapping() throws Exception {
-        MappingSource source = MappingSource.fromUser(USER, Domain.LOCALHOST);
         Mapping mapping = Mapping.regex("regex");
 
-        virtualUserTable.addMapping(source, mapping);
+        virtualUserTable.addMapping(SOURCE, mapping);
 
         assertThatThrownBy(() -> virtualUserTable.listSources(mapping))
             .isInstanceOf(IllegalArgumentException.class);
@@ -438,10 +418,9 @@ public abstract class AbstractRecipientRewriteTableTest {
 
     @Test
     public void listSourcesShouldThrowExceptionWhenHasDomainMapping() throws Exception {
-        MappingSource source = MappingSource.fromUser(USER, Domain.LOCALHOST);
         Mapping mapping = Mapping.domain(Domain.of("domain"));
 
-        virtualUserTable.addMapping(source, mapping);
+        virtualUserTable.addMapping(SOURCE, mapping);
 
         assertThatThrownBy(() -> virtualUserTable.listSources(mapping))
             .isInstanceOf(IllegalArgumentException.class);
@@ -449,10 +428,9 @@ public abstract class AbstractRecipientRewriteTableTest {
 
     @Test
     public void listSourcesShouldThrowExceptionWhenHasErrorMapping() throws Exception {
-        MappingSource source = MappingSource.fromUser(USER, Domain.LOCALHOST);
         Mapping mapping = Mapping.error("error");
 
-        virtualUserTable.addMapping(source, mapping);
+        virtualUserTable.addMapping(SOURCE, mapping);
 
         assertThatThrownBy(() -> virtualUserTable.listSources(mapping))
             .isInstanceOf(IllegalArgumentException.class);
@@ -460,11 +438,10 @@ public abstract class AbstractRecipientRewriteTableTest {
 
     @Test
     public void listSourcesShouldReturnEmptyWhenMappingDoesNotExist() throws Exception {
-        MappingSource source = MappingSource.fromUser(USER, Domain.LOCALHOST);
         Mapping domainMapping = Mapping.domain(Domain.of("domain"));
         Mapping groupMapping = Mapping.group("group");
 
-        virtualUserTable.addMapping(source, domainMapping);
+        virtualUserTable.addMapping(SOURCE, domainMapping);
 
         assertThat(virtualUserTable.listSources(groupMapping)).isEmpty();
     }


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


[05/10] james-project git commit: JAMES-2636 Add 'Alias' mapping type and handle rewrites for it

Posted by bt...@apache.org.
JAMES-2636 Add 'Alias' mapping type and handle rewrites for it


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

Branch: refs/heads/master
Commit: 760a4116b53491407d7c13a8a25f22e49c7b5ae3
Parents: 20659ee
Author: Rene Cordier <rc...@linagora.com>
Authored: Fri Jan 4 11:14:43 2019 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Fri Jan 11 09:48:33 2019 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/rrt/lib/Mapping.java  | 14 +++++++-
 .../org/apache/james/rrt/lib/MappingsImpl.java  |  2 ++
 .../org/apache/james/rrt/lib/MappingTest.java   | 35 ++++++++++++++++++
 .../rrt/lib/AbstractRecipientRewriteTable.java  |  1 +
 .../lib/AbstractRecipientRewriteTableTest.java  | 38 ++++++++++++++++++++
 5 files changed, 89 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/760a4116/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java
----------------------------------------------------------------------
diff --git a/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java b/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java
index 53bfa67..9e918dc 100644
--- a/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java
+++ b/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java
@@ -60,6 +60,7 @@ public interface Mapping {
                 return new UserRewritter.ThrowingRewriter();
             case Forward:
             case Group:
+            case Alias:
             case Address:
                 return new UserRewritter.ReplaceRewriter();
         }
@@ -73,6 +74,7 @@ public interface Mapping {
             case Error:
             case Group:
             case Address:
+            case Alias:
                 return IdentityMappingPolicy.Throw;
             case Forward:
                 return IdentityMappingPolicy.ReturnIdentity;
@@ -109,6 +111,7 @@ public interface Mapping {
                 return MailAddressConversionPolicy.ToEmpty;
             case Forward:
             case Group:
+            case Alias:
             case Address:
                 return MailAddressConversionPolicy.ToMailAddress;
             }
@@ -139,6 +142,10 @@ public interface Mapping {
         return of(Type.Group, mapping);
     }
 
+    static Mapping alias(String mapping) {
+        return of(Type.Alias, mapping);
+    }
+
     static Type detectType(String input) {
         if (input.startsWith(Type.Regex.asPrefix())) {
             return Type.Regex;
@@ -155,6 +162,9 @@ public interface Mapping {
         if (input.startsWith(Type.Group.asPrefix())) {
             return Type.Group;
         }
+        if (input.startsWith(Type.Alias.asPrefix())) {
+            return Type.Alias;
+        }
         return Type.Address;
     }
 
@@ -164,6 +174,7 @@ public interface Mapping {
         Error("error:"),
         Forward("forward:"),
         Group("group:"),
+        Alias("alias:"),
         Address("");
 
         private final String asPrefix;
@@ -186,7 +197,8 @@ public interface Mapping {
                 || mapping.startsWith(Domain.asPrefix())
                 || mapping.startsWith(Error.asPrefix())
                 || mapping.startsWith(Forward.asPrefix())
-                || mapping.startsWith(Group.asPrefix());
+                || mapping.startsWith(Group.asPrefix())
+                || mapping.startsWith(Alias.asPrefix());
         }
 
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/760a4116/server/data/data-api/src/main/java/org/apache/james/rrt/lib/MappingsImpl.java
----------------------------------------------------------------------
diff --git a/server/data/data-api/src/main/java/org/apache/james/rrt/lib/MappingsImpl.java b/server/data/data-api/src/main/java/org/apache/james/rrt/lib/MappingsImpl.java
index 7a7e4b0..9065626 100644
--- a/server/data/data-api/src/main/java/org/apache/james/rrt/lib/MappingsImpl.java
+++ b/server/data/data-api/src/main/java/org/apache/james/rrt/lib/MappingsImpl.java
@@ -63,6 +63,8 @@ public class MappingsImpl implements Mappings, Serializable {
                     return 2;
                 case Forward:
                     return 3;
+                case Alias:
+                    return 3;
                 case Regex:
                     return 4;
                 case Error:

http://git-wip-us.apache.org/repos/asf/james-project/blob/760a4116/server/data/data-api/src/test/java/org/apache/james/rrt/lib/MappingTest.java
----------------------------------------------------------------------
diff --git a/server/data/data-api/src/test/java/org/apache/james/rrt/lib/MappingTest.java b/server/data/data-api/src/test/java/org/apache/james/rrt/lib/MappingTest.java
index 6c49e8d..8eecd53 100644
--- a/server/data/data-api/src/test/java/org/apache/james/rrt/lib/MappingTest.java
+++ b/server/data/data-api/src/test/java/org/apache/james/rrt/lib/MappingTest.java
@@ -55,6 +55,12 @@ public class MappingTest {
     }
 
     @Test
+    void hasPrefixShouldReturnTrueWhenAlias() {
+        boolean hasPrefix = Mapping.Type.hasPrefix(Type.Alias.asPrefix() + "myAlias");
+        assertThat(hasPrefix).isTrue();
+    }
+
+    @Test
     void hasPrefixShouldReturnFalseWhenAddress() {
         boolean hasPrefix = Mapping.Type.hasPrefix(Type.Address.asPrefix() + "myRegex");
         assertThat(hasPrefix).isFalse();
@@ -91,6 +97,12 @@ public class MappingTest {
     }
 
     @Test
+    void detectTypeShouldReturnAliasWhenAliasPrefix() {
+        assertThat(Mapping.detectType(Type.Alias.asPrefix() + "mapping"))
+                .isEqualTo(Type.Alias);
+    }
+
+    @Test
     void withoutPrefixShouldRemoveAddressPrefix() {
         assertThat(Type.Address.withoutPrefix(Type.Address.asPrefix() + "mapping"))
             .isEqualTo("mapping");
@@ -127,6 +139,12 @@ public class MappingTest {
     }
 
     @Test
+    void withoutPrefixShouldRemoveAliasPrefix() {
+        assertThat(Type.Alias.withoutPrefix(Type.Alias.asPrefix() + "mapping"))
+                .isEqualTo("mapping");
+    }
+
+    @Test
     void withoutPrefixShouldThrowOnBadPrefix() {
         assertThatThrownBy(() -> Type.Regex.withoutPrefix(Type.Domain.asPrefix() + "mapping"))
             .isInstanceOf(IllegalArgumentException.class);
@@ -188,6 +206,12 @@ public class MappingTest {
     }
 
     @Test
+    void aliasFactoryMethodShouldThrowOnNull() {
+        assertThatThrownBy(() -> Mapping.alias(null))
+                .isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
     void hasDomainShouldReturnTrueWhenMappingContainAtMark() {
         assertThat(Mapping.address("a@b").hasDomain()).isTrue();
     }
@@ -258,6 +282,11 @@ public class MappingTest {
     }
 
     @Test
+    void getTypeShouldReturnAliasWhenAliasPrefix() {
+        assertThat(Mapping.alias("abc").getType()).isEqualTo(Mapping.Type.Alias);
+    }
+
+    @Test
     void getErrorMessageShouldThrowWhenMappingIsNotAnError() {
         assertThatThrownBy(() -> Mapping.domain(Domain.of("toto")).getErrorMessage())
             .isInstanceOf(IllegalStateException.class);
@@ -306,4 +335,10 @@ public class MappingTest {
             .contains(new MailAddress("value@domain"));
     }
 
+    @Test
+    void asMailAddressShouldReturnMappingValueForAlias() throws Exception {
+        assertThat(Mapping.alias("value@domain").asMailAddress())
+                .contains(new MailAddress("value@domain"));
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/760a4116/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java
----------------------------------------------------------------------
diff --git a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java
index 69e24f5..053f053 100644
--- a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java
+++ b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java
@@ -162,6 +162,7 @@ public abstract class AbstractRecipientRewriteTable implements RecipientRewriteT
         switch (type) {
             case Forward:
             case Group:
+            case Alias:
                 return Mapping.of(type, rewrittenUser.asString());
             case Regex:
             case Domain:

http://git-wip-us.apache.org/repos/asf/james-project/blob/760a4116/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java
----------------------------------------------------------------------
diff --git a/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java b/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java
index 9958804..e6fe5b7 100644
--- a/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java
+++ b/server/data/data-library/src/test/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTableTest.java
@@ -339,6 +339,34 @@ public abstract class AbstractRecipientRewriteTableTest {
     }
 
     @Test
+    public void addAliasMappingShouldStore() throws Exception {
+        Domain domain = Domain.LOCALHOST;
+        String address2 = "test@james";
+        MappingSource source = MappingSource.fromUser(USER, domain);
+
+        virtualUserTable.addMapping(source, Mapping.alias(ADDRESS));
+        virtualUserTable.addMapping(source, Mapping.alias(address2));
+
+        assertThat(virtualUserTable.getUserDomainMappings(source)).hasSize(2);
+    }
+
+    @Test
+    public void removeAliasMappingShouldDelete() throws Exception {
+        Domain domain = Domain.LOCALHOST;
+        String address2 = "test@james";
+        MappingSource source = MappingSource.fromUser(USER, domain);
+
+        virtualUserTable.addMapping(source, Mapping.alias(ADDRESS));
+        virtualUserTable.addMapping(source, Mapping.alias(address2));
+
+        virtualUserTable.removeMapping(source, Mapping.alias(ADDRESS));
+        virtualUserTable.removeMapping(source, Mapping.alias(address2));
+
+        assertThat(virtualUserTable.getUserDomainMappings(source))
+                .isEqualTo(MappingsImpl.empty());
+    }
+
+    @Test
     public void listSourcesShouldReturnWhenHasMapping() throws Exception {
         MappingSource source = MappingSource.fromUser(USER, Domain.LOCALHOST);
         Mapping mapping = Mapping.group(ADDRESS);
@@ -370,6 +398,16 @@ public abstract class AbstractRecipientRewriteTableTest {
     }
 
     @Test
+    public void listSourcesShouldReturnAliasMappings() throws Exception {
+        MappingSource source = MappingSource.fromUser(USER, Domain.LOCALHOST);
+        Mapping mapping = Mapping.alias("alias");
+
+        virtualUserTable.addMapping(source, mapping);
+
+        assertThat(virtualUserTable.listSources(mapping)).contains(source);
+    }
+
+    @Test
     public void listSourcesShouldReturnWhenHasAddressMapping() throws Exception {
         MappingSource source = MappingSource.fromUser(USER, Domain.LOCALHOST);
         Mapping mapping = Mapping.address("address");


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


[04/10] james-project git commit: MAILBOX-367 Disable using Nio in RabbitMQ ConnectionFactory

Posted by bt...@apache.org.
MAILBOX-367 Disable using Nio in RabbitMQ ConnectionFactory

- While using Nio, RabbitMQEventBusTest running is not stable.
Some tests sometimes be hang for a long times (ie: 9 minutes).


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

Branch: refs/heads/master
Commit: 20659eecfdf659828efa99fad073a0fb588f8bc4
Parents: 7e2a49a
Author: datph <dp...@linagora.com>
Authored: Thu Jan 10 15:21:24 2019 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Fri Jan 11 09:48:33 2019 +0700

----------------------------------------------------------------------
 .../apache/james/backend/rabbitmq/RabbitMQConnectionFactory.java    | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/20659eec/backends-common/rabbitmq/src/main/java/org/apache/james/backend/rabbitmq/RabbitMQConnectionFactory.java
----------------------------------------------------------------------
diff --git a/backends-common/rabbitmq/src/main/java/org/apache/james/backend/rabbitmq/RabbitMQConnectionFactory.java b/backends-common/rabbitmq/src/main/java/org/apache/james/backend/rabbitmq/RabbitMQConnectionFactory.java
index a6b7631..2f901f4 100644
--- a/backends-common/rabbitmq/src/main/java/org/apache/james/backend/rabbitmq/RabbitMQConnectionFactory.java
+++ b/backends-common/rabbitmq/src/main/java/org/apache/james/backend/rabbitmq/RabbitMQConnectionFactory.java
@@ -48,7 +48,6 @@ public class RabbitMQConnectionFactory {
         try {
             ConnectionFactory connectionFactory = new ConnectionFactory();
             connectionFactory.setUri(rabbitMQConfiguration.getUri());
-            connectionFactory.useNio();
             return connectionFactory;
         } catch (Exception e) {
             throw new RuntimeException(e);


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


[06/10] james-project git commit: JAMES-2636 add and remove alias mapping for RecipientRewriteTable and cucumber tests

Posted by bt...@apache.org.
JAMES-2636 add and remove alias mapping for RecipientRewriteTable and cucumber tests


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

Branch: refs/heads/master
Commit: ca7818e77d12c5e1f924f4fca3f60d115ece458b
Parents: 516787f
Author: Rene Cordier <rc...@linagora.com>
Authored: Mon Jan 7 17:05:36 2019 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Fri Jan 11 09:48:33 2019 +0700

----------------------------------------------------------------------
 .../james/rrt/api/RecipientRewriteTable.java    |  4 ++
 .../rrt/lib/AbstractRecipientRewriteTable.java  | 39 +++++++++++++++-----
 .../user/lib/AbstractJamesUsersRepository.java  | 10 +++++
 .../james/rrt/lib/RewriteTablesStepdefs.java    | 12 ++++++
 .../resources/cucumber/rewrite_tables.feature   | 22 +++++++++++
 5 files changed, 78 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/ca7818e7/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java
----------------------------------------------------------------------
diff --git a/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java b/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java
index 96f62d3..4970f1b 100644
--- a/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java
+++ b/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java
@@ -80,6 +80,10 @@ public interface RecipientRewriteTable {
 
     void removeGroupMapping(MappingSource source, String address) throws RecipientRewriteTableException;
 
+    void addAliasMapping(MappingSource source, String address) throws RecipientRewriteTableException;
+
+    void removeAliasMapping(MappingSource source, String address) throws RecipientRewriteTableException;
+
     /**
      * Return the Mappings for the given source. Return empty object if no
      * matched mapping was found

http://git-wip-us.apache.org/repos/asf/james-project/blob/ca7818e7/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java
----------------------------------------------------------------------
diff --git a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java
index d6acf8f..88e76ea 100644
--- a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java
+++ b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java
@@ -133,7 +133,7 @@ public abstract class AbstractRecipientRewriteTable implements RecipientRewriteT
     }
 
     private Stream<Mapping> convertAndRecurseMapping(Mapping mapping, User originalUser, User rewrittenUser, int remainingLoops) throws ErrorMappingException, RecipientRewriteTableException {
-        LOGGER.debug("Valid virtual user mapping {} to {}", originalUser, rewrittenUser);
+        LOGGER.debug("Valid virtual user mapping {} to {}", originalUser.asString(), rewrittenUser.asString());
 
         Stream<Mapping> nonRecursiveResult = Stream.of(toMapping(rewrittenUser, mapping.getType()));
         if (!recursive) {
@@ -201,7 +201,7 @@ public abstract class AbstractRecipientRewriteTable implements RecipientRewriteT
         checkHasValidAddress(mapping);
         checkDuplicateMapping(source, mapping);
 
-        LOGGER.info("Add address mapping => {} for source: {}", mapping, source.asString());
+        LOGGER.info("Add address mapping => {} for source: {}", mapping.toString(), source.asString());
         addMapping(source, mapping);
     }
 
@@ -215,7 +215,7 @@ public abstract class AbstractRecipientRewriteTable implements RecipientRewriteT
 
     private void checkHasValidAddress(Mapping mapping) throws RecipientRewriteTableException {
         if (!mapping.asMailAddress().isPresent()) {
-            throw new RecipientRewriteTableException("Invalid emailAddress: " + mapping);
+            throw new RecipientRewriteTableException("Invalid emailAddress: " + mapping.toString());
         }
     }
 
@@ -224,7 +224,7 @@ public abstract class AbstractRecipientRewriteTable implements RecipientRewriteT
         Mapping mapping = Mapping.address(address)
             .appendDomainFromThrowingSupplierIfNone(this::defaultDomain);
 
-        LOGGER.info("Remove address mapping => {} for source: {}", mapping, source.asString());
+        LOGGER.info("Remove address mapping => {} for source: {}", mapping.toString(), source.asString());
         removeMapping(source, mapping);
     }
 
@@ -264,7 +264,7 @@ public abstract class AbstractRecipientRewriteTable implements RecipientRewriteT
         checkHasValidAddress(mapping);
         checkDuplicateMapping(source, mapping);
 
-        LOGGER.info("Add forward mapping => {} for source: {}", mapping, source.asString());
+        LOGGER.info("Add forward mapping => {} for source: {}", mapping.toString(), source.asString());
         addMapping(source, mapping);
     }
 
@@ -273,7 +273,7 @@ public abstract class AbstractRecipientRewriteTable implements RecipientRewriteT
         Mapping mapping = Mapping.forward(address)
             .appendDomainFromThrowingSupplierIfNone(this::defaultDomain);
 
-        LOGGER.info("Remove forward mapping => {} for source: {}", mapping, source.asString());
+        LOGGER.info("Remove forward mapping => {} for source: {}", mapping.toString(), source.asString());
         removeMapping(source, mapping);
     }
 
@@ -285,7 +285,7 @@ public abstract class AbstractRecipientRewriteTable implements RecipientRewriteT
         checkHasValidAddress(mapping);
         checkDuplicateMapping(source, mapping);
 
-        LOGGER.info("Add group mapping => {} for source: {}", mapping, source.asString());
+        LOGGER.info("Add group mapping => {} for source: {}", mapping.toString(), source.asString());
         addMapping(source, mapping);
     }
 
@@ -294,7 +294,28 @@ public abstract class AbstractRecipientRewriteTable implements RecipientRewriteT
         Mapping mapping = Mapping.group(address)
             .appendDomainFromThrowingSupplierIfNone(this::defaultDomain);
 
-        LOGGER.info("Remove group mapping => {} for source: {}", mapping, source.asString());
+        LOGGER.info("Remove group mapping => {} for source: {}", mapping.toString(), source.asString());
+        removeMapping(source, mapping);
+    }
+
+    @Override
+    public void addAliasMapping(MappingSource source, String address) throws RecipientRewriteTableException {
+        Mapping mapping = Mapping.alias(address)
+            .appendDomainFromThrowingSupplierIfNone(this::defaultDomain);
+
+        checkHasValidAddress(mapping);
+        checkDuplicateMapping(source, mapping);
+
+        LOGGER.info("Add alias mapping => {} for source: {}", mapping.toString(), source.asString());
+        addMapping(source, mapping);
+    }
+
+    @Override
+    public void removeAliasMapping(MappingSource source, String address) throws RecipientRewriteTableException {
+        Mapping mapping = Mapping.alias(address)
+            .appendDomainFromThrowingSupplierIfNone(this::defaultDomain);
+
+        LOGGER.info("Remove alias mapping => {} for source: {}", mapping.toString(), source.asString());
         removeMapping(source, mapping);
     }
 
@@ -315,7 +336,7 @@ public abstract class AbstractRecipientRewriteTable implements RecipientRewriteT
     private void checkDuplicateMapping(MappingSource source, Mapping mapping) throws RecipientRewriteTableException {
         Mappings mappings = getStoredMappings(source);
         if (mappings.contains(mapping)) {
-            throw new MappingAlreadyExistsException("Mapping " + mapping + " for " + source.asString() + " already exist!");
+            throw new MappingAlreadyExistsException("Mapping " + mapping.toString() + " for " + source.asString() + " already exist!");
         }
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/ca7818e7/server/data/data-library/src/main/java/org/apache/james/user/lib/AbstractJamesUsersRepository.java
----------------------------------------------------------------------
diff --git a/server/data/data-library/src/main/java/org/apache/james/user/lib/AbstractJamesUsersRepository.java b/server/data/data-library/src/main/java/org/apache/james/user/lib/AbstractJamesUsersRepository.java
index 44f731a..daf8ec0 100644
--- a/server/data/data-library/src/main/java/org/apache/james/user/lib/AbstractJamesUsersRepository.java
+++ b/server/data/data-library/src/main/java/org/apache/james/user/lib/AbstractJamesUsersRepository.java
@@ -288,4 +288,14 @@ public abstract class AbstractJamesUsersRepository extends AbstractUsersReposito
     public void removeGroupMapping(MappingSource source, String address) throws RecipientRewriteTableException {
         throw new RecipientRewriteTableException("Read-Only RecipientRewriteTable");
     }
+
+    @Override
+    public void addAliasMapping(MappingSource source, String address) throws RecipientRewriteTableException {
+        throw new RecipientRewriteTableException("Read-Only RecipientRewriteTable");
+    }
+
+    @Override
+    public void removeAliasMapping(MappingSource source, String address) throws RecipientRewriteTableException {
+        throw new RecipientRewriteTableException("Read-Only RecipientRewriteTable");
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/ca7818e7/server/data/data-library/src/test/java/org/apache/james/rrt/lib/RewriteTablesStepdefs.java
----------------------------------------------------------------------
diff --git a/server/data/data-library/src/test/java/org/apache/james/rrt/lib/RewriteTablesStepdefs.java b/server/data/data-library/src/test/java/org/apache/james/rrt/lib/RewriteTablesStepdefs.java
index 17320a3..5cca0f7 100644
--- a/server/data/data-library/src/test/java/org/apache/james/rrt/lib/RewriteTablesStepdefs.java
+++ b/server/data/data-library/src/test/java/org/apache/james/rrt/lib/RewriteTablesStepdefs.java
@@ -84,6 +84,12 @@ public class RewriteTablesStepdefs {
         rewriteTable.addForwardMapping(source, address);
     }
 
+    @Given("store \"([^\"]*)\" alias mapping for user \"([^\"]*)\" at domain \"([^\"]*)\"")
+    public void storeAliasMappingForUserAtDomain(String address, String user, String domain) throws Throwable {
+        MappingSource source = MappingSource.fromUser(user, domain);
+        rewriteTable.addAliasMapping(source, address);
+    }
+
     @Given("store \"([^\"]*)\" group mapping for user \"([^\"]*)\" at domain \"([^\"]*)\"")
     public void storeGroupMappingForUserAtDomain(String address, String user, String domain) throws Throwable {
         MappingSource source = MappingSource.fromUser(user, domain);
@@ -128,6 +134,12 @@ public class RewriteTablesStepdefs {
         rewriteTable.removeForwardMapping(source, address);
     }
 
+    @When("user \"([^\"]*)\" at domain \"([^\"]*)\" removes an alias mapping \"([^\"]*)\"")
+    public void userAtDomainRemovesAliasMapping(String user, String domain, String address) throws Throwable {
+        MappingSource source = MappingSource.fromUser(user, domain);
+        rewriteTable.removeAliasMapping(source, address);
+    }
+
     @When("user \"([^\"]*)\" at domain \"([^\"]*)\" removes a group mapping \"([^\"]*)\"")
     public void userAtDomainRemovesGroupMapping(String user, String domain, String address) throws Throwable {
         MappingSource source = MappingSource.fromUser(user, domain);

http://git-wip-us.apache.org/repos/asf/james-project/blob/ca7818e7/server/data/data-library/src/test/resources/cucumber/rewrite_tables.feature
----------------------------------------------------------------------
diff --git a/server/data/data-library/src/test/resources/cucumber/rewrite_tables.feature b/server/data/data-library/src/test/resources/cucumber/rewrite_tables.feature
index 16be5f1..9fea1b6 100644
--- a/server/data/data-library/src/test/resources/cucumber/rewrite_tables.feature
+++ b/server/data/data-library/src/test/resources/cucumber/rewrite_tables.feature
@@ -242,6 +242,28 @@ Feature: Rewrite Tables tests
     When user "test" at domain "localhost" removes a forward mapping "test@james"
     Then mappings for user "test" at domain "localhost" should contain only "forward:test@localhost2"
 
+# Alias mapping
+
+  Scenario: stored alias mapping should be retrieved when one mapping is matching
+    Given store "test@localhost2" alias mapping for user "test" at domain "localhost"
+    Then mappings for user "test" at domain "localhost" should contain only "alias:test@localhost2"
+
+  Scenario: stored alias mapping should be retrieved when two mappings are matching
+    Given store "test@localhost2" alias mapping for user "test" at domain "localhost"
+    And store "test@james" alias mapping for user "test" at domain "localhost"
+    Then mappings for user "test" at domain "localhost" should contain only "alias:test@localhost2, alias:test@james"
+
+  Scenario: stored alias mapping should not be retrieved by another user
+    Given store "test@localhost2" alias mapping for user "test" at domain "localhost"
+    And store "test@james" alias mapping for user "test" at domain "localhost"
+    Then mappings for user "test2" at domain "localhost" should be empty
+
+  Scenario: removing a stored alias mapping should work
+    Given store "test@localhost2" alias mapping for user "test" at domain "localhost"
+    And store "test@james" alias mapping for user "test" at domain "localhost"
+    When user "test" at domain "localhost" removes an alias mapping "test@james"
+    Then mappings for user "test" at domain "localhost" should contain only "alias:test@localhost2"
+
 # Group mapping
 
   Scenario: stored group mapping should be retrieved when one mapping is matching


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