Repository: james-project
Updated Branches:
  refs/heads/master 23d22a0e9 -> 536f3caab


JAMES-2428 [DLP] Web admin endpoint to update DLP configuration


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

Branch: refs/heads/master
Commit: dec6e89024f78f3ddbe7e24157d9f7d991381d54
Parents: 23d22a0
Author: duc <[email protected]>
Authored: Thu Jun 14 15:49:47 2018 +0700
Committer: duc <[email protected]>
Committed: Tue Jun 19 16:59:52 2018 +0700

----------------------------------------------------------------------
 .../james/modules/server/DataRoutesModules.java |   2 +
 .../james/webadmin/utils/JsonExtractor.java     |   1 +
 server/protocols/webadmin/webadmin-data/pom.xml |  19 +
 .../org/apache/james/webadmin/DLPModule.java    |  36 ++
 .../james/webadmin/dto/DLPConfigurationDTO.java |  64 +++
 .../webadmin/dto/DLPConfigurationItemDTO.java   | 127 +++++
 .../webadmin/routes/DLPConfigurationRoutes.java | 217 +++++++
 .../dto/DLPConfigurationItemDTOTest.java        | 105 ++++
 .../routes/DLPConfigurationRoutesTest.java      | 571 +++++++++++++++++++
 9 files changed, 1142 insertions(+)
----------------------------------------------------------------------


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

http://git-wip-us.apache.org/repos/asf/james-project/blob/dec6e890/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java
 
b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java
index 3f62d89..fcecc3d 100644
--- 
a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java
+++ 
b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java
@@ -20,6 +20,7 @@
 package org.apache.james.webadmin.utils;
 
 import java.io.IOException;
+import java.util.Collection;
 import java.util.List;
 
 import com.fasterxml.jackson.databind.Module;

http://git-wip-us.apache.org/repos/asf/james-project/blob/dec6e890/server/protocols/webadmin/webadmin-data/pom.xml
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/pom.xml 
b/server/protocols/webadmin/webadmin-data/pom.xml
index e6c876b..f4b1d20 100644
--- a/server/protocols/webadmin/webadmin-data/pom.xml
+++ b/server/protocols/webadmin/webadmin-data/pom.xml
@@ -35,6 +35,11 @@
     <dependencies>
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>event-sourcing-event-store-memory</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>james-core</artifactId>
         </dependency>
         <dependency>
@@ -67,6 +72,10 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-guava</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
         </dependency>
@@ -80,6 +89,16 @@
             <artifactId>javax.inject</artifactId>
         </dependency>
         <dependency>
+            <groupId>net.javacrumbs.json-unit</groupId>
+            <artifactId>json-unit-fluent</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>nl.jqno.equalsverifier</groupId>
+            <artifactId>equalsverifier</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.assertj</groupId>
             <artifactId>assertj-core</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/dec6e890/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/DLPModule.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/DLPModule.java
 
