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 rc...@apache.org on 2020/03/06 03:07:22 UTC

[james-project] 21/21: JAMES-3067 Make RecipientRewriteTable configuration immutable

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

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

commit 9e7eefb22b3efc5c96896de40459865adeb5a3c4
Author: Gautier DI FOLCO <gd...@linagora.com>
AuthorDate: Wed Feb 26 09:12:50 2020 +0100

    JAMES-3067 Make RecipientRewriteTable configuration immutable
---
 .../data/CassandraRecipientRewriteTableModule.java |   8 +-
 .../data/JPARecipientRewriteTableModule.java       |   8 +-
 .../james/modules/data/MemoryDataModule.java       |   8 +-
 .../META-INF/org/apache/james/spring-server.xml    |   2 +-
 .../java/org/apache/james/util/StreamUtils.java    |   2 +-
 .../org/apache/james/util/StreamUtilsTest.java     |   2 +-
 server/data/data-api/pom.xml                       |   9 +
 ...RewriteTable.java => AliasReverseResolver.java} |   2 +-
 .../james/rrt/api/RecipientRewriteTable.java       |   2 +-
 .../api/RecipientRewriteTableConfiguration.java    |  98 +++++++++
 .../RecipientRewriteTableConfigurationTest.java    |  83 ++++++++
 ...ract.java => AliasReverseResolverContract.java} |  30 +--
 .../apache/james/rrt/lib/CanSendFromContract.java  |   6 +-
 .../CassandraRecipientRewriteTableV6Test.java      |   1 -
 .../CassandraRecipientRewriteTableV7Test.java      |   1 -
 .../james/rrt/cassandra/CassandraStepdefs.java     |   5 +-
 .../rrt/file/XMLRecipientRewriteTableTest.java     | 229 +++++++++++++++------
 .../org/apache/james/rrt/file/XMLStepdefs.java     |   4 +-
 .../rrt/jpa/JPARecipientRewriteTableTest.java      |   2 -
 .../java/org/apache/james/rrt/jpa/JPAStepdefs.java |   6 +-
 .../rrt/lib/AbstractRecipientRewriteTable.java     |  55 ++---
 ...ableImpl.java => AliasReverseResolverImpl.java} |  12 +-
 .../org/apache/james/rrt/lib/CanSendFromImpl.java  |  10 +-
 .../rrt/lib/AbstractRecipientRewriteTableTest.java |  44 ++--
 .../james/rrt/lib/RewriteTablesStepdefs.java       |  16 +-
 .../test/resources/cucumber/rewrite_tables.feature |   8 +-
 ...Test.java => AliasReverseResolverImplTest.java} |  16 +-
 .../apache/james/rrt/lib/CanSendFromImplTest.java  |  10 +-
 .../apache/james/rrt/memory/InMemoryStepdefs.java  |   5 +-
 .../memory/MemoryRecipientRewriteTableTest.java    |   7 +-
 .../methods/SetMessagesCreationProcessorTest.java  |   8 +-
 .../methods/SetMessagesUpdateProcessorTest.java    |   8 +-
 .../apache/james/smtpserver/SMTPServerTest.java    |  10 +-
 .../james/webadmin/routes/UserRoutesTest.java      |  10 +-
 34 files changed, 510 insertions(+), 217 deletions(-)

diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java
index 4eaccfc..709a242 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java
@@ -19,15 +19,15 @@
 package org.apache.james.modules.data;
 
 import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.rrt.api.AliasReverseResolver;
 import org.apache.james.rrt.api.CanSendFrom;
 import org.apache.james.rrt.api.RecipientRewriteTable;
-import org.apache.james.rrt.api.ReverseRecipientRewriteTable;
 import org.apache.james.rrt.cassandra.CassandraMappingsSourcesDAO;
 import org.apache.james.rrt.cassandra.CassandraRRTModule;
 import org.apache.james.rrt.cassandra.CassandraRecipientRewriteTable;
 import org.apache.james.rrt.cassandra.CassandraRecipientRewriteTableDAO;
+import org.apache.james.rrt.lib.AliasReverseResolverImpl;
 import org.apache.james.rrt.lib.CanSendFromImpl;
-import org.apache.james.rrt.lib.ReverseRecipientRewriteTableImpl;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.InitializationOperation;
 import org.apache.james.utils.InitilizationOperationBuilder;
