You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2021/02/25 09:06:56 UTC

[james-project] 08/12: JAMES-3400 Add remove and list domain aliases

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

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

commit bf2535a45e6a4270c1a7713a5a01b10104710190
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Sat Feb 13 10:50:48 2021 +0700

    JAMES-3400 Add remove and list domain aliases
---
 server/protocols/webadmin-cli/README.md            |  18 ++
 server/protocols/webadmin-cli/pom.xml              |   4 +
 .../java/org/apache/james/cli/WebAdminCli.java     |   5 +
 ...mainCommand.java => AddDomainAliasCommand.java} |  54 +++---
 .../org/apache/james/cli/domain/DomainCommand.java |   5 +-
 ...ainCommand.java => ListDomainAliasCommand.java} |  42 ++---
 ...nCommand.java => RemoveDomainAliasCommand.java} |  51 ++---
 .../org/apache/james/httpclient/DomainClient.java  |  39 ++++
 .../org/apache/james/cli/DomainManageTest.java     | 206 ++++++++++++++-------
 9 files changed, 283 insertions(+), 141 deletions(-)

diff --git a/server/protocols/webadmin-cli/README.md b/server/protocols/webadmin-cli/README.md
index b8b4235..0b45d48 100644
--- a/server/protocols/webadmin-cli/README.md
+++ b/server/protocols/webadmin-cli/README.md
@@ -124,6 +124,24 @@ Show all domains' name on the list.
 {cli} domain list
 ```
 
+### List domain aliases for a domain
+Show all domains' name on the list.
+```
+{cli} domain listAliases <domain>
+```
+
+### Create a domain alias for a domain
+
+```
+{cli} domain addAlias <domain> <sourceOfTheAlias>
+```
+
+### Remove a domain alias for a domain
+
+```
+{cli} domain removeAlias <domain> <sourceOfTheAlias>
+```
+
 
 
 ## Manage Users
diff --git a/server/protocols/webadmin-cli/pom.xml b/server/protocols/webadmin-cli/pom.xml
index 49ec90e..bdfe312 100644
--- a/server/protocols/webadmin-cli/pom.xml
+++ b/server/protocols/webadmin-cli/pom.xml
@@ -59,6 +59,10 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+        <dependency>
             <groupId>info.picocli</groupId>
             <artifactId>picocli</artifactId>
             <version>4.6.1</version>
diff --git a/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/WebAdminCli.java b/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/WebAdminCli.java
index 74b450c..02acc00 100644
--- a/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/WebAdminCli.java
+++ b/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/WebAdminCli.java
@@ -20,6 +20,7 @@
 package org.apache.james.cli;
 
 import java.io.PrintStream;
+import java.util.Collection;
 import java.util.Optional;
 import java.util.concurrent.Callable;
 
@@ -84,6 +85,10 @@ public class WebAdminCli implements Callable<Integer> {
         return execute(out, err, args);
     }
 
+    public static int executeFluent(PrintStream out, PrintStream err, Collection<String> args) {
+        return execute(out, err, args.stream().toArray(String[]::new));
+    }
+
     public Feign.Builder feignClientFactory(PrintStream err) {
         return new FeignClientFactory(new JwtToken(Optional.ofNullable(jwt),
             Optional.ofNullable(jwtFilePath), err))
diff --git a/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/DomainCommand.java b/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/AddDomainAliasCommand.java
similarity index 54%
copy from server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/DomainCommand.java
copy to server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/AddDomainAliasCommand.java
index ec38083..d669dfd 100644
--- a/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/DomainCommand.java
+++ b/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/AddDomainAliasCommand.java
@@ -19,42 +19,46 @@
 
 package org.apache.james.cli.domain;
 
-import java.io.PrintStream;
+import java.nio.charset.StandardCharsets;
 import java.util.concurrent.Callable;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.james.cli.WebAdminCli;
 import org.apache.james.httpclient.DomainClient;
 
+import feign.Response;
 import picocli.CommandLine;
 
 @CommandLine.Command(
-        name = "domain",
-        description = "Manage Domains",
-        subcommands = {
-            DomainListCommand.class,
-            DomainCreateCommand.class,
-            DomainDeleteCommand.class,
-            DomainExistCommand.class
-        })
-public class DomainCommand implements Callable<Integer> {
-
-    protected final WebAdminCli webAdminCli;
-    protected final PrintStream out;
-    protected final PrintStream err;
-
-    public DomainCommand(PrintStream out, WebAdminCli webAdminCli, PrintStream err) {
-        this.out = out;
-        this.webAdminCli = webAdminCli;
-        this.err = err;
-    }
+    name = "addAlias",
+    description = "Create a new domain alias")
+public class AddDomainAliasCommand implements Callable<Integer> {
+
+    public static final int CREATED_CODE = 204;
+
+    @CommandLine.ParentCommand DomainCommand domainCommand;
+
+    @CommandLine.Parameters(description = "Destination of the domain alias. This is the domain this alias belongs to.")
+    String destinationDomain;
+
+    @CommandLine.Parameters(description = "Source of the domain alias.")
+    String sourceDomain;
 
     @Override
     public Integer call() {
-        return WebAdminCli.CLI_FINISHED_SUCCEED;
-    }
-
-    public DomainClient fullyQualifiedURL(String partOfUrl) {
-        return webAdminCli.feignClientFactory(err).target(DomainClient.class, webAdminCli.jamesUrl + partOfUrl);
+        try {
+            DomainClient domainClient = domainCommand.fullyQualifiedURL("/domains");
+            Response rs = domainClient.addADomainAlias(destinationDomain, sourceDomain);
+            if (rs.status() == CREATED_CODE) {
+                return WebAdminCli.CLI_FINISHED_SUCCEED;
+            } else {
+                domainCommand.err.println(IOUtils.toString(rs.body().asInputStream(), StandardCharsets.UTF_8));
+                return WebAdminCli.CLI_FINISHED_FAILED;
+            }
+        } catch (Exception e) {
+            e.printStackTrace(domainCommand.err);
+            return WebAdminCli.CLI_FINISHED_FAILED;
+        }
     }
 
 }
\ No newline at end of file
diff --git a/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/DomainCommand.java b/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/DomainCommand.java
index ec38083..1036ec5 100644
--- a/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/DomainCommand.java
+++ b/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/DomainCommand.java
@@ -34,7 +34,10 @@ import picocli.CommandLine;
             DomainListCommand.class,
             DomainCreateCommand.class,
             DomainDeleteCommand.class,
-            DomainExistCommand.class
+            DomainExistCommand.class,
+            AddDomainAliasCommand.class,
+            ListDomainAliasCommand.class,
+            RemoveDomainAliasCommand.class
         })
 public class DomainCommand implements Callable<Integer> {
 
diff --git a/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/DomainCommand.java b/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/ListDomainAliasCommand.java
similarity index 63%
copy from server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/DomainCommand.java
copy to server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/ListDomainAliasCommand.java
index ec38083..79b6006 100644
--- a/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/DomainCommand.java
+++ b/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/ListDomainAliasCommand.java
@@ -19,7 +19,6 @@
 
 package org.apache.james.cli.domain;
 
-import java.io.PrintStream;
 import java.util.concurrent.Callable;
 
 import org.apache.james.cli.WebAdminCli;
@@ -28,33 +27,26 @@ import org.apache.james.httpclient.DomainClient;
 import picocli.CommandLine;
 
 @CommandLine.Command(
-        name = "domain",
-        description = "Manage Domains",
-        subcommands = {
-            DomainListCommand.class,
-            DomainCreateCommand.class,
-            DomainDeleteCommand.class,
-            DomainExistCommand.class
-        })
-public class DomainCommand implements Callable<Integer> {
+    name = "listAliases",
+    description = "List domain aliases for a given domain")
+public class ListDomainAliasCommand implements Callable<Integer> {
+    @CommandLine.ParentCommand DomainCommand domainCommand;
 
-    protected final WebAdminCli webAdminCli;
-    protected final PrintStream out;
-    protected final PrintStream err;
-
-    public DomainCommand(PrintStream out, WebAdminCli webAdminCli, PrintStream err) {
-        this.out = out;
-        this.webAdminCli = webAdminCli;
-        this.err = err;
-    }
+    @CommandLine.Parameters
+    String domainName;
 
     @Override
     public Integer call() {
-        return WebAdminCli.CLI_FINISHED_SUCCEED;
+        try {
+            DomainClient domainClient = domainCommand.fullyQualifiedURL("/domains");
+            domainClient.getDomainAliasList(domainName)
+                .stream()
+                .map(DomainClient.DomainAliasResponse::getSource)
+                .forEach(domainCommand.out::println);
+            return WebAdminCli.CLI_FINISHED_SUCCEED;
+        } catch (Exception e) {
+            e.printStackTrace(domainCommand.err);
+            return WebAdminCli.CLI_FINISHED_FAILED;
+        }
     }
-
-    public DomainClient fullyQualifiedURL(String partOfUrl) {
-        return webAdminCli.feignClientFactory(err).target(DomainClient.class, webAdminCli.jamesUrl + partOfUrl);
-    }
-
 }
\ No newline at end of file
diff --git a/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/DomainCommand.java b/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/RemoveDomainAliasCommand.java
similarity index 58%
copy from server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/DomainCommand.java
copy to server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/RemoveDomainAliasCommand.java
index ec38083..5e715d3 100644
--- a/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/DomainCommand.java
+++ b/server/protocols/webadmin-cli/src/main/java/org/apache/james/cli/domain/RemoveDomainAliasCommand.java
@@ -19,42 +19,43 @@
 
 package org.apache.james.cli.domain;
 
-import java.io.PrintStream;
 import java.util.concurrent.Callable;
 
 import org.apache.james.cli.WebAdminCli;
 import org.apache.james.httpclient.DomainClient;
 
+import feign.Response;
 import picocli.CommandLine;
 
 @CommandLine.Command(
-        name = "domain",
-        description = "Manage Domains",
-        subcommands = {
-            DomainListCommand.class,
-            DomainCreateCommand.class,
-            DomainDeleteCommand.class,
-            DomainExistCommand.class
-        })
-public class DomainCommand implements Callable<Integer> {
-
-    protected final WebAdminCli webAdminCli;
-    protected final PrintStream out;
-    protected final PrintStream err;
-
-    public DomainCommand(PrintStream out, WebAdminCli webAdminCli, PrintStream err) {
-        this.out = out;
-        this.webAdminCli = webAdminCli;
-        this.err = err;
-    }
+    name = "removeAlias",
+    description = "Remove a domain alias")
+public class RemoveDomainAliasCommand implements Callable<Integer> {
+
+    public static final int CREATED_CODE = 204;
+
+    @CommandLine.ParentCommand DomainCommand domainCommand;
+
+    @CommandLine.Parameters(description = "Destination of the domain alias. This is the domain this alias belongs to.")
+    String destinationDomain;
+
+    @CommandLine.Parameters(description = "Source of the domain alias.")
+    String sourceDomain;
 
     @Override
     public Integer call() {
-        return WebAdminCli.CLI_FINISHED_SUCCEED;
-    }
-
-    public DomainClient fullyQualifiedURL(String partOfUrl) {
-        return webAdminCli.feignClientFactory(err).target(DomainClient.class, webAdminCli.jamesUrl + partOfUrl);
+        try {
+            DomainClient domainClient = domainCommand.fullyQualifiedURL("/domains");
+            Response rs = domainClient.deleteADomainAlias(destinationDomain, sourceDomain);
+            if (rs.status() == CREATED_CODE) {
+                return WebAdminCli.CLI_FINISHED_SUCCEED;
+            } else {
+                return WebAdminCli.CLI_FINISHED_FAILED;
+            }
+        } catch (Exception e) {
+            e.printStackTrace(domainCommand.err);
+            return WebAdminCli.CLI_FINISHED_FAILED;
+        }
     }
 
 }
\ No newline at end of file
diff --git a/server/protocols/webadmin-cli/src/main/java/org/apache/james/httpclient/DomainClient.java b/server/protocols/webadmin-cli/src/main/java/org/apache/james/httpclient/DomainClient.java
index d195b79..a67746d 100644
--- a/server/protocols/webadmin-cli/src/main/java/org/apache/james/httpclient/DomainClient.java
+++ b/server/protocols/webadmin-cli/src/main/java/org/apache/james/httpclient/DomainClient.java
@@ -20,12 +20,43 @@
 package org.apache.james.httpclient;
 
 import java.util.List;
+import java.util.Objects;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
 
 import feign.Param;
 import feign.RequestLine;
 import feign.Response;
 
 public interface DomainClient {
+    class DomainAliasResponse {
+        private final String source;
+
+        @JsonCreator
+        public DomainAliasResponse(@JsonProperty("source") String source) {
+            this.source = source;
+        }
+
+        public String getSource() {
+            return source;
+        }
+
+        @Override
+        public final boolean equals(Object o) {
+            if (o instanceof DomainAliasResponse) {
+                DomainAliasResponse that = (DomainAliasResponse) o;
+
+                return Objects.equals(this.source, that.source);
+            }
+            return false;
+        }
+
+        @Override
+        public final int hashCode() {
+            return Objects.hash(source);
+        }
+    }
 
     @RequestLine("GET")
     List<String> getDomainList();
@@ -39,4 +70,12 @@ public interface DomainClient {
     @RequestLine("GET /{domainName}")
     Response doesExist(@Param("domainName") String domainName);
 
+    @RequestLine("DELETE /{destinationDomain}/aliases/{sourceDomain}")
+    Response deleteADomainAlias(@Param("destinationDomain") String destinationDomain, @Param("sourceDomain") String sourceDomain);
+
+    @RequestLine("PUT /{destinationDomain}/aliases/{sourceDomain}")
+    Response addADomainAlias(@Param("destinationDomain") String destinationDomain, @Param("sourceDomain") String sourceDomain);
+
+    @RequestLine("GET /{domainName}/aliases")
+    List<DomainAliasResponse> getDomainAliasList(@Param("domainName") String domainName);
 }
diff --git a/server/protocols/webadmin-cli/src/test/java/org/apache/james/cli/DomainManageTest.java b/server/protocols/webadmin-cli/src/test/java/org/apache/james/cli/DomainManageTest.java
index a219812..ea56084 100644
--- a/server/protocols/webadmin-cli/src/test/java/org/apache/james/cli/DomainManageTest.java
+++ b/server/protocols/webadmin-cli/src/test/java/org/apache/james/cli/DomainManageTest.java
@@ -24,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
+import java.nio.charset.StandardCharsets;
 
 import org.apache.james.GuiceJamesServer;
 import org.apache.james.JamesServerBuilder;
@@ -32,11 +33,16 @@ import org.apache.james.modules.TestJMAPServerModule;
 import org.apache.james.util.Port;
 import org.apache.james.utils.WebAdminGuiceProbe;
 import org.apache.james.webadmin.integration.WebadminIntegrationTestModule;
+import org.assertj.core.api.SoftAssertions;
+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.junit.jupiter.api.extension.RegisterExtension;
 
-public class DomainManageTest {
+import com.google.common.collect.ImmutableList;
 
+class DomainManageTest {
     @RegisterExtension
     static JamesServerExtension testExtension = new JamesServerBuilder<>(JamesServerBuilder.defaultConfigurationProvider())
             .server(configuration -> GuiceJamesServer.forConfiguration(configuration)
@@ -48,113 +54,183 @@ public class DomainManageTest {
     private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream();
     private final ByteArrayOutputStream errorStreamCaptor = new ByteArrayOutputStream();
 
-    @Test
-    void domainListCommandShouldWShowOnlyDefaultDomain(GuiceJamesServer server) {
-        Port port = server.getProbe(WebAdminGuiceProbe.class).getWebAdminPort();
+    Port port;
 
-        int exitCode = WebAdminCli.executeFluent(new PrintStream(outputStreamCaptor), new PrintStream(errorStreamCaptor),
-                "--url", "http://127.0.0.1:" + port.getValue(), "domain", "list");
-        assertThat(exitCode).isEqualTo(0);
-        assertThat(outputStreamCaptor.toString().trim().toCharArray()).containsOnly("localhost".toCharArray());
+    @BeforeEach
+    void setUp(GuiceJamesServer server) {
+        port = server.getProbe(WebAdminGuiceProbe.class).getWebAdminPort();
+    }
+
+    @AfterEach
+    void tearDown() {
+        System.err.println(new String(errorStreamCaptor.toByteArray(), StandardCharsets.UTF_8));
     }
 
     @Test
-    void domainCreateCommandWithValidNameShouldSuccessfully(GuiceJamesServer server) {
-        Port port = server.getProbe(WebAdminGuiceProbe.class).getWebAdminPort();
+    void domainListCommandShouldWShowOnlyDefaultDomain() {
+        int exitCode = executeFluent("domain", "list");
 
-        int exitCode = WebAdminCli.executeFluent(new PrintStream(outputStreamCaptor), new PrintStream(errorStreamCaptor),
-            "--url", "http://127.0.0.1:" + port.getValue(), "domain", "create", "linagora.com");
+        SoftAssertions.assertSoftly( softly -> {
+            assertThat(exitCode).isEqualTo(0);
+            assertThat(outputStreamCaptor.toString().trim().toCharArray()).containsOnly("localhost".toCharArray());
+        });
+    }
 
-        WebAdminCli.executeFluent(new PrintStream(outputStreamCaptor), new PrintStream(errorStreamCaptor),
-            "--url", "http://127.0.0.1:" + port.getValue(), "domain", "list");
+    @Test
+    void domainCreateCommandWithValidNameShouldSuccessfully() {
+        int exitCode = executeFluent("domain", "create", "linagora.com");
 
-        assertThat(exitCode).isEqualTo(0);
-        assertThat(outputStreamCaptor.toString()).contains("linagora.com");
+        executeFluent("domain", "list");
+
+        SoftAssertions.assertSoftly( softly -> {
+            assertThat(exitCode).isEqualTo(0);
+            assertThat(outputStreamCaptor.toString()).contains("linagora.com");
+        });
     }
 
     @Test
-    void domainCreateCommandWithInvalidNameShouldFailed(GuiceJamesServer server) {
-        Port port = server.getProbe(WebAdminGuiceProbe.class).getWebAdminPort();
-
-        int exitCode1 = WebAdminCli.executeFluent(new PrintStream(outputStreamCaptor), new PrintStream(errorStreamCaptor),
-            "--url", "http://127.0.0.1:" + port.getValue(), "domain", "create", "@linagora.com");
+    void domainCreateCommandWithInvalidNameShouldFailed() {
+        int exitCode1 = executeFluent("domain", "create", "@linagora.com");
 
-        int exitCode2 = WebAdminCli.executeFluent(new PrintStream(outputStreamCaptor), new PrintStream(errorStreamCaptor),
-            "--url", "http://127.0.0.1:" + port.getValue(), "domain", "create", "linagora.com/");
+        int exitCode2 = executeFluent("domain", "create", "linagora.com/");
 
-        int exitCode3 = WebAdminCli.executeFluent(new PrintStream(outputStreamCaptor), new PrintStream(errorStreamCaptor),
-            "--url", "http://127.0.0.1:" + port.getValue(), "domain", "create", "");
+        int exitCode3 = executeFluent("domain", "create", "");
 
         WebAdminCli.executeFluent(new PrintStream(outputStreamCaptor), new PrintStream(errorStreamCaptor),
             "--url", "http://127.0.0.1:" + port.getValue(), "domain", "list");
 
-        assertThat(exitCode1).isEqualTo(1);
-        assertThat(exitCode2).isEqualTo(1);
-        assertThat(exitCode3).isEqualTo(1);
-        assertThat(outputStreamCaptor.toString().trim().toCharArray()).containsOnly("localhost".toCharArray());
+        SoftAssertions.assertSoftly( softly -> {
+            assertThat(exitCode1).isEqualTo(1);
+            assertThat(exitCode2).isEqualTo(1);
+            assertThat(exitCode3).isEqualTo(1);
+            assertThat(outputStreamCaptor.toString().trim().toCharArray()).containsOnly("localhost".toCharArray());
+        });
     }
 
     @Test
-    void domainDeleteCommandWithValidDomainShouldSucceed(GuiceJamesServer server) {
-        Port port = server.getProbe(WebAdminGuiceProbe.class).getWebAdminPort();
-
-        WebAdminCli.executeFluent(new PrintStream(outputStreamCaptor), new PrintStream(errorStreamCaptor),
-            "--url", "http://127.0.0.1:" + port.getValue(), "domain", "create", "linagora.com");
+    void domainDeleteCommandWithValidDomainShouldSucceed() {
+        executeFluent("domain", "create", "linagora.com");
 
-        int exitCode = WebAdminCli.executeFluent(new PrintStream(outputStreamCaptor), new PrintStream(errorStreamCaptor),
-            "--url", "http://127.0.0.1:" + port.getValue(), "domain", "delete", "linagora.com");
+        int exitCode = executeFluent("domain", "delete", "linagora.com");
 
-        WebAdminCli.executeFluent(new PrintStream(outputStreamCaptor), new PrintStream(errorStreamCaptor),
-            "--url", "http://127.0.0.1:" + port.getValue(), "domain", "list");
+        executeFluent("domain", "list");
 
-        assertThat(exitCode).isEqualTo(0);
-        assertThat(outputStreamCaptor.toString().contains("linagora.com")).isFalse();
+        SoftAssertions.assertSoftly( softly -> {
+            assertThat(exitCode).isEqualTo(0);
+            assertThat(outputStreamCaptor.toString().contains("linagora.com")).isFalse();
+        });
     }
 
     @Test
-    void domainDeleteCommandWithDefaultDomainShouldFail(GuiceJamesServer server) {
-        Port port = server.getProbe(WebAdminGuiceProbe.class).getWebAdminPort();
-
-        int exitCode = WebAdminCli.executeFluent(new PrintStream(outputStreamCaptor), new PrintStream(errorStreamCaptor),
-            "--url", "http://127.0.0.1:" + port.getValue(), "domain", "delete", "localhost");
+    void domainDeleteCommandWithDefaultDomainShouldFail() {
+        int exitCode = executeFluent("domain", "delete", "localhost");
 
         assertThat(exitCode).isEqualTo(1);
     }
 
     @Test
-    void domainExistCommandWithDefaultDomainShouldExist(GuiceJamesServer server) {
-        Port port = server.getProbe(WebAdminGuiceProbe.class).getWebAdminPort();
-
-        int exitCode = WebAdminCli.executeFluent(new PrintStream(outputStreamCaptor), new PrintStream(errorStreamCaptor),
-            "--url", "http://127.0.0.1:" + port.getValue(), "domain", "exist", "localhost");
+    void domainExistCommandWithDefaultDomainShouldExist() {
+        int exitCode = executeFluent("domain", "exist", "localhost");
 
-        assertThat(exitCode).isEqualTo(0);
-        assertThat(outputStreamCaptor.toString().trim()).isEqualTo("localhost exists");
+        SoftAssertions.assertSoftly( softly -> {
+            assertThat(exitCode).isEqualTo(0);
+            assertThat(outputStreamCaptor.toString().trim()).isEqualTo("localhost exists");
+        });
     }
 
     @Test
-    void domainExistCommandWithNonExistingDomainShouldFail(GuiceJamesServer server) {
-        Port port = server.getProbe(WebAdminGuiceProbe.class).getWebAdminPort();
-
-        int exitCode = WebAdminCli.executeFluent(new PrintStream(outputStreamCaptor), new PrintStream(errorStreamCaptor),
-            "--url", "http://127.0.0.1:" + port.getValue(), "domain", "exist", "linagora.com");
+    void domainExistCommandWithNonExistingDomainShouldFail() {
+        int exitCode = executeFluent("domain", "exist", "linagora.com");
 
         assertThat(exitCode).isEqualTo(0);
         assertThat(outputStreamCaptor.toString().trim()).isEqualTo("linagora.com does not exist");
     }
 
     @Test
-    void domainExistCommandWithAddedDomainShouldSucceed(GuiceJamesServer server) {
-        Port port = server.getProbe(WebAdminGuiceProbe.class).getWebAdminPort();
+    void domainExistCommandWithAddedDomainShouldSucceed() {
+        executeFluent("domain", "create", "linagora.com");
 
-        WebAdminCli.executeFluent(new PrintStream(outputStreamCaptor), new PrintStream(errorStreamCaptor),
-            "--url", "http://127.0.0.1:" + port.getValue(), "domain", "create", "linagora.com");
+        int exitCode = executeFluent("domain", "exist", "linagora.com");
 
-        int exitCode = WebAdminCli.executeFluent(new PrintStream(outputStreamCaptor), new PrintStream(errorStreamCaptor),
-            "--url", "http://127.0.0.1:" + port.getValue(), "domain", "exist", "linagora.com");
+        SoftAssertions.assertSoftly( softly -> {
+            assertThat(exitCode).isEqualTo(0);
+            assertThat(outputStreamCaptor.toString().trim()).isEqualTo("linagora.com exists");
+        });
+    }
 
-        assertThat(exitCode).isEqualTo(0);
-        assertThat(outputStreamCaptor.toString().trim()).isEqualTo("linagora.com exists");
+    @Nested
+    class DomainAliases {
+        @BeforeEach
+        void setUp() {
+            executeFluent("domain", "create", "linagora.com");
+            executeFluent("domain", "create", "linagora-james.com");
+        }
+
+        @Test
+        void listDomainAliasShouldReturnEmptyByDefault() {
+            int exitCode = executeFluent("domain", "listAliases", "linagora.com");
+
+            SoftAssertions.assertSoftly( softly -> {
+                assertThat(exitCode).isEqualTo(0);
+                assertThat(outputStreamCaptor.toString().trim()).hasSize(0);
+            });
+        }
+
+        @Test
+        void addDomainAliasShouldBeIdempotent() {
+            executeFluent("domain", "addAlias", "linagora.com", "linagora-james.com");
+            int exitCode = executeFluent("domain", "addAlias", "linagora.com", "linagora-james.com");
+
+            assertThat(exitCode).isEqualTo(0);
+        }
+
+        @Test
+        void removeDomainAliasShouldBeIdempotent() {
+            int exitCode = executeFluent("domain", "removeAlias", "linagora.com", "linagora-james.com");
+
+            assertThat(exitCode).isEqualTo(0);
+        }
+
+        @Test
+        void listDomainAliasShouldNotReturnRemovedValues() {
+            executeFluent("domain", "addAlias", "linagora.com", "linagora-james.com");
+            executeFluent("domain", "removeAlias", "linagora.com", "linagora-james.com");
+
+            int exitCode = executeFluent("domain", "listAliases", "linagora.com");
+
+            SoftAssertions.assertSoftly( softly -> {
+                assertThat(exitCode).isEqualTo(0);
+                assertThat(outputStreamCaptor.toString().trim()).hasSize(0);
+            });
+        }
+
+        @Test
+        void listDomainAliasShouldReturnAddedValues() {
+            executeFluent("domain", "addAlias", "linagora.com", "linagora-james.com");
+
+            int exitCode = executeFluent("domain", "listAliases", "linagora.com");
+
+            SoftAssertions.assertSoftly( softly -> {
+                assertThat(exitCode).isEqualTo(0);
+                assertThat(outputStreamCaptor.toString().trim()).contains("linagora-james.com");
+            });
+        }
+
+        @Test
+        void addAliasShouldRequireAManageDomain() {
+            int exitCode = executeFluent("domain", "addAlias", "linagora.com", "unknown.com");
+
+            SoftAssertions.assertSoftly( softly -> {
+                assertThat(exitCode).isEqualTo(1);
+                assertThat(errorStreamCaptor.toString().trim()).isEqualTo("{\"statusCode\":404,\"type\":\"InvalidArgument\",\"message\":\"The domain list does not contain: unknown.com\",\"details\":null}");
+            });
+        }
     }
 
+    private int executeFluent(String... args) {
+        return WebAdminCli.executeFluent(new PrintStream(outputStreamCaptor), new PrintStream(errorStreamCaptor),
+            ImmutableList.<String>builder().add("--url", "http://127.0.0.1:" + port.getValue())
+                .addAll(ImmutableList.copyOf(args))
+                .build());
+    }
 }


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