b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/DLPModule.java
new file mode 100644
index 0000000..0363ca3
--- /dev/null
+++ 
b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/DLPModule.java
@@ -0,0 +1,36 @@
+/****************************************************************
+ * 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;
+
+import org.apache.james.webadmin.utils.JsonTransformerModule;
+
+import com.fasterxml.jackson.databind.Module;
+import com.fasterxml.jackson.datatype.guava.GuavaModule;
+
+public class DLPModule implements JsonTransformerModule {
+
+    public DLPModule() {
+    }
+
+    @Override
+    public Module asJacksonModule() {
+        return new GuavaModule();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/dec6e890/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationDTO.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationDTO.java
 
b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationDTO.java
new file mode 100644
index 0000000..d1265a6
--- /dev/null
+++ 
b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationDTO.java
@@ -0,0 +1,64 @@
+/****************************************************************
+ * 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 java.util.List;
+
+import org.apache.james.dlp.api.DLPConfigurationItem;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.github.steveash.guavate.Guavate;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+public class DLPConfigurationDTO {
+
+    public static List<DLPConfigurationItem> 
toDLPConfigurations(DLPConfigurationDTO dto) {
+        Preconditions.checkNotNull(dto);
+
+        return dto.rules
+            .stream()
+            .map(DLPConfigurationItemDTO::toDLPConfiguration)
+            .collect(Guavate.toImmutableList());
+    }
+
+    public static DLPConfigurationDTO toDTO(List<DLPConfigurationItem> 
dlpConfigurations) {
+        Preconditions.checkNotNull(dlpConfigurations);
+
+        return new DLPConfigurationDTO(
+            dlpConfigurations
+                .stream()
+                .map(DLPConfigurationItemDTO::toDTO)
+                .collect(Guavate.toImmutableList()));
+    }
+
+    private final ImmutableList<DLPConfigurationItemDTO> rules;
+
+    @JsonCreator
+    public DLPConfigurationDTO(
+        @JsonProperty("rules") ImmutableList<DLPConfigurationItemDTO> rules) {
+        this.rules = rules;
+    }
+
+    public ImmutableList<DLPConfigurationItemDTO> getRules() {
+        return rules;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/dec6e890/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTO.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTO.java
 
b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTO.java
new file mode 100644
index 0000000..502615a
--- /dev/null
+++ 
b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTO.java
@@ -0,0 +1,127 @@
+/****************************************************************
+ * 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 java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+import org.apache.james.dlp.api.DLPConfigurationItem;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.github.steveash.guavate.Guavate;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+
+public class DLPConfigurationItemDTO {
+
+    @VisibleForTesting
+    static DLPConfigurationItem toDLPConfiguration(DLPConfigurationItemDTO 
dto) {
+        return DLPConfigurationItem.builder()
+            .id(DLPConfigurationItem.Id.of(dto.id))
+            .expression(dto.expression)
+            .explanation(dto.explanation)
+            .targetsSender(dto.targetsSender)
+            .targetsRecipients(dto.targetsRecipients)
+            .targetsContent(dto.targetsContent)
+            .build();
+    }
+
+    @VisibleForTesting
+    static DLPConfigurationItemDTO toDTO(DLPConfigurationItem 
dlpConfiguration) {
+        DLPConfigurationItem.Targets targets = dlpConfiguration.getTargets();
+        return new DLPConfigurationItemDTO(
+            dlpConfiguration.getId().asString(),
+            dlpConfiguration.getRegexp(),
+            dlpConfiguration.getExplanation(),
+            Optional.of(targets.isSenderTargeted()),
+            Optional.of(targets.isRecipientTargeted()),
+            Optional.of(targets.isContentTargeted()));
+    }
+
+    private final String id;
+    private final String expression;
+    private final Optional<String> explanation;
+    private final Optional<Boolean> targetsSender;
+    private final Optional<Boolean> targetsRecipients;
+    private final Optional<Boolean> targetsContent;
+
+    @JsonCreator
+    public DLPConfigurationItemDTO(@JsonProperty("id") String id,
+                                   @JsonProperty("expression") String 
expression,
+                                   @JsonProperty("explanation") 
Optional<String> explanation,
+                                   @JsonProperty("targetsSender") 
Optional<Boolean> targetsSender,
+                                   @JsonProperty("targetsRecipients") 
Optional<Boolean> targetsRecipients,
+                                   @JsonProperty("targetsContent") 
Optional<Boolean> targetsContent) {
+        Preconditions.checkNotNull(id, "'id' is mandatory");
+        Preconditions.checkNotNull(expression, "'expression' is mandatory");
+        this.id = id;
+        this.expression = expression;
+        this.explanation = explanation;
+        this.targetsSender = targetsSender;
+        this.targetsRecipients = targetsRecipients;
+        this.targetsContent = targetsContent;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getExpression() {
+        return expression;
+    }
+
+    public Optional<String> getExplanation() {
+        return explanation;
+    }
+
+    public Optional<Boolean> getTargetsSender() {
+        return targetsSender;
+    }
+
+    public Optional<Boolean> getTargetsRecipients() {
+        return targetsRecipients;
+    }
+
+    public Optional<Boolean> getTargetsContent() {
+        return targetsContent;
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof DLPConfigurationItemDTO) {
+            DLPConfigurationItemDTO that = (DLPConfigurationItemDTO) o;
+
+            return Objects.equals(this.id, that.id)
+                && Objects.equals(this.expression, that.expression)
+                && Objects.equals(this.explanation, that.explanation)
+                && Objects.equals(this.targetsSender, that.targetsSender)
+                && Objects.equals(this.targetsRecipients, 
that.targetsRecipients)
+                && Objects.equals(this.targetsContent, that.targetsContent);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(id, expression, explanation, targetsSender, 
targetsRecipients, targetsContent);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/dec6e890/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DLPConfigurationRoutes.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DLPConfigurationRoutes.java
 
b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DLPConfigurationRoutes.java
new file mode 100644
index 0000000..73b1d33
--- /dev/null
+++ 
b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DLPConfigurationRoutes.java
@@ -0,0 +1,217 @@
+/****************************************************************
+ * 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 com.google.common.net.HttpHeaders.CONTENT_TYPE;
+import static org.apache.james.webadmin.Constants.EMPTY_BODY;
+import static org.apache.james.webadmin.Constants.JSON_CONTENT_TYPE;
+import static org.apache.james.webadmin.Constants.SEPARATOR;
+
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+
+import org.apache.james.core.Domain;
+import org.apache.james.dlp.api.DLPConfigurationItem;
+import org.apache.james.dlp.api.DLPConfigurationStore;
+import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.domainlist.api.DomainListException;
+import org.apache.james.webadmin.Routes;
+import org.apache.james.webadmin.dto.DLPConfigurationDTO;
+import org.apache.james.webadmin.utils.ErrorResponder;
+import org.apache.james.webadmin.utils.ErrorResponder.ErrorType;
+import org.apache.james.webadmin.utils.JsonExtractor;
+import org.apache.james.webadmin.utils.JsonTransformer;
+import org.eclipse.jetty.http.HttpStatus;
+
+import com.fasterxml.jackson.datatype.guava.GuavaModule;
+import com.github.steveash.guavate.Guavate;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import spark.HaltException;
+import spark.Request;
+import spark.Service;
+
+@Api(tags = "DLPRules")
+@Path(DLPConfigurationRoutes.BASE_PATH)
+@Produces(JSON_CONTENT_TYPE)
+public class DLPConfigurationRoutes implements Routes {
+
+    static final String BASE_PATH = "/dlp/rules";
+
+    private static final String DOMAIN_NAME = ":senderDomain";
+    private static final String SPECIFIC_DLP_RULE_DOMAIN = BASE_PATH + 
SEPARATOR + DOMAIN_NAME;
+
+    private final JsonTransformer jsonTransformer;
+    private final DLPConfigurationStore dlpConfigurationStore;
+    private final JsonExtractor<DLPConfigurationDTO> jsonExtractor;
+    private final DomainList domainList;
+
+    private Service service;
+
+    @Inject
+    public DLPConfigurationRoutes(DLPConfigurationStore dlpConfigurationStore, 
DomainList domainList, JsonTransformer jsonTransformer) {
+        this.dlpConfigurationStore = dlpConfigurationStore;
+        this.domainList = domainList;
+        this.jsonTransformer = jsonTransformer;
+        this.jsonExtractor = new JsonExtractor<>(DLPConfigurationDTO.class, 
new GuavaModule());
+    }
+
+    @Override
+    public void define(Service service) {
+        this.service = service;
+
+        defineStore();
+
+        defineList();
+
+        defineClear();
+    }
+
+    @PUT
+    @Path("/{senderDomain}")
+    @ApiOperation(value = "Store a list of dlp configs for given senderDomain")
+    @ApiImplicitParams({
+        @ApiImplicitParam(required = true, dataType = "string", name = 
"senderDomain", paramType = "path")
+    })
+    @ApiResponses(value = {
+        @ApiResponse(code = HttpStatus.NO_CONTENT_204, message = "OK. dlp 
config is stored."),
+        @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid 
senderDomain or payload in request"),
+        @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "The domain 
does not exist."),
+        @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
+            message = "Internal server error - Something went bad on the 
server side.")
+    })
+    public void defineStore() {
+        service.put(SPECIFIC_DLP_RULE_DOMAIN, (request, response) -> {
+            Domain senderDomain = parseDomain(request);
+            DLPConfigurationDTO dto = jsonExtractor.parse(request.body());
+
+            dlpConfigurationStore.store(senderDomain, 
DLPConfigurationDTO.toDLPConfigurations(dto));
+
+            response.status(HttpStatus.NO_CONTENT_204);
+            return EMPTY_BODY;
+        });
+    }
+
+    @GET
+    @Path("/{senderDomain}")
+    @ApiOperation(value = "Retrieve a list of dlp configs for given 
senderDomain")
+    @ApiImplicitParams({
+        @ApiImplicitParam(required = true, dataType = "string", name = 
"senderDomain", paramType = "path")
+    })
+    @ApiResponses(value = {
+        @ApiResponse(code = HttpStatus.OK_200, message = "OK. dlp configs 
returned"),
+        @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid 
senderDomain in request"),
+        @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "The domain 
does not exist."),
+        @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
+            message = "Internal server error - Something went bad on the 
server side.")
+    })
+    public void defineList() {
+        service.get(SPECIFIC_DLP_RULE_DOMAIN, (request, response) -> {
+            Domain senderDomain = parseDomain(request);
+            List<DLPConfigurationItem> dlpConfigurations = 
dlpConfigurationStore
+                .list(senderDomain)
+                .collect(Guavate.toImmutableList());
+
+            DLPConfigurationDTO dto = 
DLPConfigurationDTO.toDTO(dlpConfigurations);
+            response.status(HttpStatus.OK_200);
+            response.header(CONTENT_TYPE, JSON_CONTENT_TYPE);
+            return dto;
+        }, jsonTransformer);
+    }
+
+    @DELETE
+    @Path("/{senderDomain}")
+    @ApiOperation(value = "Clear all dlp configs for given senderDomain")
+    @ApiImplicitParams({
+        @ApiImplicitParam(required = true, dataType = "string", name = 
"senderDomain", paramType = "path")
+    })
+    @ApiResponses(value = {
+        @ApiResponse(code = HttpStatus.NO_CONTENT_204, message = "OK. dlp 
configs are cleared"),
+        @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid 
senderDomain in request"),
+        @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "The domain 
does not exist."),
+        @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
+            message = "Internal server error - Something went bad on the 
server side.")
+    })
+    public void defineClear() {
+        service.delete(SPECIFIC_DLP_RULE_DOMAIN, (request, response) -> {
+            Domain senderDomain = parseDomain(request);
+            dlpConfigurationStore.clear(senderDomain);
+
+            response.status(HttpStatus.NO_CONTENT_204);
+            return EMPTY_BODY;
+        }, jsonTransformer);
+    }
+
+    private Domain parseDomain(Request request) {
+        String domainName = request.params(DOMAIN_NAME);
+        try {
+            Domain domain = Domain.of(domainName);
+            validateDomainInList(domain);
+
+            return domain;
+        } catch (IllegalArgumentException e) {
+            throw invalidDomain(String.format("Invalid request for domain: 
%s", domainName), e);
+        } catch (DomainListException e) {
+            throw serverError(String.format("Cannot recognize domain: %s in 
domain list", domainName), e);
+        }
+    }
+
+    private void validateDomainInList(Domain domain) throws 
DomainListException {
+        if (!domainList.containsDomain(domain)) {
+            throw notFound(String.format("'%s' is not managed by this James 
server", domain.name()));
+        }
+    }
+
+    private HaltException invalidDomain(String message, Exception e) {
+        return ErrorResponder.builder()
+            .statusCode(HttpStatus.BAD_REQUEST_400)
+            .type(ErrorType.INVALID_ARGUMENT)
+            .message(message)
+            .cause(e)
+            .haltError();
+    }
+
+    private HaltException serverError(String message, Exception e) {
+        return ErrorResponder.builder()
+            .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500)
+            .type(ErrorType.SERVER_ERROR)
+            .message(message)
+            .cause(e)
+            .haltError();
+    }
+
+    private HaltException notFound(String message) {
+        return ErrorResponder.builder()
+            .statusCode(HttpStatus.NOT_FOUND_404)
+            .type(ErrorType.INVALID_ARGUMENT)
+            .message(message)
+            .haltError();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/dec6e890/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTOTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTOTest.java
 
b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTOTest.java
new file mode 100644
index 0000000..a4b0da8
--- /dev/null
+++ 
b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTOTest.java
@@ -0,0 +1,105 @@
+/****************************************************************
+ * 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 static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.james.dlp.api.DLPConfigurationItem;
+import org.assertj.core.api.SoftAssertions;
+import org.junit.jupiter.api.Test;
+
+import com.google.common.collect.ImmutableList;
+
+class DLPConfigurationItemDTOTest {
+
+    private static final String ID = "id";
+    private static final String EXPRESSION = "expression";
+    private static final String EXPLANATION = "explanation";
+    private static final String NULL_ID = null;
+    private static final String NULL_EXPRESSION = null;
+
+    @Test
+    void toDTOsShouldBeSetAllFields() {
+        DLPConfigurationItemDTO dto = DLPConfigurationItemDTO.toDTO(
+            DLPConfigurationItem.builder()
+                .id(DLPConfigurationItem.Id.of(ID))
+                .expression(EXPRESSION)
+                .explanation(EXPLANATION)
+                .targetsSender(Optional.of(true))
+                .targetsRecipients(Optional.of(true))
+                .targetsContent(Optional.of(true))
+                .build());
+
+        SoftAssertions.assertSoftly(softly -> {
+            softly.assertThat(dto.getId()).isEqualTo(ID);
+            softly.assertThat(dto.getExpression()).isEqualTo(EXPRESSION);
+            
softly.assertThat(dto.getExplanation().get()).isEqualTo(EXPLANATION);
+            softly.assertThat(dto.getTargetsSender().get()).isTrue();
+            softly.assertThat(dto.getTargetsRecipients().get()).isTrue();
+            softly.assertThat(dto.getTargetsContent().get()).isTrue();
+        });
+    }
+
+    @Test
+    void toDLPConfigurationsShouldBeSetAllFields() {
+        DLPConfigurationItem item = DLPConfigurationItemDTO.toDLPConfiguration(
+            new DLPConfigurationItemDTO(
+                ID,
+                EXPRESSION,
+                Optional.of(EXPLANATION),
+                Optional.of(true),
+                Optional.of(true),
+                Optional.of(true)));
+
+        SoftAssertions.assertSoftly(softly -> {
+            softly.assertThat(item.getId().asString()).isEqualTo(ID);
+            softly.assertThat(item.getRegexp()).isEqualTo(EXPRESSION);
+            
softly.assertThat(item.getExplanation().get()).isEqualTo(EXPLANATION);
+            softly.assertThat(item.getTargets().isSenderTargeted()).isTrue();
+            
softly.assertThat(item.getTargets().isRecipientTargeted()).isTrue();
+            softly.assertThat(item.getTargets().isContentTargeted()).isTrue();
+        });
+    }
+
+    @Test
+    void constructorShouldThrowWhenIdIsNull() {
+        assertThatThrownBy(() -> new DLPConfigurationItemDTO(NULL_ID,
+                EXPRESSION,
+                Optional.of(EXPLANATION),
+                Optional.of(true),
+                Optional.of(true),
+                Optional.of(true)))
+            .isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    void constructorShouldThrowWhenExpressionIsNull() {
+        assertThatThrownBy(() -> new DLPConfigurationItemDTO(ID,
+                NULL_EXPRESSION,
+                Optional.of(EXPLANATION),
+                Optional.of(true),
+                Optional.of(true),
+                Optional.of(true)))
+            .isInstanceOf(NullPointerException.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/dec6e890/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DLPConfigurationRoutesTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DLPConfigurationRoutesTest.java
 
b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DLPConfigurationRoutesTest.java
new file mode 100644
index 0000000..74d3468
--- /dev/null
+++ 
b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DLPConfigurationRoutesTest.java
@@ -0,0 +1,571 @@
+/****************************************************************
+ * 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 com.jayway.restassured.RestAssured.given;
+import static com.jayway.restassured.RestAssured.requestSpecification;
+import static com.jayway.restassured.RestAssured.when;
+import static com.jayway.restassured.RestAssured.with;
+import static net.javacrumbs.jsonunit.fluent.JsonFluentAssert.assertThatJson;
+import static org.apache.james.webadmin.Constants.JSON_CONTENT_TYPE;
+import static org.apache.james.webadmin.WebAdminServer.NO_CONFIGURATION;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+
+import java.net.InetAddress;
+import java.util.List;
+
+import org.apache.james.core.Domain;
+import org.apache.james.dlp.api.DLPConfigurationItem;
+import org.apache.james.dlp.api.DLPConfigurationStore;
+import org.apache.james.dlp.eventsourcing.EventSourcingDLPConfigurationStore;
+import org.apache.james.dnsservice.api.DNSService;
+import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.domainlist.memory.MemoryDomainList;
+import org.apache.james.eventsourcing.eventstore.memory.InMemoryEventStore;
+import org.apache.james.metrics.logger.DefaultMetricFactory;
+import org.apache.james.webadmin.DLPModule;
+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.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import com.google.common.collect.ImmutableList;
+import com.jayway.restassured.RestAssured;
+import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.specification.RequestSpecification;
+
+class DLPConfigurationRoutesTest {
+
+    private static final String DEFAULT_DOMAIN = "james.org";
+    private static final Domain SENDER_DOMAIN = Domain.of(DEFAULT_DOMAIN);
+    private static final String DOMAIN_2 = "apache.org";
+    private static final Domain SENDER_DOMAIN_2 = Domain.of(DOMAIN_2);
+
+    private static final DLPConfigurationItem CONFIGURATION_ITEM_1 = 
DLPConfigurationItem.builder()
+        .id(DLPConfigurationItem.Id.of("1"))
+        .explanation("explanation 1")
+        .expression(DEFAULT_DOMAIN)
+        .targetsSender()
+        .targetsRecipients()
+        .targetsContent()
+        .build();
+    private static final DLPConfigurationItem CONFIGURATION_ITEM_2 = 
DLPConfigurationItem.builder()
+        .id(DLPConfigurationItem.Id.of("2"))
+        .expression(DEFAULT_DOMAIN)
+        .targetsSender()
+        .build();
+
+    private static final List<DLPConfigurationItem> 
CONFIGURATION_ITEMS_FOR_DOMAIN_2 = 
ImmutableList.of(DLPConfigurationItem.builder()
+        .id(DLPConfigurationItem.Id.of("3"))
+        .expression(DOMAIN_2)
+        .targetsSender()
+        .build());
+
+    private static final List<DLPConfigurationItem> CONFIGURATION_ITEMS = 
ImmutableList.of(CONFIGURATION_ITEM_1, CONFIGURATION_ITEM_2);
+
+    private WebAdminServer webAdminServer;
+    private EventSourcingDLPConfigurationStore dlpStore;
+
+    private void createServer(DLPConfigurationStore dlpConfigurationStore, 
DomainList domainList) throws Exception {
+        webAdminServer = WebAdminUtils.createWebAdminServer(
+            new DefaultMetricFactory(),
+            new DLPConfigurationRoutes(dlpConfigurationStore, domainList, new 
JsonTransformer(new DLPModule())));
+        webAdminServer.configure(NO_CONFIGURATION);
+        webAdminServer.await();
+
+        requestSpecification = buildRequestSpecification(webAdminServer);
+    }
+
+    RequestSpecification buildRequestSpecification(WebAdminServer server) {
+        RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
+
+        return WebAdminUtils
+                .buildRequestSpecification(server)
+                .setBasePath(DLPConfigurationRoutes.BASE_PATH)
+                .build();
+    }
+
+
+    @BeforeEach
+    void setup() throws Exception {
+        DNSService dnsService = mock(DNSService.class);
+        Mockito.when(dnsService.getHostName(any())).thenReturn("localhost");
+        
Mockito.when(dnsService.getLocalHost()).thenReturn(InetAddress.getByName("localhost"));
+
+        MemoryDomainList domainList = new MemoryDomainList(dnsService);
+        domainList.setAutoDetectIP(false);
+        domainList.setAutoDetect(false);
+        domainList.addDomain(SENDER_DOMAIN);
+        domainList.addDomain(SENDER_DOMAIN_2);
+
+        dlpStore = new EventSourcingDLPConfigurationStore(new 
InMemoryEventStore());
+        createServer(dlpStore, domainList);
+    }
+
+
+    @Nested
+    class DefineStore {
+
+        @Test
+        void putShouldStoreTheConfigurations() {
+            String storeBody =
+                "{\"rules\": [" +
+                "  {" +
+                "    \"id\": \"1\"," +
+                "    \"expression\": \"expression 1\"," +
+                "    \"explanation\": \"explanation 1\"," +
+                "    \"targetsSender\": true," +
+                "    \"targetsRecipients\": true," +
+                "    \"targetsContent\": true" +
+                "  }," +
+                "  {" +
+                "    \"id\": \"2\"," +
+                "    \"expression\": \"expression 2\"," +
+                "    \"explanation\": \"explanation 2\"," +
+                "    \"targetsSender\": false," +
+                "    \"targetsRecipients\": false," +
+                "    \"targetsContent\": false" +
+                "  }]}";
+
+            given()
+                .body(storeBody)
+            .when()
+                .put(DEFAULT_DOMAIN)
+            .then()
+                .statusCode(HttpStatus.NO_CONTENT_204);
+
+            String retrievedBody = with()
+                .get(DEFAULT_DOMAIN)
+            .then()
+                .statusCode(HttpStatus.OK_200)
+                .contentType(ContentType.JSON)
+                .extract()
+                .body().asString();
+
+            assertThatJson(retrievedBody).isEqualTo(storeBody);
+        }
+
+        @Test
+        void putShouldStoreTheConfigurationsWhenTargetsAreNotSpecified() {
+            String storeBody =
+                "{\"rules\": [" +
+                "  {" +
+                "    \"id\": \"3\"," +
+                "    \"expression\": \"expression 3\"," +
+                "    \"explanation\": \"explanation 3\"" +
+                "  }]}";
+
+            given()
+                .body(storeBody)
+            .when()
+                .put(DEFAULT_DOMAIN)
+            .then()
+                .statusCode(HttpStatus.NO_CONTENT_204);
+
+            String retrievedBody = with()
+                .get(DEFAULT_DOMAIN)
+            .then()
+                .statusCode(HttpStatus.OK_200)
+                .contentType(ContentType.JSON)
+                .extract()
+                .body().asString();
+
+            assertThatJson(retrievedBody)
+                .isEqualTo(
+                    "{\"rules\": [" +
+                    "  {" +
+                    "    \"id\": \"3\"," +
+                    "    \"expression\": \"expression 3\"," +
+                    "    \"explanation\": \"explanation 3\"," +
+                    "    \"targetsSender\": false," +
+                    "    \"targetsRecipients\": false," +
+                    "    \"targetsContent\": false" +
+                    "  }" +
+                    "]}");
+        }
+
+        @Test
+        void putShouldStoreTheConfigurationsWhenExplanationNotSpecified() {
+            String storeBody =
+                "{\"rules\": [{" +
+                "  \"id\": \"3\"," +
+                "  \"expression\": \"expression 3\"" +
+                "}]}";
+
+            given()
+                .body(storeBody)
+            .when()
+                .put(DEFAULT_DOMAIN)
+            .then()
+                .statusCode(HttpStatus.NO_CONTENT_204);
+
+            String retrievedBody = with()
+                .get(DEFAULT_DOMAIN)
+            .then()
+                .statusCode(HttpStatus.OK_200)
+                .contentType(ContentType.JSON)
+                .extract()
+                .body().asString();
+
+            assertThatJson(retrievedBody)
+                .isEqualTo(
+                    "{\"rules\": [" +
+                    "  {" +
+                    "    \"id\": \"3\"," +
+                    "    \"expression\": \"expression 3\"," +
+                    "    \"explanation\": null," +
+                    "    \"targetsSender\": false," +
+                    "    \"targetsRecipients\": false," +
+                    "    \"targetsContent\": false" +
+                    "  }" +
+                    "]}");
+        }
+
+        @Test
+        void putShouldReturnBadRequestWhenIdIsNotSpecified() {
+            String body =
+                "{" +
+                "  \"expression\": \"expression 4\"," +
+                "  \"explanation\": \"explanation 4\"," +
+                "  \"targetsSender\": false," +
+                "  \"targetsRecipients\": false," +
+                "  \"targetsContent\": false" +
+                "}";
+
+            given()
+                .body(body)
+            .when()
+                .put(DEFAULT_DOMAIN)
+            .then()
+                .statusCode(HttpStatus.BAD_REQUEST_400)
+                .contentType(JSON_CONTENT_TYPE)
+                .body("statusCode", is(400))
+                .body("type", is("InvalidArgument"))
+                .body("message", is("JSON payload of the request is not 
valid"));
+        }
+
+        @Test
+        void putShouldReturnBadRequestWhenExpressionIsNotSpecified() {
+            String body =
+                "{" +
+                "  \"id\": \"5\"," +
+                "  \"explanation\": \"explanation 5\"," +
+                "  \"targetsSender\": false," +
+                "  \"targetsRecipients\": false," +
+                "  \"targetsContent\": false" +
+                "}";
+
+            given()
+                .body(body)
+            .when()
+                .put(DEFAULT_DOMAIN)
+            .then()
+                .statusCode(HttpStatus.BAD_REQUEST_400)
+                .contentType(JSON_CONTENT_TYPE)
+                .body("statusCode", is(400))
+                .body("type", is("InvalidArgument"))
+                .body("message", is("JSON payload of the request is not 
valid"));
+        }
+
+        @Test
+        void putShouldReturnNotFoundWhenDomainNotInList() {
+            String body =
+                "[{" +
+                "  \"id\": \"1\"," +
+                "  \"expression\": \"expression 1\"," +
+                "  \"explanation\": \"explanation 1\"," +
+                "  \"targetsSender\": true," +
+                "  \"targetsRecipients\": true," +
+                "  \"targetsContent\": true" +
+                "}," +
+                "{" +
+                "  \"id\": \"2\"," +
+                "  \"expression\": \"expression 2\"," +
+                "  \"explanation\": \"explanation 2\"," +
+                "  \"targetsSender\": false," +
+                "  \"targetsRecipients\": false," +
+                "  \"targetsContent\": false" +
+                "}]";
+
+            given()
+                .body(body)
+            .when()
+                .put("strange.com")
+            .then()
+                .statusCode(HttpStatus.NOT_FOUND_404)
+                .contentType(JSON_CONTENT_TYPE)
+                .body("statusCode", is(HttpStatus.NOT_FOUND_404))
+                .body("type", is("InvalidArgument"))
+                .body("message", is("'strange.com' is not managed by this 
James server"));
+        }
+
+        @Test
+        void putShouldReturnBadRequestWhenDomainIsNotValid() {
+            String body =
+                "[{" +
+                "  \"id\": \"1\"," +
+                "  \"expression\": \"expression 1\"," +
+                "  \"explanation\": \"explanation 1\"," +
+                "  \"targetsSender\": true," +
+                "  \"targetsRecipients\": true," +
+                "  \"targetsContent\": true" +
+                "}," +
+                "{" +
+                "  \"id\": \"2\"," +
+                "  \"expression\": \"expression 2\"," +
+                "  \"explanation\": \"explanation 2\"," +
+                "  \"targetsSender\": false," +
+                "  \"targetsRecipients\": false," +
+                "  \"targetsContent\": false" +
+                "}]";
+
+            given()
+                .body(body)
+            .when()
+                .put("[email protected]")
+            .then()
+                .statusCode(HttpStatus.BAD_REQUEST_400)
+                .contentType(JSON_CONTENT_TYPE)
+                .body("statusCode", is(HttpStatus.BAD_REQUEST_400))
+                .body("type", is("InvalidArgument"))
+                .body("message", is("Invalid request for domain: 
[email protected]"));
+        }
+    }
+
+    @Nested
+    class DefineClear {
+
+        @Test
+        void deleteShouldRemoveTheConfigurations() {
+            dlpStore.store(SENDER_DOMAIN, CONFIGURATION_ITEMS);
+
+            when()
+                .delete(DEFAULT_DOMAIN)
+            .then()
+                .statusCode(HttpStatus.NO_CONTENT_204);
+
+            String retrievedBody = with()
+                .get(DEFAULT_DOMAIN)
+            .then()
+                .statusCode(HttpStatus.OK_200)
+                .contentType(ContentType.JSON)
+                .extract()
+                .body().asString();
+
+            assertThatJson(retrievedBody).isEqualTo("{\"rules\":[]}");
+        }
+
+        @Test
+        void deleteShouldRemoveOnlyConfigurationsFromCorrespondingDomain() {
+            dlpStore.store(SENDER_DOMAIN, CONFIGURATION_ITEMS);
+            dlpStore.store(SENDER_DOMAIN_2, CONFIGURATION_ITEMS_FOR_DOMAIN_2);
+
+            when()
+                .delete(DEFAULT_DOMAIN)
+            .then()
+                .statusCode(HttpStatus.NO_CONTENT_204);
+
+            String retrievedBody = with()
+                .get(DEFAULT_DOMAIN)
+            .then()
+                .statusCode(HttpStatus.OK_200)
+                .contentType(ContentType.JSON)
+                .extract()
+                .body().asString();
+
+            assertThatJson(retrievedBody).isEqualTo("{\"rules\":[]}");
+
+            String retrievedBodyDomain2 = when()
+                .get(DOMAIN_2)
+            .then()
+                .statusCode(HttpStatus.OK_200)
+                .contentType(ContentType.JSON)
+                .extract()
+                .body().asString();
+
+            assertThatJson(retrievedBodyDomain2)
+                .isEqualTo(
+                    "{\"rules\": [" +
+                    "    {" +
+                    "        \"id\": \"3\"," +
+                    "        \"expression\": \"apache.org\"," +
+                    "        \"explanation\": null," +
+                    "        \"targetsSender\": true," +
+                    "        \"targetsRecipients\": false," +
+                    "        \"targetsContent\": false" +
+                    "    }" +
+                    "]}");
+        }
+
+        @Test
+        void deleteShouldReturnNotFoundWhenDomainNotInList() {
+            when()
+                .delete("strange.com")
+            .then()
+                .statusCode(HttpStatus.NOT_FOUND_404)
+                .contentType(JSON_CONTENT_TYPE)
+                .body("statusCode", is(HttpStatus.NOT_FOUND_404))
+                .body("type", is("InvalidArgument"))
+                .body("message", is("'strange.com' is not managed by this 
James server"));
+        }
+
+        @Test
+        void deleteShouldReturnBadRequestWhenDomainIsNotValid() {
+            when()
+                .delete("[email protected]")
+            .then()
+                .statusCode(HttpStatus.BAD_REQUEST_400)
+                .contentType(JSON_CONTENT_TYPE)
+                .body("statusCode", is(HttpStatus.BAD_REQUEST_400))
+                .body("type", is("InvalidArgument"))
+                .body("message", is("Invalid request for domain: 
[email protected]"));
+        }
+    }
+
+    @Nested
+    class DefineList {
+
+        @Test
+        void getShouldReturnOK() {
+            dlpStore.store(SENDER_DOMAIN, CONFIGURATION_ITEMS);
+
+            when()
+                .get(DEFAULT_DOMAIN)
+            .then()
+                .statusCode(HttpStatus.OK_200)
+                .contentType(ContentType.JSON);
+        }
+
+        @Test
+        void getShouldReturnABody() {
+            dlpStore.store(SENDER_DOMAIN, CONFIGURATION_ITEMS);
+
+            String body = when()
+                .get(DEFAULT_DOMAIN)
+            .then()
+                .statusCode(HttpStatus.OK_200)
+                .contentType(ContentType.JSON)
+                .extract()
+                .body()
+                .asString();
+
+            assertThatJson(body).isEqualTo(
+                "{\"rules\": [" +
+                "  {" +
+                "    \"id\": \"1\"," +
+                "    \"expression\": \"james.org\"," +
+                "    \"explanation\": \"explanation 1\"," +
+                "    \"targetsSender\": true," +
+                "    \"targetsRecipients\": true," +
+                "    \"targetsContent\": true" +
+                "  }," +
+                "  {" +
+                "    \"id\": \"2\"," +
+                "    \"expression\": \"james.org\"," +
+                "    \"explanation\": null," +
+                "    \"targetsSender\": true," +
+                "    \"targetsRecipients\": false," +
+                "    \"targetsContent\": false" +
+                "  }" +
+                "]}");
+        }
+
+        @Test
+        void getShouldReturnAnEmptyBodyWhenDLPStoreIsEmpty() {
+            dlpStore.store(SENDER_DOMAIN, ImmutableList.of());
+
+            String body = when()
+                .get(DEFAULT_DOMAIN)
+            .then()
+                .statusCode(HttpStatus.OK_200)
+                .contentType(ContentType.JSON)
+                .extract()
+                .body()
+                .asString();
+
+            assertThatJson(body).isEqualTo("{\"rules\":[]}");
+        }
+
+        @Test
+        void getShouldReturnOnlyConfigurationsFromCorrespondingDomain() {
+            dlpStore.store(SENDER_DOMAIN, CONFIGURATION_ITEMS);
+            dlpStore.store(SENDER_DOMAIN_2, CONFIGURATION_ITEMS_FOR_DOMAIN_2);
+
+            String body = when()
+                .get(DEFAULT_DOMAIN)
+            .then()
+                .statusCode(HttpStatus.OK_200)
+                .contentType(ContentType.JSON)
+                .extract()
+                .body()
+                .asString();
+
+            assertThatJson(body).isEqualTo(
+                "{\"rules\": [" +
+                "  {" +
+                "    \"id\": \"1\"," +
+                "    \"expression\": \"james.org\"," +
+                "    \"explanation\": \"explanation 1\"," +
+                "    \"targetsSender\": true," +
+                "    \"targetsRecipients\": true," +
+                "    \"targetsContent\": true" +
+                "  }," +
+                "  {" +
+                "    \"id\": \"2\"," +
+                "    \"expression\": \"james.org\"," +
+                "    \"explanation\": null," +
+                "    \"targetsSender\": true," +
+                "    \"targetsRecipients\": false," +
+                "    \"targetsContent\": false" +
+                "  }" +
+                "]}");
+        }
+
+        @Test
+        void getShouldReturnNotFoundWhenDomainNotInList() {
+            when()
+                .get("strange.com")
+            .then()
+                .statusCode(HttpStatus.NOT_FOUND_404)
+                .contentType(JSON_CONTENT_TYPE)
+                .body("statusCode", is(HttpStatus.NOT_FOUND_404))
+                .body("type", is("InvalidArgument"))
+                .body("message", is("'strange.com' is not managed by this 
James server"));
+        }
+
+        @Test
+        void getShouldReturnBadRequestWhenDomainIsNotValid() {
+            when()
+                .get("[email protected]")
+            .then()
+                .statusCode(HttpStatus.BAD_REQUEST_400)
+                .contentType(JSON_CONTENT_TYPE)
+                .body("statusCode", is(HttpStatus.BAD_REQUEST_400))
+                .body("type", is("InvalidArgument"))
+                .body("message", is("Invalid request for domain: 
[email protected]"));
+        }
+    }
+}
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to