You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2019/07/31 06:40:13 UTC

[james-project] 02/04: JAMES-2818 MappingRoutes implementation

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 b665dde8d01bbc6c9c6b085dbc0ff6518ff37a14
Author: Khanh Le <bk...@linagora.com>
AuthorDate: Tue Jul 23 15:37:08 2019 +0700

    JAMES-2818 MappingRoutes implementation
---
 .../apache/james/webadmin/dto/MappingValueDTO.java |  46 +++
 .../james/webadmin/routes/MappingRoutes.java       | 101 +++++
 .../james/webadmin/routes/MappingRoutesTest.java   | 417 +++++++++++++++++++++
 3 files changed, 564 insertions(+)

diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/MappingValueDTO.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/MappingValueDTO.java
new file mode 100644
index 0000000..ea75c26
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/MappingValueDTO.java
@@ -0,0 +1,46 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.webadmin.dto;
+
+import org.apache.james.rrt.lib.Mapping;
+
+public class MappingValueDTO {
+
+    public static MappingValueDTO fromMapping(Mapping mapping) {
+        return new MappingValueDTO(mapping.getType().toString(), mapping.getMappingValue());
+    }
+
+    private final String type;
+    private final String mapping;
+
+    private MappingValueDTO(String type, String mapping) {
+        this.type = type;
+        this.mapping = mapping;
+    }
+    
+    public String getType() {
+        return type;
+    }
+
+    public String getMapping() {
+        return mapping;
+    }
+
+}
\ No newline at end of file
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/MappingRoutes.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/MappingRoutes.java
new file mode 100644
index 0000000..cec9caf
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/MappingRoutes.java
@@ -0,0 +1,101 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.webadmin.routes;
+
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.james.rrt.api.RecipientRewriteTable;
+import org.apache.james.rrt.api.RecipientRewriteTableException;
+import org.apache.james.webadmin.Constants;
+import org.apache.james.webadmin.Routes;
+import org.apache.james.webadmin.dto.MappingValueDTO;
+import org.apache.james.webadmin.utils.ErrorResponder;
+import org.apache.james.webadmin.utils.JsonTransformer;
+import org.eclipse.jetty.http.HttpStatus;
+
+import com.github.steveash.guavate.Guavate;
+import com.google.common.collect.ImmutableListMultimap;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import spark.Request;
+import spark.Response;
+import spark.Service;
+
+@Api(tags = "Mappings")
+@Path(MappingRoutes.BASE_PATH)
+@Produces(Constants.JSON_CONTENT_TYPE)
+public class MappingRoutes implements Routes {
+
+    static final String BASE_PATH = "/mappings";
+
+    private final JsonTransformer jsonTransformer;
+    private final RecipientRewriteTable recipientRewriteTable;
+
+    @Inject
+    MappingRoutes(JsonTransformer jsonTransformer, RecipientRewriteTable recipientRewriteTable) {
+        this.jsonTransformer = jsonTransformer;
+        this.recipientRewriteTable = recipientRewriteTable;
+    }
+
+    @Override
+    public String getBasePath() {
+        return BASE_PATH;
+    }
+
+    @Override
+    public void define(Service service) {
+        service.get(BASE_PATH, this::getMappings, jsonTransformer);
+    }
+
+    @GET
+    @Path(BASE_PATH)
+    @ApiOperation(value = "getting all mappings in RecipientRewriteTable")
+    @ApiResponses(value = {
+        @ApiResponse(code = HttpStatus.OK_200, message = "OK", response = List.class)
+    })
+    private ImmutableListMultimap<String, MappingValueDTO> getMappings(Request request, Response response) {
+        try {
+            return recipientRewriteTable.getAllMappings()
+                .entrySet()
+                .stream()
+                .flatMap(entry -> entry.getValue().asStream()
+                    .map(mapping -> Pair.of(
+                        entry.getKey().asString(),
+                        MappingValueDTO.fromMapping(mapping))))
+                .collect(Guavate.toImmutableListMultimap(Pair::getLeft, Pair::getRight));
+        } catch (RecipientRewriteTableException e) {
+            throw ErrorResponder.builder()
+                .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500)
+                .type(ErrorResponder.ErrorType.SERVER_ERROR)
+                .message(e.getMessage())
+                .haltError();
+        }
+    }
+}
+
diff --git a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/MappingRoutesTest.java b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/MappingRoutesTest.java
new file mode 100644
index 0000000..0d1e967
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/MappingRoutesTest.java
@@ -0,0 +1,417 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.webadmin.routes;
+
+import static io.restassured.RestAssured.when;
+import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
+import static org.hamcrest.CoreMatchers.is;
+import static org.mockito.Mockito.mock;
+
+import org.apache.james.core.Domain;
+import org.apache.james.core.MailAddress;
+import org.apache.james.core.User;
+import org.apache.james.dnsservice.api.DNSService;
+import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.domainlist.api.DomainListException;
+import org.apache.james.domainlist.memory.MemoryDomainList;
+import org.apache.james.rrt.api.RecipientRewriteTableException;
+import org.apache.james.rrt.lib.MappingSource;
+import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
+import org.apache.james.webadmin.WebAdminServer;
+import org.apache.james.webadmin.WebAdminUtils;
+import org.apache.james.webadmin.utils.JsonTransformer;
+import org.eclipse.jetty.http.HttpStatus;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import io.restassured.RestAssured;
+import io.restassured.filter.log.LogDetail;
+import io.restassured.http.ContentType;
+import net.javacrumbs.jsonunit.core.Option;
+
+class MappingRoutesTest {
+
+    private WebAdminServer webAdminServer;
+    private MemoryRecipientRewriteTable recipientRewriteTable;
+
+    @BeforeEach
+    void setUp() throws DomainListException {
+        JsonTransformer jsonTransformer = new JsonTransformer();
+        recipientRewriteTable = new MemoryRecipientRewriteTable();
+        DNSService dnsService = mock(DNSService.class);
+        DomainList domainList = new MemoryDomainList(dnsService);
+        domainList.addDomain(Domain.of("domain.tld"));
+        domainList.addDomain(Domain.of("aliasdomain.tld"));
+
+        recipientRewriteTable.setDomainList(domainList);
+
+        webAdminServer = WebAdminUtils.createWebAdminServer(new MappingRoutes(jsonTransformer, recipientRewriteTable))
+            .start();
+
+        RestAssured.requestSpecification = WebAdminUtils.buildRequestSpecification(webAdminServer)
+            .setBasePath(MappingRoutes.BASE_PATH)
+            .log(LogDetail.METHOD)
+            .build();
+    }
+
+    @AfterEach
+    void stop() {
+        webAdminServer.destroy();
+    }
+
+    @Test
+    void getMappingsShouldReturnEmptyWhenNoMappings() {
+        when()
+            .get()
+        .then()
+            .contentType(ContentType.JSON)
+            .statusCode(HttpStatus.OK_200)
+            .body(is("{}"));
+    }
+
+    @Test
+    void getMappingsShouldReturnAliasMappings() throws RecipientRewriteTableException {
+        User aliasDomain = User.fromUsername("alias@domain.tld");
+
+        recipientRewriteTable.addAliasMapping(
+            MappingSource.fromUser(aliasDomain),
+            "user@domain.tld");
+        recipientRewriteTable.addAliasMapping(
+            MappingSource.fromUser(aliasDomain),
+            "abc@domain.tld");
+
+        String jsonBody = when()
+                .get()
+            .then()
+                .contentType(ContentType.JSON)
+                .statusCode(HttpStatus.OK_200)
+            .extract()
+                .body()
+                .asString();
+
+        assertThatJson(jsonBody)
+            .when(Option.IGNORING_ARRAY_ORDER)
+            .isEqualTo("{" +
+                "  \"alias@domain.tld\" : [" +
+                "    {" +
+                "      \"type\": \"Alias\"," +
+                "      \"mapping\": \"user@domain.tld\"" +
+                "    }," +
+                "    {" +
+                "      \"type\": \"Alias\"," +
+                "      \"mapping\" : \"abc@domain.tld\"" +
+                "    }" +
+                "  ]" +
+                "}");
+    }
+
+    @Test
+    void getMappingsShouldReturnAliasDomainMappings() throws RecipientRewriteTableException {
+        Domain domain = Domain.of("aliasdomain.tld");
+
+        recipientRewriteTable.addAliasDomainMapping(
+            MappingSource.fromDomain(domain),
+            Domain.of("domain1abc.tld"));
+        recipientRewriteTable.addAliasDomainMapping(
+            MappingSource.fromDomain(domain),
+            Domain.of("domain2cde.tld"));
+
+        String jsonBody = when()
+                .get()
+            .then()
+                .contentType(ContentType.JSON)
+                .statusCode(HttpStatus.OK_200)
+            .extract()
+                .body()
+                .asString();
+
+        assertThatJson(jsonBody)
+            .when(Option.IGNORING_ARRAY_ORDER)
+            .isEqualTo("{" +
+                "  \"aliasdomain.tld\" : [" +
+                "    {" +
+                "      \"type\": \"Domain\"," +
+                "      \"mapping\": \"domain1abc.tld\"" +
+                "    }," +
+                "    {" +
+                "      \"type\": \"Domain\"," +
+                "      \"mapping\" : \"domain2cde.tld\"" +
+                "    }" +
+                "  ]" +
+                "}");
+    }
+
+    @Test
+    void getMappingsShouldReturnAddressMappings() throws Exception {
+        MailAddress mailAddress = new MailAddress("group@domain.tld");
+
+        recipientRewriteTable.addAddressMapping(
+            MappingSource.fromMailAddress(mailAddress), "user123@domain.tld");
+        recipientRewriteTable.addAddressMapping(
+            MappingSource.fromMailAddress(mailAddress), "user789@domain.tld");
+
+        String jsonBody = when()
+                .get()
+            .then()
+                .contentType(ContentType.JSON)
+                .statusCode(HttpStatus.OK_200)
+            .extract()
+                .body()
+                .asString();
+
+        assertThatJson(jsonBody)
+            .when(Option.IGNORING_ARRAY_ORDER)
+            .isEqualTo("{" +
+                "  \"group@domain.tld\" : [" +
+                "    {" +
+                "      \"type\": \"Address\"," +
+                "      \"mapping\": \"user123@domain.tld\"" +
+                "    }," +
+                "    {" +
+                "      \"type\": \"Address\"," +
+                "      \"mapping\" : \"user789@domain.tld\"" +
+                "    }" +
+                "  ]" +
+                "}");
+    }
+
+    @Test
+    void getMappingsShouldReturnGroupMappings() throws Exception {
+        MailAddress groupAddress = new MailAddress("group@domain.tld");
+
+        recipientRewriteTable.addGroupMapping(
+            MappingSource.fromMailAddress(groupAddress), "member1@domain.tld");
+        recipientRewriteTable.addGroupMapping(
+            MappingSource.fromMailAddress(groupAddress), "member2@domain.tld");
+
+        String jsonBody = when()
+                .get()
+            .then()
+                .contentType(ContentType.JSON)
+                .statusCode(HttpStatus.OK_200)
+            .extract()
+                .body()
+                .asString();
+
+        assertThatJson(jsonBody)
+            .when(Option.IGNORING_ARRAY_ORDER)
+            .isEqualTo("{" +
+                "  \"group@domain.tld\": [" +
+                "    {" +
+                "      \"type\": \"Group\"," +
+                "      \"mapping\": \"member1@domain.tld\"" +
+                "    }," +
+                "    {" +
+                "      \"type\": \"Group\"," +
+                "      \"mapping\": \"member2@domain.tld\"" +
+                "    }" +
+                "  ]" +
+                "}");
+    }
+
+    @Test
+    void getMappingsShouldReturnForwardMappings() throws RecipientRewriteTableException {
+        User forwardUser = User.fromUsername("forwarduser@domain.tld");
+
+        recipientRewriteTable.addForwardMapping(
+            MappingSource.fromUser(forwardUser), "person1@domain.tld");
+        recipientRewriteTable.addForwardMapping(
+            MappingSource.fromUser(forwardUser), "person2@domain.tld");
+
+        String jsonBody = when()
+                .get()
+            .then()
+                .contentType(ContentType.JSON)
+                .statusCode(HttpStatus.OK_200)
+            .extract()
+                .body()
+                .asString();
+
+        assertThatJson(jsonBody)
+            .when(Option.IGNORING_ARRAY_ORDER)
+            .isEqualTo("{" +
+                "  \"forwarduser@domain.tld\": [" +
+                "    {" +
+                "      \"type\": \"Forward\"," +
+                "      \"mapping\": \"person1@domain.tld\"" +
+                "    }," +
+                "    {" +
+                "      \"type\": \"Forward\"," +
+                "      \"mapping\": \"person2@domain.tld\"" +
+                "    }" +
+                "  ]" +
+                "}");
+    }
+
+    @Test
+    void getMappingsShouldReturnRegexMappings() throws RecipientRewriteTableException {
+        User regexUser = User.fromUsername("regex@domain.tld");
+
+        recipientRewriteTable.addRegexMapping(
+            MappingSource.fromUser(regexUser), "abc");
+        recipientRewriteTable.addRegexMapping(
+            MappingSource.fromUser(regexUser), "def");
+
+        String jsonBody = when()
+                .get()
+            .then()
+                .contentType(ContentType.JSON)
+                .statusCode(HttpStatus.OK_200)
+            .extract()
+                .body()
+                .asString();
+
+        assertThatJson(jsonBody)
+            .when(Option.IGNORING_ARRAY_ORDER)
+            .isEqualTo("{" +
+                "  \"regex@domain.tld\": [" +
+                "    {" +
+                "      \"type\": \"Regex\"," +
+                "      \"mapping\": \"abc\"" +
+                "    }," +
+                "    {" +
+                "      \"type\": \"Regex\"," +
+                "      \"mapping\": \"def\"" +
+                "    }" +
+                "  ]" +
+                "}");
+    }
+
+    @Test
+    void getMappingsShouldReturnErrorMappings() throws RecipientRewriteTableException {
+        User errorUser = User.fromUsername("error@domain.tld");
+
+        recipientRewriteTable.addErrorMapping(
+            MappingSource.fromUser(errorUser), "Error 123");
+        recipientRewriteTable.addErrorMapping(
+            MappingSource.fromUser(errorUser), "Error 456");
+
+        String jsonBody = when()
+                .get()
+            .then()
+                .contentType(ContentType.JSON)
+                .statusCode(HttpStatus.OK_200)
+            .extract()
+                .body()
+                .asString();
+
+        assertThatJson(jsonBody)
+            .when(Option.IGNORING_ARRAY_ORDER)
+            .isEqualTo("{" +
+                "  \"error@domain.tld\": [" +
+                "    {" +
+                "      \"type\": \"Error\"," +
+                "      \"mapping\": \"Error 123\"" +
+                "    }," +
+                "    {" +
+                "      \"type\": \"Error\"," +
+                "      \"mapping\": \"Error 456\"" +
+                "    }" +
+                "  ]" +
+                "}");
+    }
+
+    @Test
+    void getMappingsShouldReturnAllMappings() throws Exception {
+        MailAddress mailAddress = new MailAddress("address@domain.tld");
+
+        recipientRewriteTable.addAliasMapping(
+            MappingSource.fromUser(User.fromUsername("alias@domain.tld")),
+            "user@domain.tld");
+
+        recipientRewriteTable.addAliasDomainMapping(
+            MappingSource.fromDomain(Domain.of("aliasdomain.tld")),
+            Domain.of("realdomain.tld"));
+
+        recipientRewriteTable.addAddressMapping(
+            MappingSource.fromMailAddress(mailAddress), "user@domain.tld");
+
+        recipientRewriteTable.addGroupMapping(
+            MappingSource.fromUser(User.fromUsername("group@domain.tld")),
+                "member1@domain.tld");
+
+        recipientRewriteTable.addForwardMapping(
+            MappingSource.fromUser(User.fromUsername("forward@domain.tld")),
+                "abc@domain.tld");
+
+        recipientRewriteTable.addRegexMapping(
+            MappingSource.fromUser(User.fromUsername("regex@domain.tld")), "abc");
+
+        recipientRewriteTable.addErrorMapping(
+            MappingSource.fromUser(User.fromUsername("error@domain.tld")), "Error 456");
+
+        String jsonBody = when()
+                .get()
+            .then()
+                .contentType(ContentType.JSON)
+                .statusCode(HttpStatus.OK_200)
+            .extract()
+                .body()
+                .asString();
+
+        assertThatJson(jsonBody)
+            .isEqualTo("{" +
+                "  \"alias@domain.tld\": [" +
+                "    {" +
+                "      \"type\": \"Alias\"," +
+                "      \"mapping\": \"user@domain.tld\"" +
+                "    }" +
+                "  ]," +
+                "  \"aliasdomain.tld\": [" +
+                "    {" +
+                "      \"type\": \"Domain\"," +
+                "      \"mapping\": \"realdomain.tld\"" +
+                "    }" +
+                "  ]," +
+                "  \"address@domain.tld\": [" +
+                "    {" +
+                "      \"type\": \"Address\"," +
+                "      \"mapping\": \"user@domain.tld\"" +
+                "    }" +
+                "  ]," +
+                "  \"group@domain.tld\": [" +
+                "    {" +
+                "      \"type\": \"Group\"," +
+                "      \"mapping\": \"member1@domain.tld\"" +
+                "    }" +
+                "  ]," +
+                "  \"forward@domain.tld\": [" +
+                "    {" +
+                "      \"type\": \"Forward\"," +
+                "      \"mapping\": \"abc@domain.tld\"" +
+                "    }" +
+                "  ]," +
+                "  \"regex@domain.tld\": [" +
+                "    {" +
+                "      \"type\": \"Regex\"," +
+                "      \"mapping\": \"abc\"" +
+                "    }" +
+                "  ]," +
+                "  \"error@domain.tld\": [" +
+                "    {" +
+                "      \"type\": \"Error\"," +
+                "      \"mapping\": \"Error 456\"" +
+                "    }" +
+                "  ]" +
+                "}"
+            );
+    }
+}
\ No newline at end of file


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