@@ -44,8 +44,8 @@ public class CassandraRecipientRewriteTableModule extends AbstractModule {
         bind(CassandraRecipientRewriteTableDAO.class).in(Scopes.SINGLETON);
         bind(CassandraMappingsSourcesDAO.class).in(Scopes.SINGLETON);
         bind(RecipientRewriteTable.class).to(CassandraRecipientRewriteTable.class);
-        bind(ReverseRecipientRewriteTableImpl.class).in(Scopes.SINGLETON);
-        bind(ReverseRecipientRewriteTable.class).to(ReverseRecipientRewriteTableImpl.class);
+        bind(AliasReverseResolverImpl.class).in(Scopes.SINGLETON);
+        bind(AliasReverseResolver.class).to(AliasReverseResolverImpl.class);
         bind(CanSendFromImpl.class).in(Scopes.SINGLETON);
         bind(CanSendFrom.class).to(CanSendFromImpl.class);
         Multibinder<CassandraModule> cassandraDataDefinitions = Multibinder.newSetBinder(binder(), CassandraModule.class);
diff --git a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java
index a608538..f00af56 100644
--- a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java
+++ b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java
@@ -18,12 +18,12 @@
  ****************************************************************/
 package org.apache.james.modules.data;
 
+import org.apache.james.rrt.api.AliasReverseResolver;
 import org.apache.james.rrt.api.CanSendFrom;
 import org.apache.james.rrt.api.RecipientRewriteTable;
-import org.apache.james.rrt.api.ReverseRecipientRewriteTable;
 import org.apache.james.rrt.jpa.JPARecipientRewriteTable;
+import org.apache.james.rrt.lib.AliasReverseResolverImpl;
 import org.apache.james.rrt.lib.CanSendFromImpl;
-import org.apache.james.rrt.lib.ReverseRecipientRewriteTableImpl;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.InitializationOperation;
 import org.apache.james.utils.InitilizationOperationBuilder;
@@ -37,8 +37,8 @@ public class JPARecipientRewriteTableModule extends AbstractModule {
     public void configure() {
         bind(JPARecipientRewriteTable.class).in(Scopes.SINGLETON);
         bind(RecipientRewriteTable.class).to(JPARecipientRewriteTable.class);
-        bind(ReverseRecipientRewriteTableImpl.class).in(Scopes.SINGLETON);
-        bind(ReverseRecipientRewriteTable.class).to(ReverseRecipientRewriteTableImpl.class);
+        bind(AliasReverseResolverImpl.class).in(Scopes.SINGLETON);
+        bind(AliasReverseResolver.class).to(AliasReverseResolverImpl.class);
         bind(CanSendFromImpl.class).in(Scopes.SINGLETON);
         bind(CanSendFrom.class).to(CanSendFromImpl.class);
     }
diff --git a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
index d33c1ea..a99a408 100644
--- a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
+++ b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
@@ -32,11 +32,11 @@ import org.apache.james.mailrepository.memory.MailRepositoryStoreConfiguration;
 import org.apache.james.mailrepository.memory.MemoryMailRepository;
 import org.apache.james.mailrepository.memory.MemoryMailRepositoryUrlStore;
 import org.apache.james.modules.server.MailStoreRepositoryModule;
+import org.apache.james.rrt.api.AliasReverseResolver;
 import org.apache.james.rrt.api.CanSendFrom;
 import org.apache.james.rrt.api.RecipientRewriteTable;
-import org.apache.james.rrt.api.ReverseRecipientRewriteTable;
+import org.apache.james.rrt.lib.AliasReverseResolverImpl;
 import org.apache.james.rrt.lib.CanSendFromImpl;
-import org.apache.james.rrt.lib.ReverseRecipientRewriteTableImpl;
 import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.user.api.UsersRepository;
@@ -70,8 +70,8 @@ public class MemoryDataModule extends AbstractModule {
         bind(MemoryRecipientRewriteTable.class).in(Scopes.SINGLETON);
         bind(RecipientRewriteTable.class).to(MemoryRecipientRewriteTable.class);
 
-        bind(ReverseRecipientRewriteTableImpl.class).in(Scopes.SINGLETON);
-        bind(ReverseRecipientRewriteTable.class).to(ReverseRecipientRewriteTableImpl.class);
+        bind(AliasReverseResolverImpl.class).in(Scopes.SINGLETON);
+        bind(AliasReverseResolver.class).to(AliasReverseResolverImpl.class);
 
         bind(CanSendFromImpl.class).in(Scopes.SINGLETON);
         bind(CanSendFrom.class).to(CanSendFromImpl.class);
diff --git a/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml b/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml
index 8a37ab5..b4a0753 100644
--- a/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml
+++ b/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml
@@ -326,6 +326,6 @@
 
     <bean id="jspfLogger" class="org.apache.james.smtpserver.fastfail.SPFHandler.SPFLogger"/>
 
-    <bean id="reverserecipientrewritetable" class="org.apache.james.rrt.lib.ReverseRecipientRewriteTableImpl" />
+    <bean id="aliasreverseresolver" class="org.apache.james.rrt.lib.AliasReverseResolverImpl" />
     <bean id="cansendfrom" class="org.apache.james.rrt.lib.CanSendFromImpl" />
 </beans>
diff --git a/server/container/util/src/main/java/org/apache/james/util/StreamUtils.java b/server/container/util/src/main/java/org/apache/james/util/StreamUtils.java
index aea59a1..73452ad 100644
--- a/server/container/util/src/main/java/org/apache/james/util/StreamUtils.java
+++ b/server/container/util/src/main/java/org/apache/james/util/StreamUtils.java
@@ -69,7 +69,7 @@ public class StreamUtils {
     }
 
     public static <T> Stream<T> iterate(T seed, Long limit, Function<T, Stream<T>> generator) {
-        Preconditions.checkArgument(limit >= 0, "StreamUtils.iterate have a given limit ok '{}', while it should not be negative", limit);
+        Preconditions.checkArgument(limit >= 0, "StreamUtils.iterate have a given limit '{}', while it should not be negative", limit);
         return StreamUtils.unfold(Arrays.asList(seed), conservativeGenerator(generator))
             .limit(limit + 1)
             .flatMap(List::stream);
diff --git a/server/container/util/src/test/java/org/apache/james/util/StreamUtilsTest.java b/server/container/util/src/test/java/org/apache/james/util/StreamUtilsTest.java
index 67f8527..f29ae43 100644
--- a/server/container/util/src/test/java/org/apache/james/util/StreamUtilsTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/StreamUtilsTest.java
@@ -117,7 +117,7 @@ class StreamUtilsTest {
     }
 
     @Test
-    void unfoldShouldGenerateAnFiniteStream() {
+    void unfoldShouldGenerateAFiniteStream() {
         Stream<Integer> unfolded = StreamUtils.unfold(1, i -> {
             if (i < 10) {
                 return Optional.of(i + 1);
diff --git a/server/data/data-api/pom.xml b/server/data/data-api/pom.xml
index 3818153..94f8b62 100644
--- a/server/data/data-api/pom.xml
+++ b/server/data/data-api/pom.xml
@@ -47,6 +47,10 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-configuration2</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
         </dependency>
@@ -54,5 +58,10 @@
             <groupId>com.sun.mail</groupId>
             <artifactId>javax.mail</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/server/data/data-api/src/main/java/org/apache/james/rrt/api/ReverseRecipientRewriteTable.java b/server/data/data-api/src/main/java/org/apache/james/rrt/api/AliasReverseResolver.java
similarity index 96%
rename from server/data/data-api/src/main/java/org/apache/james/rrt/api/ReverseRecipientRewriteTable.java
rename to server/data/data-api/src/main/java/org/apache/james/rrt/api/AliasReverseResolver.java
index 3f17aff..05117c5 100644
--- a/server/data/data-api/src/main/java/org/apache/james/rrt/api/ReverseRecipientRewriteTable.java
+++ b/server/data/data-api/src/main/java/org/apache/james/rrt/api/AliasReverseResolver.java
@@ -24,6 +24,6 @@ import java.util.stream.Stream;
 import org.apache.james.core.MailAddress;
 import org.apache.james.core.Username;
 
-public interface ReverseRecipientRewriteTable {
+public interface AliasReverseResolver {
     Stream<MailAddress> listAddresses(Username user) throws RecipientRewriteTable.ErrorMappingException, RecipientRewriteTableException;
 }
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 ece8f55..d11d338 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
@@ -122,7 +122,7 @@ public interface RecipientRewriteTable {
      */
     Map<MappingSource, Mappings> getAllMappings() throws RecipientRewriteTableException;
 
-    int getMappingLimit();
+    RecipientRewriteTableConfiguration getConfiguration();
 
     default Stream<MappingSource> listSources(Mapping mapping) throws RecipientRewriteTableException {
         Preconditions.checkArgument(listSourcesSupportedType.contains(mapping.getType()),
diff --git a/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTableConfiguration.java b/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTableConfiguration.java
new file mode 100644
index 0000000..e349ccc
--- /dev/null
+++ b/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTableConfiguration.java
@@ -0,0 +1,98 @@
+/****************************************************************
+ * 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.rrt.api;
+
+import java.util.Objects;
+
+import org.apache.commons.configuration2.HierarchicalConfiguration;
+import org.apache.commons.configuration2.ex.ConfigurationException;
+import org.apache.commons.configuration2.tree.ImmutableNode;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+
+public class RecipientRewriteTableConfiguration {
+
+    public static final boolean RECURSIVE_MAPPING_ENABLE = true;
+    public static final int DEFAULT_ENABLED_MAPPING_LIMIT = 10;
+    public static final int DISABLED_MAPPING_LIMIT = 0;
+
+    // The maximum mappings which will process before throwing exception
+    private final int mappingLimit;
+
+    private final boolean recursive;
+
+    @VisibleForTesting
+    public RecipientRewriteTableConfiguration(boolean recursive, int mappingLimit) {
+        Preconditions.checkArgument(mappingLimit == 0 || recursive, "mappingLimit can not be different than 0 when recursive mode is disabled");
+        this.recursive = recursive;
+        this.mappingLimit = mappingLimit;
+    }
+
+    public static RecipientRewriteTableConfiguration fromConfiguration(HierarchicalConfiguration<ImmutableNode> config) throws ConfigurationException {
+        boolean recursive = config.getBoolean("recursiveMapping", RECURSIVE_MAPPING_ENABLE);
+        int mappingLimit;
+        if (recursive) {
+            mappingLimit = config.getInt("mappingLimit", DEFAULT_ENABLED_MAPPING_LIMIT);
+            checkMappingLimit(mappingLimit);
+        } else {
+            mappingLimit = DISABLED_MAPPING_LIMIT;
+        }
+        return new RecipientRewriteTableConfiguration(recursive, mappingLimit);
+    }
+
+    private static void checkMappingLimit(int mappingLimit) throws ConfigurationException {
+        if (mappingLimit < 1) {
+            throw new ConfigurationException("The minimum mappingLimit is 1");
+        }
+    }
+
+    public int getMappingLimit() {
+        return mappingLimit;
+    }
+
+    public boolean isRecursive() {
+        return recursive;
+    }
+
+    @Override
+    public final boolean equals(Object other) {
+        if (other instanceof RecipientRewriteTableConfiguration) {
+            RecipientRewriteTableConfiguration that = (RecipientRewriteTableConfiguration) other;
+            return Objects.equals(mappingLimit, that.mappingLimit) && Objects.equals(recursive, that.recursive);
+        }
+
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(mappingLimit, recursive);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+            .add("mappingLimit", mappingLimit)
+            .add("recursive", recursive)
+            .toString();
+    }
+}
diff --git a/server/data/data-api/src/test/java/org/apache/james/rrt/api/RecipientRewriteTableConfigurationTest.java b/server/data/data-api/src/test/java/org/apache/james/rrt/api/RecipientRewriteTableConfigurationTest.java
new file mode 100644
index 0000000..f92e79b
--- /dev/null
+++ b/server/data/data-api/src/test/java/org/apache/james/rrt/api/RecipientRewriteTableConfigurationTest.java
@@ -0,0 +1,83 @@
+/****************************************************************
+ * 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.rrt.api;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+
+import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
+import org.apache.commons.configuration2.ex.ConfigurationException;
+import org.junit.jupiter.api.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+class RecipientRewriteTableConfigurationTest {
+    @Test
+    void shouldRespectBeanContract() {
+        EqualsVerifier.forClass(RecipientRewriteTableConfiguration.class).verify();
+    }
+
+    @Test
+    void emptyConfigurationShouldHaveDefaults() throws ConfigurationException {
+        BaseHierarchicalConfiguration configuration = new BaseHierarchicalConfiguration();
+        RecipientRewriteTableConfiguration recipientRewriteTableConfiguration = RecipientRewriteTableConfiguration.fromConfiguration(configuration);
+
+        assertThat(recipientRewriteTableConfiguration.getMappingLimit())
+            .isEqualTo(10);
+        assertThat(recipientRewriteTableConfiguration.isRecursive())
+            .isTrue();
+    }
+
+    @Test
+    void negativeLimitShouldThrows() {
+        BaseHierarchicalConfiguration configuration = new BaseHierarchicalConfiguration();
+        configuration.addProperty("recursiveMapping", "true");
+        configuration.addProperty("mappingLimit", -1);
+
+        assertThatCode(() -> RecipientRewriteTableConfiguration.fromConfiguration(configuration))
+            .isInstanceOf(ConfigurationException.class);
+    }
+
+    @Test
+    void goodConfigurationShouldPopulateTheConfiguration() throws ConfigurationException {
+        BaseHierarchicalConfiguration configuration = new BaseHierarchicalConfiguration();
+        configuration.addProperty("recursiveMapping", "true");
+        configuration.addProperty("mappingLimit", 42);
+        RecipientRewriteTableConfiguration recipientRewriteTableConfiguration = RecipientRewriteTableConfiguration.fromConfiguration(configuration);
+
+        assertThat(recipientRewriteTableConfiguration.getMappingLimit())
+            .isEqualTo(42);
+        assertThat(recipientRewriteTableConfiguration.isRecursive())
+            .isTrue();
+    }
+
+    @Test
+    void goodConfigurationWithoutMappingShouldHaveANullMappingLevel() throws ConfigurationException {
+        BaseHierarchicalConfiguration configuration = new BaseHierarchicalConfiguration();
+        configuration.addProperty("recursiveMapping", "false");
+        configuration.addProperty("mappingLimit", 42);
+        RecipientRewriteTableConfiguration recipientRewriteTableConfiguration = RecipientRewriteTableConfiguration.fromConfiguration(configuration);
+
+        assertThat(recipientRewriteTableConfiguration.getMappingLimit())
+            .isEqualTo(0);
+        assertThat(recipientRewriteTableConfiguration.isRecursive())
+            .isFalse();
+    }
+}
\ No newline at end of file
diff --git a/server/data/data-api/src/test/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableContract.java b/server/data/data-api/src/test/java/org/apache/james/rrt/lib/AliasReverseResolverContract.java
similarity index 84%
rename from server/data/data-api/src/test/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableContract.java
rename to server/data/data-api/src/test/java/org/apache/james/rrt/lib/AliasReverseResolverContract.java
index edf4372..d0d7f66 100644
--- a/server/data/data-api/src/test/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableContract.java
+++ b/server/data/data-api/src/test/java/org/apache/james/rrt/lib/AliasReverseResolverContract.java
@@ -26,12 +26,12 @@ import java.util.stream.IntStream;
 
 import org.apache.james.core.Domain;
 import org.apache.james.core.Username;
-import org.apache.james.rrt.api.ReverseRecipientRewriteTable;
+import org.apache.james.rrt.api.AliasReverseResolver;
 import org.junit.jupiter.api.Test;
 
 import com.github.fge.lambdas.Throwing;
 
-public interface ReverseRecipientRewriteTableContract {
+public interface AliasReverseResolverContract {
 
     Domain DOMAIN = Domain.of("example.com");
     Domain OTHER_DOMAIN = Domain.of("other.org");
@@ -39,7 +39,7 @@ public interface ReverseRecipientRewriteTableContract {
     Username USER_ALIAS = Username.of("alias@example.com");
     Username OTHER_USER = Username.of("other@example.com");
 
-    ReverseRecipientRewriteTable reverseRecipientRewriteTable();
+    AliasReverseResolver aliasReverseResolver();
 
     void addAliasMapping(Username alias, Username user) throws Exception;
 
@@ -70,14 +70,14 @@ public interface ReverseRecipientRewriteTableContract {
     }
     @Test
     default void listAddressesShouldContainOnlyUserAddressWhenUserHasNoAlias() throws Exception {
-        assertThat(reverseRecipientRewriteTable().listAddresses(USER))
+        assertThat(aliasReverseResolver().listAddresses(USER))
             .containsExactly(USER.asMailAddress());
     }
 
     @Test
     default void listAddressesShouldContainOnlyUserAddressWhenUserHasNoAliasAndAnotherUserHasOne() throws Exception {
         redirectUser(USER_ALIAS).to(OTHER_USER);
-        assertThat(reverseRecipientRewriteTable().listAddresses(USER))
+        assertThat(aliasReverseResolver().listAddresses(USER))
             .containsExactly(USER.asMailAddress());
     }
 
@@ -85,17 +85,17 @@ public interface ReverseRecipientRewriteTableContract {
     default void listAddressesShouldContainUserAddressAndAnAliasOfTheUser() throws Exception {
         redirectUser(USER_ALIAS).to(USER);
 
-        assertThat(reverseRecipientRewriteTable().listAddresses(USER))
+        assertThat(aliasReverseResolver().listAddresses(USER))
             .containsExactlyInAnyOrder(USER.asMailAddress(), USER_ALIAS.asMailAddress());
     }
 
     @Test
-    default void listAddressesFromShouldBeTrueWhenSenderIsAnAliasOfAnAliasOfTheUser() throws Exception {
+    default void listAddressesShouldBeTrueWhenSenderIsAnAliasOfAnAliasOfTheUser() throws Exception {
         Username userAliasBis = Username.of("aliasbis@" + DOMAIN.asString());
         redirectUser(userAliasBis).to(USER_ALIAS);
         redirectUser(USER_ALIAS).to(USER);
 
-        assertThat(reverseRecipientRewriteTable().listAddresses(USER))
+        assertThat(aliasReverseResolver().listAddresses(USER))
             .containsExactlyInAnyOrder(USER.asMailAddress(), USER_ALIAS.asMailAddress(), userAliasBis.asMailAddress());
     }
 
@@ -105,7 +105,7 @@ public interface ReverseRecipientRewriteTableContract {
 
         redirectDomain(OTHER_DOMAIN).to(DOMAIN);
 
-        assertThat(reverseRecipientRewriteTable().listAddresses(USER))
+        assertThat(aliasReverseResolver().listAddresses(USER))
             .containsExactlyInAnyOrder(USER.asMailAddress(), fromUser.asMailAddress());
     }
 
@@ -118,7 +118,7 @@ public interface ReverseRecipientRewriteTableContract {
 
         Username userAliasMainDomain = USER_ALIAS.withOtherDomain(Optional.of(DOMAIN));
         Username userOtherDomain = USER.withOtherDomain(Optional.of(OTHER_DOMAIN));
-        assertThat(reverseRecipientRewriteTable().listAddresses(USER))
+        assertThat(aliasReverseResolver().listAddresses(USER))
             .containsExactlyInAnyOrder(USER.asMailAddress(), userAliasOtherDomain.asMailAddress(), userAliasMainDomain.asMailAddress(), userOtherDomain.asMailAddress());
     }
 
@@ -140,28 +140,28 @@ public interface ReverseRecipientRewriteTableContract {
         Username userAliasExcluded = Username.of("alias" + (recursionLevel - 1) + "@" + DOMAIN.asString());
         redirectUser(USER_ALIAS).to(USER);
 
-        assertThat(reverseRecipientRewriteTable().listAddresses(USER))
+        assertThat(aliasReverseResolver().listAddresses(USER))
             .doesNotContain(userAliasExcluded.asMailAddress());
     }
 
     @Test
-    default void listAddressesShouldContainASendersAliasOfAnAliasInAnotherDomainOfTheUser() throws Exception {
+    default void listAddressesShouldContainASenderAliasOfAnAliasInAnotherDomainOfTheUser() throws Exception {
         Username userAlias = Username.of("aliasbis@" + OTHER_DOMAIN.asString());
         Username userAliasBis = Username.of("aliaster@" + OTHER_DOMAIN.asString());
         redirectUser(userAliasBis).to(userAlias);
         redirectUser(userAlias).to(USER);
 
-        assertThat(reverseRecipientRewriteTable().listAddresses(USER))
+        assertThat(aliasReverseResolver().listAddresses(USER))
             .contains(userAliasBis.asMailAddress());
     }
 
     @Test
-    default void listAddressesShouldContainAnUserAliasFollowingADomainAliasResolution() throws Exception {
+    default void listAddressesShouldContainAUserAliasFollowingADomainAliasResolution() throws Exception {
         Username userAliasBis = Username.of("aliasbis@" + OTHER_DOMAIN.asString());
         redirectUser(userAliasBis).to(USER_ALIAS);
         redirectUser(USER_ALIAS).to(USER);
 
-        assertThat(reverseRecipientRewriteTable().listAddresses(USER))
+        assertThat(aliasReverseResolver().listAddresses(USER))
             .contains(userAliasBis.asMailAddress());
     }
 }
diff --git a/server/data/data-api/src/test/java/org/apache/james/rrt/lib/CanSendFromContract.java b/server/data/data-api/src/test/java/org/apache/james/rrt/lib/CanSendFromContract.java
index 0a0201d..5a182ec 100644
--- a/server/data/data-api/src/test/java/org/apache/james/rrt/lib/CanSendFromContract.java
+++ b/server/data/data-api/src/test/java/org/apache/james/rrt/lib/CanSendFromContract.java
@@ -206,7 +206,7 @@ public interface CanSendFromContract {
     }
 
     @Test
-    default void allValidFromAddressesShouldContainASendersAliasOfAnAliasOfTheUser() throws Exception {
+    default void allValidFromAddressesShouldContainASenderAliasOfAnAliasOfTheUser() throws Exception {
         Username userAliasBis = Username.of("aliasbis@" + DOMAIN.asString());
         redirectUser(userAliasBis).to(USER_ALIAS);
         redirectUser(USER_ALIAS).to(USER);
@@ -237,7 +237,7 @@ public interface CanSendFromContract {
     }
 
     @Test
-    default void allValidFromAddressesShouldContainASendersAliasOfAnAliasInAnotherDomainOfTheUser() throws Exception {
+    default void allValidFromAddressesShouldContainASenderAliasOfAnAliasInAnotherDomainOfTheUser() throws Exception {
         Username userAlias = Username.of("aliasbis@" + OTHER_DOMAIN.asString());
         Username userAliasBis = Username.of("aliaster@" + OTHER_DOMAIN.asString());
         redirectUser(userAliasBis).to(userAlias);
@@ -248,7 +248,7 @@ public interface CanSendFromContract {
     }
 
     @Test
-    default void allValidFromAddressesShouldContainAnUserAliasFollowingADomainAliasResolution() throws Exception {
+    default void allValidFromAddressesShouldContainAUserAliasFollowingADomainAliasResolution() throws Exception {
         Username userAliasBis = Username.of("aliasbis@" + OTHER_DOMAIN.asString());
         redirectUser(userAliasBis).to(USER_ALIAS);
         redirectUser(USER_ALIAS).to(USER);
diff --git a/server/data/data-cassandra/src/test/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTableV6Test.java b/server/data/data-cassandra/src/test/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTableV6Test.java
index 9412389..34e51ad 100644
--- a/server/data/data-cassandra/src/test/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTableV6Test.java
+++ b/server/data/data-cassandra/src/test/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTableV6Test.java
@@ -69,7 +69,6 @@ public class CassandraRecipientRewriteTableV6Test extends AbstractRecipientRewri
             new CassandraRecipientRewriteTableDAO(cassandra.getConf(), CassandraUtils.WITH_DEFAULT_CONFIGURATION),
             new CassandraMappingsSourcesDAO(cassandra.getConf()),
             cassandraSchemaVersionDAO);
-        rrt.configure(new BaseHierarchicalConfiguration());
 
         cassandraSchemaVersionDAO.updateVersion(SCHEMA_VERSION_V6);
 
diff --git a/server/data/data-cassandra/src/test/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTableV7Test.java b/server/data/data-cassandra/src/test/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTableV7Test.java
index 0523ed6..2c6a205 100644
--- a/server/data/data-cassandra/src/test/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTableV7Test.java
+++ b/server/data/data-cassandra/src/test/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTableV7Test.java
@@ -69,7 +69,6 @@ public class CassandraRecipientRewriteTableV7Test extends AbstractRecipientRewri
             new CassandraRecipientRewriteTableDAO(cassandra.getConf(), CassandraUtils.WITH_DEFAULT_CONFIGURATION),
             new CassandraMappingsSourcesDAO(cassandra.getConf()),
             cassandraSchemaVersionDAO);
-        rrt.configure(new BaseHierarchicalConfiguration());
 
         cassandraSchemaVersionDAO.updateVersion(SCHEMA_VERSION_V7);
 
diff --git a/server/data/data-cassandra/src/test/java/org/apache/james/rrt/cassandra/CassandraStepdefs.java b/server/data/data-cassandra/src/test/java/org/apache/james/rrt/cassandra/CassandraStepdefs.java
index a32812f..eb16b46 100644
--- a/server/data/data-cassandra/src/test/java/org/apache/james/rrt/cassandra/CassandraStepdefs.java
+++ b/server/data/data-cassandra/src/test/java/org/apache/james/rrt/cassandra/CassandraStepdefs.java
@@ -18,7 +18,6 @@
  ****************************************************************/
 package org.apache.james.rrt.cassandra;
 
-import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.DockerCassandraRule;
 import org.apache.james.backends.cassandra.components.CassandraModule;
@@ -30,6 +29,7 @@ import org.apache.james.rrt.lib.RecipientRewriteTableFixture;
 import org.apache.james.rrt.lib.RewriteTablesStepdefs;
 import org.junit.Rule;
 
+import com.github.fge.lambdas.Throwing;
 import cucumber.api.java.After;
 import cucumber.api.java.Before;
 
@@ -51,7 +51,7 @@ public class CassandraStepdefs {
         cassandra = CassandraCluster.create(
             CassandraModule.aggregateModules(CassandraRRTModule.MODULE, CassandraSchemaVersionModule.MODULE),
             cassandraServer.getHost());
-        mainStepdefs.rewriteTable = getRecipientRewriteTable();
+        mainStepdefs.setUp(Throwing.supplier(this::getRecipientRewriteTable).sneakyThrow());
     }
 
     @After
@@ -64,7 +64,6 @@ public class CassandraStepdefs {
             new CassandraRecipientRewriteTableDAO(cassandra.getConf(), CassandraUtils.WITH_DEFAULT_CONFIGURATION),
             new CassandraMappingsSourcesDAO(cassandra.getConf()),
             new CassandraSchemaVersionDAO(cassandra.getConf()));
-        rrt.configure(new BaseHierarchicalConfiguration());
         rrt.setDomainList(RecipientRewriteTableFixture.domainListForCucumberTests());
         return rrt;
     }
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 4b3f4d4..7ef0a37 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
@@ -18,19 +18,10 @@
  ****************************************************************/
 package org.apache.james.rrt.file;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
 import org.apache.commons.configuration2.convert.DisabledListDelimiterHandler;
-import org.apache.james.rrt.api.RecipientRewriteTableException;
 import org.apache.james.rrt.lib.AbstractRecipientRewriteTable;
 import org.apache.james.rrt.lib.AbstractRecipientRewriteTableTest;
-import org.apache.james.rrt.lib.Mapping;
-import org.apache.james.rrt.lib.Mapping.Type;
-import org.apache.james.rrt.lib.MappingSource;
-import org.apache.james.rrt.lib.Mappings;
-import org.apache.james.rrt.lib.MappingsImpl;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Ignore;
@@ -55,22 +46,7 @@ public class XMLRecipientRewriteTableTest extends AbstractRecipientRewriteTableT
 
     @Override
     protected AbstractRecipientRewriteTable getRecipientRewriteTable() {
-        return new XMLRecipientRewriteTable() {
-            @Override
-            public void addMapping(MappingSource source, Mapping mapping) throws RecipientRewriteTableException {
-                addMappingToConfiguration(source, mapping.getType().withoutPrefix(mapping.asString()), mapping.getType());
-            }
-
-            @Override
-            public void removeMapping(MappingSource source, Mapping mapping) throws RecipientRewriteTableException {
-                removeMappingFromConfiguration(source, mapping.getType().withoutPrefix(mapping.asString()), mapping.getType());
-            }
-
-            @Override
-            public void addAddressMapping(MappingSource source, String address) throws RecipientRewriteTableException {
-                addMapping(source, Mapping.address(address));
-            }
-        };
+        return new XMLRecipientRewriteTable();
     }
 
     @Test
@@ -85,57 +61,182 @@ public class XMLRecipientRewriteTableTest extends AbstractRecipientRewriteTableT
     public void addMappingShouldThrowWhenMappingAlreadyExists() {
     }
 
-    protected void addMappingToConfiguration(MappingSource source, String mapping, Type type) throws RecipientRewriteTableException {
-        Mappings mappings = virtualUserTable.getStoredMappings(source);
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void testStoreAndGetMappings() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void testStoreAndRetrieveRegexMapping() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void getAllMappingsShouldListAllEntries() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void testStoreAndRetrieveAddressMapping() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void testStoreAndRetrieveErrorMapping() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void testStoreAndRetrieveWildCardAddressMapping() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void testNonRecursiveMapping() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void testAliasDomainMapping() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void addMappingShouldNotThrowWhenMappingAlreadyExistsWithAnOtherType() {
+    }
 
-        Mappings updatedMappings = MappingsImpl.from(mappings)
-            .add(Mapping.of(type, mapping))
-            .build();
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void addForwardMappingShouldStore() {
+    }
 
-        updateConfiguration(source, mappings, updatedMappings);
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void removeForwardMappingShouldDelete() {
     }
 
-    protected void removeMappingFromConfiguration(MappingSource source, String mapping, Type type) throws RecipientRewriteTableException {
-        Mappings oldMappings = virtualUserTable.getStoredMappings(source);
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void addGroupMappingShouldStore() {
+    }
 
-        if (oldMappings.isEmpty()) {
-            throw new RecipientRewriteTableException("Cannot remove from null mappings");
-        }
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void removeGroupMappingShouldDelete() {
+    }
 
-        Mappings updatedMappings = oldMappings.remove(Mapping.of(type, mapping));
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void addAliasMappingShouldStore() {
 
-        updateConfiguration(source, oldMappings, updatedMappings);
     }
 
-    private void updateConfiguration(MappingSource source, Mappings oldMappings, Mappings updatedMappings) throws RecipientRewriteTableException {
-        removeMappingsFromConfig(source, oldMappings);
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void removeAliasMappingShouldDelete() {
 
-        if (!updatedMappings.isEmpty()) {
-            defaultConfiguration.addProperty("mapping", source.getFixedUser() + "@" + source.getFixedDomain() + "=" + updatedMappings.serialize());
-        }
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void listSourcesShouldReturnWhenHasMapping() {
+
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void listSourcesShouldReturnWhenMultipleSourceMapping() {
+
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void listSourcesShouldReturnWhenHasForwardMapping() {
 
-        try {
-            virtualUserTable.configure(defaultConfiguration);
-        } catch (Exception e) {
-            if (updatedMappings.size() > 0) {
-                throw new RecipientRewriteTableException("Error update mapping", e);
-            }
-        }
     }
 
-    private void removeMappingsFromConfig(MappingSource source, Mappings mappings) {
-        List<String> stored = new ArrayList<>();
-        for (String c : defaultConfiguration.getStringArray("mapping")) {
-            String mapping = source.getFixedUser() + "@" + source.getFixedDomain() + "=" + mappings.serialize();
-            if (!c.equalsIgnoreCase(mapping)) {
-                stored.add(c);
-            }
-        }
-        // clear old values
-        defaultConfiguration.clear();
-        // add stored mappings
-        for (String aStored : stored) {
-            defaultConfiguration.addProperty("mapping", aStored);
-        }
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void listSourcesShouldReturnAliasMappings() {
+
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void listSourcesShouldReturnWhenHasAddressMapping() {
+
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void listSourcesShouldThrowExceptionWhenHasRegexMapping() {
+
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void listSourcesShouldHandleDomainMapping() {
+
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void listSourcesShouldHandleDomainSource() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void listSourcesShouldHandleDomainSources() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void listSourcesShouldThrowExceptionWhenHasErrorMapping() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void listSourcesShouldReturnEmptyWhenMappingDoesNotExist() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void getSourcesForTypeShouldReturnEmptyWhenNoMatchingMapping() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void getSourcesForTypeShouldReturnMatchingMapping() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void getSourcesForTypeShouldNotReturnDuplicatedSources() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void getSourcesForTypeShouldReturnSortedStream() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void getMappingsForTypeShouldReturnEmptyWhenNoMatchingMapping() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void getMappingsForTypeShouldReturnMatchingMapping() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void getMappingsForTypeShouldNotReturnDuplicatedDestinations() {
+    }
+
+    @Test
+    @Ignore("XMLRecipientRewriteTable is read only")
+    public void getMappingsForTypeShouldReturnSortedStream() {
     }
 }
diff --git a/server/data/data-file/src/test/java/org/apache/james/rrt/file/XMLStepdefs.java b/server/data/data-file/src/test/java/org/apache/james/rrt/file/XMLStepdefs.java
index 580f928..789f9b3 100644
--- a/server/data/data-file/src/test/java/org/apache/james/rrt/file/XMLStepdefs.java
+++ b/server/data/data-file/src/test/java/org/apache/james/rrt/file/XMLStepdefs.java
@@ -33,10 +33,10 @@ public class XMLStepdefs {
 
     @Before
     public void setup() throws Throwable {
-        mainStepdefs.rewriteTable = getRecipientRewriteTable(); 
+        mainStepdefs.setUp(this::getRecipientRewriteTable);
     }
 
-    private AbstractRecipientRewriteTable getRecipientRewriteTable() throws Exception {
+    private AbstractRecipientRewriteTable getRecipientRewriteTable() {
         return new XMLRecipientRewriteTable();
     }
 }
diff --git a/server/data/data-jpa/src/test/java/org/apache/james/rrt/jpa/JPARecipientRewriteTableTest.java b/server/data/data-jpa/src/test/java/org/apache/james/rrt/jpa/JPARecipientRewriteTableTest.java
index 80f02fa..5f50ab9 100644
--- a/server/data/data-jpa/src/test/java/org/apache/james/rrt/jpa/JPARecipientRewriteTableTest.java
+++ b/server/data/data-jpa/src/test/java/org/apache/james/rrt/jpa/JPARecipientRewriteTableTest.java
@@ -46,8 +46,6 @@ public class JPARecipientRewriteTableTest extends AbstractRecipientRewriteTableT
     protected AbstractRecipientRewriteTable getRecipientRewriteTable() throws Exception {
         JPARecipientRewriteTable localVirtualUserTable = new JPARecipientRewriteTable();
         localVirtualUserTable.setEntityManagerFactory(JPA_TEST_CLUSTER.getEntityManagerFactory());
-        BaseHierarchicalConfiguration defaultConfiguration = new BaseHierarchicalConfiguration();
-        localVirtualUserTable.configure(defaultConfiguration);
         return localVirtualUserTable;
     }
 }
diff --git a/server/data/data-jpa/src/test/java/org/apache/james/rrt/jpa/JPAStepdefs.java b/server/data/data-jpa/src/test/java/org/apache/james/rrt/jpa/JPAStepdefs.java
index 4b27b75..249b0b2 100644
--- a/server/data/data-jpa/src/test/java/org/apache/james/rrt/jpa/JPAStepdefs.java
+++ b/server/data/data-jpa/src/test/java/org/apache/james/rrt/jpa/JPAStepdefs.java
@@ -18,13 +18,13 @@
  ****************************************************************/
 package org.apache.james.rrt.jpa;
 
-import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
 import org.apache.james.backends.jpa.JpaTestCluster;
 import org.apache.james.rrt.jpa.model.JPARecipientRewrite;
 import org.apache.james.rrt.lib.AbstractRecipientRewriteTable;
 import org.apache.james.rrt.lib.RecipientRewriteTableFixture;
 import org.apache.james.rrt.lib.RewriteTablesStepdefs;
 
+import com.github.fge.lambdas.Throwing;
 import cucumber.api.java.After;
 import cucumber.api.java.Before;
 
@@ -40,7 +40,7 @@ public class JPAStepdefs {
 
     @Before
     public void setup() throws Throwable {
-        mainStepdefs.rewriteTable = getRecipientRewriteTable(); 
+        mainStepdefs.setUp(Throwing.supplier(this::getRecipientRewriteTable).sneakyThrow());
     }
 
     @After
@@ -51,8 +51,6 @@ public class JPAStepdefs {
     private AbstractRecipientRewriteTable getRecipientRewriteTable() throws Exception {
         JPARecipientRewriteTable localVirtualUserTable = new JPARecipientRewriteTable();
         localVirtualUserTable.setEntityManagerFactory(JPA_TEST_CLUSTER.getEntityManagerFactory());
-        BaseHierarchicalConfiguration defaultConfiguration = new BaseHierarchicalConfiguration();
-        localVirtualUserTable.configure(defaultConfiguration);
         localVirtualUserTable.setDomainList(RecipientRewriteTableFixture.domainListForCucumberTests());
         return localVirtualUserTable;
     }
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 cafc427..b341d92 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
@@ -40,6 +40,7 @@ import org.apache.james.lifecycle.api.Configurable;
 import org.apache.james.rrt.api.InvalidRegexException;
 import org.apache.james.rrt.api.MappingAlreadyExistsException;
 import org.apache.james.rrt.api.RecipientRewriteTable;
+import org.apache.james.rrt.api.RecipientRewriteTableConfiguration;
 import org.apache.james.rrt.api.RecipientRewriteTableException;
 import org.apache.james.rrt.api.SameSourceAndDestinationException;
 import org.apache.james.rrt.api.SourceDomainIsNotInDomainListException;
@@ -49,24 +50,17 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
 
 public abstract class AbstractRecipientRewriteTable implements RecipientRewriteTable, Configurable {
     private static final Logger LOGGER = LoggerFactory.getLogger(AbstractRecipientRewriteTable.class);
 
-    // The maximum mappings which will process before throwing exception
-    private int mappingLimit = 10;
-
-    private boolean recursive = true;
-
+    private RecipientRewriteTableConfiguration configuration;
     private DomainList domainList;
 
-    @Override
-    public int getMappingLimit() {
-        if (recursive) {
-            return mappingLimit;
-        } else {
-            return 0;
-        }
+    public void setConfiguration(RecipientRewriteTableConfiguration configuration) {
+        Preconditions.checkState(this.configuration == null, "A configuration cannot be set twice");
+        this.configuration = configuration;
     }
 
     @Inject
@@ -76,44 +70,23 @@ public abstract class AbstractRecipientRewriteTable implements RecipientRewriteT
 
     @Override
     public void configure(HierarchicalConfiguration<ImmutableNode> config) throws ConfigurationException {
-        setRecursiveMapping(config.getBoolean("recursiveMapping", true));
-        try {
-            setMappingLimit(config.getInt("mappingLimit", 10));
-        } catch (IllegalArgumentException e) {
-            throw new ConfigurationException(e.getMessage());
-        }
+        setConfiguration(RecipientRewriteTableConfiguration.fromConfiguration(config));
         doConfigure(config);
     }
 
-    /**
-     * Override to handle config
-     */
-    protected void doConfigure(HierarchicalConfiguration<ImmutableNode> conf) throws ConfigurationException {
-    }
+    protected void doConfigure(HierarchicalConfiguration<ImmutableNode> arg0) throws ConfigurationException {
 
-    public void setRecursiveMapping(boolean recursive) {
-        this.recursive = recursive;
     }
 
-    /**
-     * Set the mappingLimit
-     * 
-     * @param mappingLimit
-     *            the mappingLimit
-     * @throws IllegalArgumentException
-     *             get thrown if mappingLimit smaller then 1 is used
-     */
-    public void setMappingLimit(int mappingLimit) throws IllegalArgumentException {
-        if (mappingLimit < 1) {
-            throw new IllegalArgumentException("The minimum mappingLimit is 1");
-        }
-        this.mappingLimit = mappingLimit;
+    @Override
+    public RecipientRewriteTableConfiguration getConfiguration() {
+        return configuration;
     }
 
     @Override
     public Mappings getResolvedMappings(String user, Domain domain, EnumSet<Type> mappingTypes) throws ErrorMappingException, RecipientRewriteTableException {
-
-        return getMappings(Username.fromLocalPartWithDomain(user, domain), mappingLimit, mappingTypes);
+        Preconditions.checkState(this.configuration != null, "RecipientRewriteTable is not configured");
+        return getMappings(Username.fromLocalPartWithDomain(user, domain), configuration.getMappingLimit(), mappingTypes);
     }
 
     private Mappings getMappings(Username username, int mappingLimit, EnumSet<Type> mappingTypes) throws ErrorMappingException, RecipientRewriteTableException {
@@ -155,7 +128,7 @@ public abstract class AbstractRecipientRewriteTable implements RecipientRewriteT
         LOGGER.debug("Valid virtual user mapping {} to {}", originalUsername.asString(), rewrittenUsername.asString());
 
         Stream<Mapping> nonRecursiveResult = Stream.of(toMapping(rewrittenUsername, mapping.getType()));
-        if (!recursive) {
+        if (!configuration.isRecursive()) {
             return nonRecursiveResult;
         }
 
diff --git a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableImpl.java b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AliasReverseResolverImpl.java
similarity index 91%
rename from server/data/data-library/src/main/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableImpl.java
rename to server/data/data-library/src/main/java/org/apache/james/rrt/lib/AliasReverseResolverImpl.java
index 419a69b..5bec3f7 100644
--- a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableImpl.java
+++ b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AliasReverseResolverImpl.java
@@ -31,21 +31,23 @@ import javax.inject.Inject;
 import org.apache.james.core.Domain;
 import org.apache.james.core.MailAddress;
 import org.apache.james.core.Username;
+import org.apache.james.rrt.api.AliasReverseResolver;
 import org.apache.james.rrt.api.RecipientRewriteTable;
 import org.apache.james.rrt.api.RecipientRewriteTableException;
-import org.apache.james.rrt.api.ReverseRecipientRewriteTable;
 import org.apache.james.util.OptionalUtils;
 import org.apache.james.util.StreamUtils;
 
 import com.github.fge.lambdas.Throwing;
 import com.github.steveash.guavate.Guavate;
 
-public class ReverseRecipientRewriteTableImpl implements ReverseRecipientRewriteTable {
+public class AliasReverseResolverImpl implements AliasReverseResolver {
     private final RecipientRewriteTable recipientRewriteTable;
+    private final int mappingLimit;
 
     @Inject
-    public ReverseRecipientRewriteTableImpl(RecipientRewriteTable recipientRewriteTable) {
+    public AliasReverseResolverImpl(RecipientRewriteTable recipientRewriteTable) {
         this.recipientRewriteTable = recipientRewriteTable;
+        this.mappingLimit = recipientRewriteTable.getConfiguration().getMappingLimit();
     }
 
     @Override
@@ -64,7 +66,7 @@ public class ReverseRecipientRewriteTableImpl implements ReverseRecipientRewrite
     private Stream<Username> relatedAliases(Username user) {
         return StreamUtils.iterate(
             user,
-            (long) recipientRewriteTable.getMappingLimit(),
+            (long) mappingLimit,
             Throwing.<Username, Stream<Username>>function(targetUser ->
                 recipientRewriteTable
                     .listSources(Mapping.alias(targetUser.asString()))
@@ -94,7 +96,7 @@ public class ReverseRecipientRewriteTableImpl implements ReverseRecipientRewrite
     private Stream<Domain> fetchDomains(Domain domain) {
         return StreamUtils.iterate(
             domain,
-            (long) recipientRewriteTable.getMappingLimit(),
+            (long) mappingLimit,
             Throwing.<Domain, Stream<Domain>>function(targetDomain ->
                 recipientRewriteTable
                     .listSources(Mapping.domain(targetDomain))
diff --git a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/CanSendFromImpl.java b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/CanSendFromImpl.java
index b2bedc8..70d7a82 100644
--- a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/CanSendFromImpl.java
+++ b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/CanSendFromImpl.java
@@ -30,10 +30,10 @@ import javax.inject.Inject;
 import org.apache.james.core.Domain;
 import org.apache.james.core.MailAddress;
 import org.apache.james.core.Username;
+import org.apache.james.rrt.api.AliasReverseResolver;
 import org.apache.james.rrt.api.CanSendFrom;
 import org.apache.james.rrt.api.RecipientRewriteTable;
 import org.apache.james.rrt.api.RecipientRewriteTableException;
-import org.apache.james.rrt.api.ReverseRecipientRewriteTable;
 import org.apache.james.util.OptionalUtils;
 
 public class CanSendFromImpl implements CanSendFrom {
@@ -45,12 +45,12 @@ public class CanSendFromImpl implements CanSendFrom {
 
     public static final EnumSet<Mapping.Type> ALIAS_TYPES_ACCEPTED_IN_FROM = EnumSet.of(Alias, Domain);
     private final RecipientRewriteTable recipientRewriteTable;
-    private final ReverseRecipientRewriteTable reverseRecipientRewriteTable;
+    private final AliasReverseResolver aliasReverseResolver;
 
     @Inject
-    public CanSendFromImpl(RecipientRewriteTable recipientRewriteTable, ReverseRecipientRewriteTable reverseRecipientRewriteTable) {
+    public CanSendFromImpl(RecipientRewriteTable recipientRewriteTable, AliasReverseResolver aliasReverseResolver) {
         this.recipientRewriteTable = recipientRewriteTable;
-        this.reverseRecipientRewriteTable = reverseRecipientRewriteTable;
+        this.aliasReverseResolver = aliasReverseResolver;
     }
 
     @Override
@@ -64,7 +64,7 @@ public class CanSendFromImpl implements CanSendFrom {
 
     @Override
     public Stream<MailAddress> allValidFromAddressesForUser(Username user) throws RecipientRewriteTable.ErrorMappingException, RecipientRewriteTableException {
-        return reverseRecipientRewriteTable.listAddresses(user);
+        return aliasReverseResolver.listAddresses(user);
     }
 
     private boolean emailIsAnAliasOfTheConnectedUser(Username connectedUser, Username fromUser) throws RecipientRewriteTable.ErrorMappingException, RecipientRewriteTableException {
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 fab6ab3..4f9928c 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
@@ -19,6 +19,7 @@
 package org.apache.james.rrt.lib;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.util.Map;
@@ -28,6 +29,7 @@ import org.apache.james.core.Domain;
 import org.apache.james.domainlist.api.mock.SimpleDomainList;
 import org.apache.james.lifecycle.api.LifecycleUtil;
 import org.apache.james.rrt.api.RecipientRewriteTable.ErrorMappingException;
+import org.apache.james.rrt.api.RecipientRewriteTableConfiguration;
 import org.apache.james.rrt.api.RecipientRewriteTableException;
 import org.apache.james.rrt.api.SourceDomainIsNotInDomainListException;
 import org.junit.Rule;
@@ -58,6 +60,20 @@ public abstract class AbstractRecipientRewriteTableTest {
     protected AbstractRecipientRewriteTable virtualUserTable;
 
     public void setUp() throws Exception {
+        setRecursiveRecipientRewriteTable();
+    }
+
+    private void setRecursiveRecipientRewriteTable() throws Exception {
+        setNotConfiguredRecipientRewriteTable();
+        virtualUserTable.setConfiguration(new RecipientRewriteTableConfiguration(true, 10));
+    }
+
+    private void setNonRecursiveRecipientRewriteTable() throws Exception {
+        setNotConfiguredRecipientRewriteTable();
+        virtualUserTable.setConfiguration(new RecipientRewriteTableConfiguration(false, 0));
+    }
+
+    private void setNotConfiguredRecipientRewriteTable() throws Exception {
         virtualUserTable = getRecipientRewriteTable();
 
         SimpleDomainList domainList = new SimpleDomainList();
@@ -89,6 +105,19 @@ public abstract class AbstractRecipientRewriteTableTest {
     }
 
     @Test
+    public void notConfiguredResolutionShouldThrow() throws Exception {
+        setNotConfiguredRecipientRewriteTable();
+        assertThatCode(() -> virtualUserTable.getResolvedMappings(USER, Domain.LOCALHOST))
+            .isInstanceOf(IllegalStateException.class);
+    }
+
+    @Test
+    public void configuringTwiceShouldThrow() {
+        assertThatCode(() -> virtualUserTable.setConfiguration(new RecipientRewriteTableConfiguration(true, 10)))
+            .isInstanceOf(IllegalStateException.class);
+    }
+
+    @Test
     public void testStoreAndRetrieveRegexMapping() throws Exception {
         String regex = "(.*)@localhost";
         String regex2 = "(.+)@test";
@@ -211,7 +240,7 @@ public abstract class AbstractRecipientRewriteTableTest {
     }
 
     @Test
-    public void testRecursiveMapping() throws Exception {
+    public void testNonRecursiveMapping() throws Exception {
         String user1 = "user1";
         String user2 = "user2";
         String user3 = "user3";
@@ -220,26 +249,17 @@ public abstract class AbstractRecipientRewriteTableTest {
         Domain domain3 = Domain.of("domain3");
         MappingSource source1 = MappingSource.fromUser(user1, domain1);
         MappingSource source2 = MappingSource.fromUser(user2, domain2);
-        MappingSource source3 = MappingSource.fromUser(user3, domain3);
 
-        virtualUserTable.setRecursiveMapping(true);
+        setNonRecursiveRecipientRewriteTable();
 
         assertThat(virtualUserTable.getAllMappings()).describedAs("No mapping").isEmpty();
 
         virtualUserTable.addMapping(source1, Mapping.address(user2 + "@" + domain2.asString()));
         virtualUserTable.addMapping(source2, Mapping.address(user3 + "@" + domain3.asString()));
-        assertThat(virtualUserTable.getResolvedMappings(user1, domain1)).containsOnly(Mapping.address(user3 + "@" + domain3.asString()));
-        virtualUserTable.addMapping(source3, Mapping.address(user1 + "@" + domain1.asString()));
-
         assertThatThrownBy(() ->
             virtualUserTable.getResolvedMappings(user1, domain1))
-            .describedAs("Exception thrown on to many mappings")
+            .describedAs("Exception thrown on too many mappings")
             .isInstanceOf(ErrorMappingException.class);
-
-        // disable recursive mapping
-        virtualUserTable.setRecursiveMapping(false);
-        assertThat(virtualUserTable.getResolvedMappings(user1, domain1)).describedAs("Not recursive mapped")
-            .containsExactly(Mapping.address(user2 + "@" + domain2.asString()));
     }
 
     @Test
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 3b3d80e..23d7684 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
@@ -22,9 +22,11 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.util.List;
+import java.util.function.Supplier;
 
 import org.apache.james.core.Domain;
 import org.apache.james.rrt.api.RecipientRewriteTable.ErrorMappingException;
+import org.apache.james.rrt.api.RecipientRewriteTableConfiguration;
 import org.apache.james.rrt.api.RecipientRewriteTableException;
 
 import cucumber.api.java.en.Given;
@@ -33,9 +35,16 @@ import cucumber.api.java.en.When;
 
 public class RewriteTablesStepdefs {
 
-    public AbstractRecipientRewriteTable rewriteTable;
+    private Supplier<AbstractRecipientRewriteTable> recipientRewriteTableSupplier;
+    private AbstractRecipientRewriteTable rewriteTable;
     private Exception exception;
 
+    public void setUp(Supplier<AbstractRecipientRewriteTable> recipientRewriteTableSupplier) {
+        this.recipientRewriteTableSupplier = recipientRewriteTableSupplier;
+        this.rewriteTable = this.recipientRewriteTableSupplier.get();
+        this.rewriteTable.setConfiguration(new RecipientRewriteTableConfiguration(true, 10));
+    }
+
     @Given("store \"([^\"]*)\" regexp mapping for user \"([^\"]*)\" at domain \"([^\"]*)\"")
     public void storeRegexpMappingForUserAtDomain(String regexp, String user, String domain) throws Throwable {
         MappingSource source = MappingSource.fromUser(user, domain);
@@ -98,12 +107,13 @@ public class RewriteTablesStepdefs {
 
     @Given("recursive mapping is disable")
     public void disableRecursiveMapping() {
-        rewriteTable.setRecursiveMapping(false);
+        this.rewriteTable = this.recipientRewriteTableSupplier.get();
+        this.rewriteTable.setConfiguration(new RecipientRewriteTableConfiguration(false, 0));
     }
 
     @Given("recursive mapping is enable")
     public void enableRecursiveMapping() {
-        rewriteTable.setRecursiveMapping(true);
+        // default case
     }
 
     @When("user \"([^\"]*)\" at domain \"([^\"]*)\" removes a regexp mapping \"([^\"]*)\"")
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 9e1a367..c4367de 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
@@ -107,13 +107,13 @@ Feature: Rewrite Tables tests
     Given recursive mapping is disable
     Given store "test@localhost" address mapping as wildcard for domain "localhost"
     And store "mine@localhost" address mapping for user "user" at domain "localhost"
-    Then mappings for user "user" at domain "localhost" should contain only "mine@localhost"
+    Then retrieving mappings for user "user" at domain "localhost" should raise an ErrorMappingException with message "554 Too many mappings to process"
 
   Scenario: direct mapping should override address mapping as wildcard (reverse insertion order)
     Given recursive mapping is disable
     Given store "mine@localhost" address mapping for user "user" at domain "localhost"
     And store "test@localhost" address mapping as wildcard for domain "localhost"
-    Then mappings for user "user" at domain "localhost" should contain only "mine@localhost"
+    Then retrieving mappings for user "user" at domain "localhost" should raise an ErrorMappingException with message "554 Too many mappings to process"
 
   Scenario: direct mapping should not override address mapping as wildcard when other user
     Given store "test@localhost" address mapping as wildcard for domain "localhost"
@@ -188,11 +188,11 @@ Feature: Rewrite Tables tests
 
 # Recursive mapping
 
-  Scenario: direct mapping should be returned when recursive mapping is disable
+  Scenario: direct mapping should throw when recursive mapping is disable
     Given recursive mapping is disable
     And store "user2@domain2" address mapping for user "user1" at domain "domain1"
     And store "user3@domain3" address mapping for user "user2" at domain "domain2"
-    Then mappings for user "user1" at domain "domain1" should contain only "user2@domain2"
+    Then retrieving mappings for user "user1" at domain "localhost1" should raise an ErrorMappingException with message "554 Too many mappings to process"
 
   Scenario: recursive mapping should work when two levels
     Given recursive mapping is enable
diff --git a/server/data/data-memory/src/test/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableImplTest.java b/server/data/data-memory/src/test/java/org/apache/james/rrt/lib/AliasReverseResolverImplTest.java
similarity index 78%
rename from server/data/data-memory/src/test/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableImplTest.java
rename to server/data/data-memory/src/test/java/org/apache/james/rrt/lib/AliasReverseResolverImplTest.java
index fe0d17b..7230ee5 100644
--- a/server/data/data-memory/src/test/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableImplTest.java
+++ b/server/data/data-memory/src/test/java/org/apache/james/rrt/lib/AliasReverseResolverImplTest.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.rrt.lib;
 
+import static org.apache.james.rrt.api.RecipientRewriteTableConfiguration.DEFAULT_ENABLED_MAPPING_LIMIT;
+import static org.apache.james.rrt.api.RecipientRewriteTableConfiguration.RECURSIVE_MAPPING_ENABLE;
 import static org.mockito.Mockito.mock;
 
 import org.apache.james.core.Domain;
@@ -26,14 +28,15 @@ import org.apache.james.core.Username;
 import org.apache.james.dnsservice.api.DNSService;
 import org.apache.james.domainlist.lib.DomainListConfiguration;
 import org.apache.james.domainlist.memory.MemoryDomainList;
-import org.apache.james.rrt.api.ReverseRecipientRewriteTable;
+import org.apache.james.rrt.api.AliasReverseResolver;
+import org.apache.james.rrt.api.RecipientRewriteTableConfiguration;
 import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
 import org.junit.jupiter.api.BeforeEach;
 
-public class ReverseRecipientRewriteTableImplTest implements ReverseRecipientRewriteTableContract {
+public class AliasReverseResolverImplTest implements AliasReverseResolverContract {
 
     AbstractRecipientRewriteTable recipientRewriteTable;
-    ReverseRecipientRewriteTableImpl reverseRecipientRewriteTable;
+    AliasReverseResolverImpl aliasReverseResolver;
 
     @BeforeEach
     void setup() throws Exception {
@@ -47,13 +50,14 @@ public class ReverseRecipientRewriteTableImplTest implements ReverseRecipientRew
         domainList.addDomain(DOMAIN);
         domainList.addDomain(OTHER_DOMAIN);
         recipientRewriteTable.setDomainList(domainList);
+        recipientRewriteTable.setConfiguration(new RecipientRewriteTableConfiguration(RECURSIVE_MAPPING_ENABLE, DEFAULT_ENABLED_MAPPING_LIMIT));
 
-        this.reverseRecipientRewriteTable = new ReverseRecipientRewriteTableImpl(recipientRewriteTable);
+        this.aliasReverseResolver = new AliasReverseResolverImpl(recipientRewriteTable);
     }
 
     @Override
-    public ReverseRecipientRewriteTable reverseRecipientRewriteTable() {
-        return reverseRecipientRewriteTable;
+    public AliasReverseResolver aliasReverseResolver() {
+        return aliasReverseResolver;
     }
 
     @Override
diff --git a/server/data/data-memory/src/test/java/org/apache/james/rrt/lib/CanSendFromImplTest.java b/server/data/data-memory/src/test/java/org/apache/james/rrt/lib/CanSendFromImplTest.java
index 47863a1..99265c1 100644
--- a/server/data/data-memory/src/test/java/org/apache/james/rrt/lib/CanSendFromImplTest.java
+++ b/server/data/data-memory/src/test/java/org/apache/james/rrt/lib/CanSendFromImplTest.java
@@ -18,6 +18,8 @@
  ****************************************************************/
 package org.apache.james.rrt.lib;
 
+import static org.apache.james.rrt.api.RecipientRewriteTableConfiguration.DEFAULT_ENABLED_MAPPING_LIMIT;
+import static org.apache.james.rrt.api.RecipientRewriteTableConfiguration.RECURSIVE_MAPPING_ENABLE;
 import static org.mockito.Mockito.mock;
 
 import org.apache.james.core.Domain;
@@ -26,7 +28,8 @@ import org.apache.james.dnsservice.api.DNSService;
 import org.apache.james.domainlist.lib.DomainListConfiguration;
 import org.apache.james.domainlist.memory.MemoryDomainList;
 import org.apache.james.rrt.api.CanSendFrom;
-import org.apache.james.rrt.api.ReverseRecipientRewriteTable;
+import org.apache.james.rrt.api.AliasReverseResolver;
+import org.apache.james.rrt.api.RecipientRewriteTableConfiguration;
 import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
 import org.junit.jupiter.api.BeforeEach;
 
@@ -47,9 +50,10 @@ public class CanSendFromImplTest implements CanSendFromContract {
         domainList.addDomain(DOMAIN);
         domainList.addDomain(OTHER_DOMAIN);
         recipientRewriteTable.setDomainList(domainList);
+        recipientRewriteTable.setConfiguration(new RecipientRewriteTableConfiguration(RECURSIVE_MAPPING_ENABLE, DEFAULT_ENABLED_MAPPING_LIMIT));
 
-        ReverseRecipientRewriteTable reverseRecipientRewriteTable = new ReverseRecipientRewriteTableImpl(recipientRewriteTable);
-        canSendFrom = new CanSendFromImpl(recipientRewriteTable, reverseRecipientRewriteTable);
+        AliasReverseResolver aliasReverseResolver = new AliasReverseResolverImpl(recipientRewriteTable);
+        canSendFrom = new CanSendFromImpl(recipientRewriteTable, aliasReverseResolver);
     }
 
     @Override
diff --git a/server/data/data-memory/src/test/java/org/apache/james/rrt/memory/InMemoryStepdefs.java b/server/data/data-memory/src/test/java/org/apache/james/rrt/memory/InMemoryStepdefs.java
index c3176a8..a2c36da 100644
--- a/server/data/data-memory/src/test/java/org/apache/james/rrt/memory/InMemoryStepdefs.java
+++ b/server/data/data-memory/src/test/java/org/apache/james/rrt/memory/InMemoryStepdefs.java
@@ -19,11 +19,11 @@
 
 package org.apache.james.rrt.memory;
 
-import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
 import org.apache.james.rrt.lib.AbstractRecipientRewriteTable;
 import org.apache.james.rrt.lib.RecipientRewriteTableFixture;
 import org.apache.james.rrt.lib.RewriteTablesStepdefs;
 
+import com.github.fge.lambdas.Throwing;
 import cucumber.api.java.Before;
 
 public class InMemoryStepdefs {
@@ -36,12 +36,11 @@ public class InMemoryStepdefs {
 
     @Before
     public void setup() throws Throwable {
-        mainStepdefs.rewriteTable = getRecipientRewriteTable(); 
+        mainStepdefs.setUp(Throwing.supplier(this::getRecipientRewriteTable).sneakyThrow());
     }
 
     private AbstractRecipientRewriteTable getRecipientRewriteTable() throws Exception {
         MemoryRecipientRewriteTable rrt = new MemoryRecipientRewriteTable();
-        rrt.configure(new BaseHierarchicalConfiguration());
         rrt.setDomainList(RecipientRewriteTableFixture.domainListForCucumberTests());
         return rrt;
     }
diff --git a/server/data/data-memory/src/test/java/org/apache/james/rrt/memory/MemoryRecipientRewriteTableTest.java b/server/data/data-memory/src/test/java/org/apache/james/rrt/memory/MemoryRecipientRewriteTableTest.java
index da7853f..7725797 100644
--- a/server/data/data-memory/src/test/java/org/apache/james/rrt/memory/MemoryRecipientRewriteTableTest.java
+++ b/server/data/data-memory/src/test/java/org/apache/james/rrt/memory/MemoryRecipientRewriteTableTest.java
@@ -19,7 +19,6 @@
 
 package org.apache.james.rrt.memory;
 
-import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
 import org.apache.james.rrt.lib.AbstractRecipientRewriteTable;
 import org.apache.james.rrt.lib.AbstractRecipientRewriteTableTest;
 import org.junit.After;
@@ -40,9 +39,7 @@ public class MemoryRecipientRewriteTableTest extends AbstractRecipientRewriteTab
     }
 
     @Override
-    protected AbstractRecipientRewriteTable getRecipientRewriteTable() throws Exception {
-        AbstractRecipientRewriteTable rrt = new MemoryRecipientRewriteTable();
-        rrt.configure(new BaseHierarchicalConfiguration());
-        return rrt;
+    protected AbstractRecipientRewriteTable getRecipientRewriteTable() {
+        return new MemoryRecipientRewriteTable();
     }
 }
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java
index 6740ff1..a4a25fc 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java
@@ -74,11 +74,11 @@ import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
 import org.apache.james.rrt.api.CanSendFrom;
 import org.apache.james.rrt.api.RecipientRewriteTableException;
-import org.apache.james.rrt.api.ReverseRecipientRewriteTable;
+import org.apache.james.rrt.api.AliasReverseResolver;
+import org.apache.james.rrt.lib.AliasReverseResolverImpl;
 import org.apache.james.rrt.lib.Mapping;
 import org.apache.james.rrt.lib.MappingSource;
 import org.apache.james.rrt.lib.CanSendFromImpl;
-import org.apache.james.rrt.lib.ReverseRecipientRewriteTableImpl;
 import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
 import org.apache.james.util.OptionalUtils;
 import org.apache.james.util.html.HtmlTextExtractor;
@@ -156,8 +156,8 @@ public class SetMessagesCreationProcessorTest {
         domainList.addDomain(Domain.of("example.com"));
         domainList.addDomain(Domain.of("other.org"));
         recipientRewriteTable.setDomainList(domainList);
-        ReverseRecipientRewriteTable reverseRecipientRewriteTable = new ReverseRecipientRewriteTableImpl(recipientRewriteTable);
-        canSendFrom = new CanSendFromImpl(recipientRewriteTable, reverseRecipientRewriteTable);
+        AliasReverseResolver aliasReverseResolver = new AliasReverseResolverImpl(recipientRewriteTable);
+        canSendFrom = new CanSendFromImpl(recipientRewriteTable, aliasReverseResolver);
         messageFullViewFactory = new MessageFullViewFactory(blobManager, messageContentExtractor, htmlTextExtractor,
             messageIdManager,
             new MemoryMessageFastViewProjection(new RecordingMetricFactory()));
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesUpdateProcessorTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesUpdateProcessorTest.java
index 4b8f472..e3c9bf8 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesUpdateProcessorTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesUpdateProcessorTest.java
@@ -67,10 +67,10 @@ import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
 import org.apache.james.rrt.api.CanSendFrom;
 import org.apache.james.rrt.api.RecipientRewriteTableException;
-import org.apache.james.rrt.api.ReverseRecipientRewriteTable;
+import org.apache.james.rrt.api.AliasReverseResolver;
+import org.apache.james.rrt.lib.AliasReverseResolverImpl;
 import org.apache.james.rrt.lib.CanSendFromImpl;
 import org.apache.james.rrt.lib.MappingSource;
-import org.apache.james.rrt.lib.ReverseRecipientRewriteTableImpl;
 import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
 import org.apache.james.util.OptionalUtils;
 import org.apache.james.util.html.HtmlTextExtractor;
@@ -169,8 +169,8 @@ public class SetMessagesUpdateProcessorTest {
         domainList.addDomain(Domain.of("example.com"));
         domainList.addDomain(Domain.of("other.org"));
         recipientRewriteTable.setDomainList(domainList);
-        ReverseRecipientRewriteTable reverseRecipientRewriteTable = new ReverseRecipientRewriteTableImpl(recipientRewriteTable);
-        canSendFrom = new CanSendFromImpl(recipientRewriteTable, reverseRecipientRewriteTable);
+        AliasReverseResolver aliasReverseResolver = new AliasReverseResolverImpl(recipientRewriteTable);
+        canSendFrom = new CanSendFromImpl(recipientRewriteTable, aliasReverseResolver);
         mockedMailSpool = mock(MailSpool.class);
         mockedMailboxManager = mock(MailboxManager.class);
         mockedMailboxIdFactory = mock(MailboxId.Factory.class);
diff --git a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
index c471f72..fbfb0a0 100644
--- a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
+++ b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
@@ -70,12 +70,12 @@ import org.apache.james.protocols.netty.AbstractChannelPipelineFactory;
 import org.apache.james.queue.api.MailQueueFactory;
 import org.apache.james.queue.api.RawMailQueueItemDecoratorFactory;
 import org.apache.james.queue.memory.MemoryMailQueueFactory;
+import org.apache.james.rrt.api.AliasReverseResolver;
 import org.apache.james.rrt.api.CanSendFrom;
 import org.apache.james.rrt.api.RecipientRewriteTable;
-import org.apache.james.rrt.api.ReverseRecipientRewriteTable;
+import org.apache.james.rrt.lib.AliasReverseResolverImpl;
 import org.apache.james.rrt.lib.CanSendFromImpl;
 import org.apache.james.rrt.lib.MappingSource;
-import org.apache.james.rrt.lib.ReverseRecipientRewriteTableImpl;
 import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
 import org.apache.james.server.core.configuration.Configuration;
 import org.apache.james.server.core.filesystem.FileSystemImpl;
@@ -200,7 +200,7 @@ public class SMTPServerTest {
     protected MemoryMailQueueFactory queueFactory;
     protected MemoryMailQueueFactory.MemoryMailQueue queue;
     protected MemoryRecipientRewriteTable rewriteTable;
-    private ReverseRecipientRewriteTable reverseRewriteTable;
+    private AliasReverseResolver aliasReverseResolver;
     protected CanSendFrom canSendFrom;
 
     private SMTPServer smtpServer;
@@ -279,8 +279,8 @@ public class SMTPServerTest {
         dnsServer = new AlterableDNSServer();
 
         rewriteTable = new MemoryRecipientRewriteTable();
-        reverseRewriteTable = new ReverseRecipientRewriteTableImpl(rewriteTable);
-        canSendFrom = new CanSendFromImpl(rewriteTable, reverseRewriteTable);
+        aliasReverseResolver = new AliasReverseResolverImpl(rewriteTable);
+        canSendFrom = new CanSendFromImpl(rewriteTable, aliasReverseResolver);
         queueFactory = new MemoryMailQueueFactory(new RawMailQueueItemDecoratorFactory());
         queue = queueFactory.createQueue(MailQueueFactory.SPOOL);
 
diff --git a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/UserRoutesTest.java b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/UserRoutesTest.java
index d45f79e..d876ce2 100644
--- a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/UserRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/UserRoutesTest.java
@@ -40,13 +40,13 @@ import org.apache.james.core.Domain;
 import org.apache.james.core.Username;
 import org.apache.james.domainlist.api.DomainListException;
 import org.apache.james.domainlist.api.mock.SimpleDomainList;
+import org.apache.james.rrt.api.AliasReverseResolver;
 import org.apache.james.rrt.api.CanSendFrom;
 import org.apache.james.rrt.api.RecipientRewriteTable;
 import org.apache.james.rrt.api.RecipientRewriteTableException;
-import org.apache.james.rrt.api.ReverseRecipientRewriteTable;
 import org.apache.james.rrt.lib.CanSendFromImpl;
 import org.apache.james.rrt.lib.MappingSource;
-import org.apache.james.rrt.lib.ReverseRecipientRewriteTableImpl;
+import org.apache.james.rrt.lib.AliasReverseResolverImpl;
 import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
@@ -100,7 +100,7 @@ class UserRoutesTest {
         final MemoryUsersRepository usersRepository;
         final SimpleDomainList domainList;
         final MemoryRecipientRewriteTable recipientRewriteTable;
-        final ReverseRecipientRewriteTable reverseRecipientRewriteTable;
+        final AliasReverseResolver aliasReverseResolver;
         final CanSendFrom canSendFrom;
 
         WebAdminServer webAdminServer;
@@ -110,8 +110,8 @@ class UserRoutesTest {
             this.domainList = domainList;
             this.recipientRewriteTable = new MemoryRecipientRewriteTable();
             this.recipientRewriteTable.setDomainList(domainList);
-            this.reverseRecipientRewriteTable = new ReverseRecipientRewriteTableImpl(recipientRewriteTable);
-            this.canSendFrom = new CanSendFromImpl(recipientRewriteTable, reverseRecipientRewriteTable);
+            this.aliasReverseResolver = new AliasReverseResolverImpl(recipientRewriteTable);
+            this.canSendFrom = new CanSendFromImpl(recipientRewriteTable, aliasReverseResolver);
         }
 
         @Override


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