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 ma...@apache.org on 2018/06/15 08:57:51 UTC

james-project git commit: JAMES-2421 [DLP] Rules store by event souring Cassandra implementation

Repository: james-project
Updated Branches:
  refs/heads/master cf143b6e8 -> dc5cefcd7


JAMES-2421 [DLP] Rules store by event souring Cassandra implementation


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

Branch: refs/heads/master
Commit: dc5cefcd789e167b4d5ec28703e4de3cf0ec09d7
Parents: cf143b6
Author: duc <dt...@linagora.com>
Authored: Tue Jun 12 15:03:55 2018 +0700
Committer: duc <dt...@linagora.com>
Committed: Fri Jun 15 15:52:24 2018 +0700

----------------------------------------------------------------------
 .../apache/james/CassandraJamesServerMain.java  |   2 +
 .../CassandraDLPConfigurationStoreModule.java   |  44 ++++++
 .../james/modules/data/MemoryDataModule.java    |   5 +
 .../james/dlp/api/DLPConfigurationItem.java     |  26 +++-
 server/data/data-cassandra/pom.xml              |  15 ++
 .../cassandra/DLPConfigurationItemAddedDTO.java | 111 ++++++++++++++
 .../DLPConfigurationItemAddedDTOModule.java     |  53 +++++++
 .../cassandra/DLPConfigurationItemDTO.java      | 147 ++++++++++++++++++
 .../DLPConfigurationItemsRemovedDTO.java        | 110 ++++++++++++++
 .../DLPConfigurationItemsRemovedDTOModule.java  |  53 +++++++
 ...tSourcingDLPConfigurationStoreExtension.java |  90 +++++++++++
 ...aEventSourcingDLPConfigurationStoreTest.java |  28 ++++
 .../dlp/eventsourcing/cassandra/DTOTest.java    | 150 +++++++++++++++++++
 .../dlp/eventsourcing/configuration_item_1.json |   8 +
 .../dlp/eventsourcing/items_added_event_1.json  |   6 +
 .../dlp/eventsourcing/items_added_event_2.json  |  30 ++++
 .../eventsourcing/items_removed_event_1.json    |   6 +
 .../eventsourcing/items_removed_event_2.json    |  30 ++++
 .../aggregates/DLPAggregateId.java              |   7 +
 19 files changed, 920 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java
index 762ad8a..035a272 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java
@@ -20,6 +20,7 @@
 package org.apache.james;
 
 import org.apache.james.modules.MailboxModule;
+import org.apache.james.modules.data.CassandraDLPConfigurationStoreModule;
 import org.apache.james.modules.data.CassandraDomainListModule;
 import org.apache.james.modules.data.CassandraJmapModule;
 import org.apache.james.modules.data.CassandraMailRepositoryModule;
@@ -85,6 +86,7 @@ public class CassandraJamesServerMain {
     public static final Module CASSANDRA_SERVER_CORE_MODULE = Modules.combine(
         new ActiveMQQueueModule(),
         new CassandraDomainListModule(),
+        new CassandraDLPConfigurationStoreModule(),
         new CassandraEventStoreModule(),
         new CassandraMailRepositoryModule(),
         new CassandraMetricsModule(),

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDLPConfigurationStoreModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDLPConfigurationStoreModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDLPConfigurationStoreModule.java
new file mode 100644
index 0000000..5d3abc7
--- /dev/null
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDLPConfigurationStoreModule.java
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.modules.data;
+
+import org.apache.james.dlp.api.DLPConfigurationStore;
+import org.apache.james.dlp.eventsourcing.EventSourcingDLPConfigurationStore;
+import org.apache.james.dlp.eventsourcing.cassandra.DLPConfigurationItemAddedDTOModule;
+import org.apache.james.dlp.eventsourcing.cassandra.DLPConfigurationItemsRemovedDTOModule;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Scopes;
+import com.google.inject.multibindings.Multibinder;
+
+public class CassandraDLPConfigurationStoreModule extends AbstractModule {
+
+    @Override
+    protected void configure() {
+        bind(EventSourcingDLPConfigurationStore.class).in(Scopes.SINGLETON);
+        bind(DLPConfigurationStore.class).to(EventSourcingDLPConfigurationStore.class);
+
+        Multibinder<EventDTOModule> eventDTOModuleBinder = Multibinder.newSetBinder(binder(), EventDTOModule.class);
+
+        eventDTOModuleBinder.addBinding().to(DLPConfigurationItemAddedDTOModule.class);
+        eventDTOModuleBinder.addBinding().to(DLPConfigurationItemsRemovedDTOModule.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
index 6fd5de2..90fdd43 100644
--- a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
+++ b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
@@ -22,6 +22,8 @@ package org.apache.james.modules.data;
 import java.util.List;
 
 import org.apache.commons.configuration.ConfigurationException;
+import org.apache.james.dlp.api.DLPConfigurationStore;
+import org.apache.james.dlp.eventsourcing.EventSourcingDLPConfigurationStore;
 import org.apache.james.domainlist.api.DomainList;
 import org.apache.james.domainlist.memory.MemoryDomainList;
 import org.apache.james.lifecycle.api.Configurable;
@@ -47,6 +49,9 @@ public class MemoryDataModule extends AbstractModule {
     protected void configure() {
         install(new SieveFileRepositoryModule());
 
+        bind(EventSourcingDLPConfigurationStore.class).in(Scopes.SINGLETON);
+        bind(DLPConfigurationStore.class).to(EventSourcingDLPConfigurationStore.class);
+
         bind(MemoryDomainList.class).in(Scopes.SINGLETON);
         bind(DomainList.class).to(MemoryDomainList.class);
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/data/data-api/src/main/java/org/apache/james/dlp/api/DLPConfigurationItem.java
----------------------------------------------------------------------
diff --git a/server/data/data-api/src/main/java/org/apache/james/dlp/api/DLPConfigurationItem.java b/server/data/data-api/src/main/java/org/apache/james/dlp/api/DLPConfigurationItem.java
index d0babdb..6c48b8d 100644
--- a/server/data/data-api/src/main/java/org/apache/james/dlp/api/DLPConfigurationItem.java
+++ b/server/data/data-api/src/main/java/org/apache/james/dlp/api/DLPConfigurationItem.java
@@ -95,26 +95,51 @@ public class DLPConfigurationItem {
             return this;
         }
 
+        public Builder targetsSender(boolean targetsSender) {
+            this.targetsSender = Optional.of(targetsSender);
+            return this;
+        }
+
         public Builder targetsRecipients() {
             this.targetsRecipients = Optional.of(true);
             return this;
         }
 
+        public Builder targetsRecipients(boolean targetsRecipients) {
+            this.targetsRecipients = Optional.of(targetsRecipients);
+            return this;
+        }
+
         public Builder targetsContent() {
             this.targetsContent = Optional.of(true);
             return this;
         }
 
+        public Builder targetsContent(boolean targetsContent) {
+            this.targetsContent = Optional.of(targetsContent);
+            return this;
+        }
+
         public Builder expression(String expression) {
             this.expression = Optional.of(expression);
             return this;
         }
 
+        public Builder expression(Optional<String> expression) {
+            expression.ifPresent(this::expression);
+            return this;
+        }
+
         public Builder explanation(String explanation) {
             this.explanation = Optional.of(explanation);
             return this;
         }
 
+        public Builder explanation(Optional<String> explanation) {
+            explanation.ifPresent(this::explanation);
+            return this;
+        }
+
         public Builder id(Id id) {
             this.id = Optional.of(id);
             return this;
@@ -189,7 +214,6 @@ public class DLPConfigurationItem {
         public String toString() {
             return MoreObjects.toStringHelper(this)
                 .add("senderTargeted", senderTargeted)
-                .add("senderTargeted", senderTargeted)
                 .add("recipientTargeted", recipientTargeted)
                 .add("contentTargeted", contentTargeted)
                 .toString();

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/data/data-cassandra/pom.xml
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/pom.xml b/server/data/data-cassandra/pom.xml
index 5e86b05..77921bb 100644
--- a/server/data/data-cassandra/pom.xml
+++ b/server/data/data-cassandra/pom.xml
@@ -43,6 +43,16 @@
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>event-sourcing-event-store-cassandra</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>event-sourcing-event-store-cassandra</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>james-server-data-api</artifactId>
         </dependency>
         <dependency>
@@ -103,6 +113,11 @@
             <scope>test</scope>
         </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>

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemAddedDTO.java
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemAddedDTO.java b/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemAddedDTO.java
new file mode 100644
index 0000000..fd1776b
--- /dev/null
+++ b/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemAddedDTO.java
@@ -0,0 +1,111 @@
+/****************************************************************
+ * 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.dlp.eventsourcing.cassandra;
+
+import static org.apache.james.dlp.eventsourcing.cassandra.DLPConfigurationItemDTO.fromDTOs;
+
+import java.util.List;
+import java.util.Objects;
+
+import org.apache.james.dlp.eventsourcing.aggregates.DLPAggregateId;
+import org.apache.james.dlp.eventsourcing.events.ConfigurationItemsAdded;
+import org.apache.james.eventsourcing.EventId;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Preconditions;
+
+class DLPConfigurationItemAddedDTO implements EventDTO {
+
+    public static DLPConfigurationItemAddedDTO from(ConfigurationItemsAdded event, String type) {
+        return new DLPConfigurationItemAddedDTO(
+            type,
+            event.eventId().serialize(),
+            event.getAggregateId().asAggregateKey(),
+            DLPConfigurationItemDTO.from(event.getRules()));
+    }
+
+    private final String type;
+    private final int eventId;
+    private final String aggregateId;
+    private final List<DLPConfigurationItemDTO> configurationItems;
+
+    @JsonCreator
+    private DLPConfigurationItemAddedDTO(
+            @JsonProperty("type") String type,
+            @JsonProperty("eventId") int eventId,
+            @JsonProperty("aggregateId") String aggregateId,
+            @JsonProperty("configurationItems") List<DLPConfigurationItemDTO> configurationItems) {
+        Preconditions.checkNotNull(type);
+        Preconditions.checkNotNull(aggregateId);
+        Preconditions.checkNotNull(configurationItems);
+        Preconditions.checkArgument(!configurationItems.isEmpty());
+
+        this.type = type;
+        this.eventId = eventId;
+        this.aggregateId = aggregateId;
+        this.configurationItems = configurationItems;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public long getEventId() {
+        return eventId;
+    }
+
+    public String getAggregateId() {
+        return aggregateId;
+    }
+
+    public List<DLPConfigurationItemDTO> getConfigurationItems() {
+        return configurationItems;
+    }
+
+    @JsonIgnore
+    @Override
+    public ConfigurationItemsAdded toEvent() {
+        return new ConfigurationItemsAdded(
+            DLPAggregateId.parse(aggregateId),
+            EventId.fromSerialized(eventId),
+            fromDTOs(configurationItems));
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof DLPConfigurationItemAddedDTO) {
+            DLPConfigurationItemAddedDTO that = (DLPConfigurationItemAddedDTO) o;
+
+            return Objects.equals(this.eventId, that.eventId)
+                && Objects.equals(this.type, that.type)
+                && Objects.equals(this.aggregateId, that.aggregateId)
+                && Objects.equals(this.configurationItems, that.configurationItems);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(type, eventId, aggregateId, configurationItems);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemAddedDTOModule.java
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemAddedDTOModule.java b/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemAddedDTOModule.java
new file mode 100644
index 0000000..d38808b
--- /dev/null
+++ b/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemAddedDTOModule.java
@@ -0,0 +1,53 @@
+/****************************************************************
+ * 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.dlp.eventsourcing.cassandra;
+
+import org.apache.james.dlp.eventsourcing.events.ConfigurationItemsAdded;
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
+
+import com.google.common.base.Preconditions;
+
+public class DLPConfigurationItemAddedDTOModule implements EventDTOModule {
+    private static final String DLP_CONFIGURATION_STORE = "dlp-configuration-store";
+
+    @Override
+    public String getType() {
+        return DLP_CONFIGURATION_STORE;
+    }
+
+    @Override
+    public Class<? extends EventDTO> getDTOClass() {
+        return DLPConfigurationItemAddedDTO.class;
+    }
+
+    @Override
+    public Class<? extends Event> getEventClass() {
+        return ConfigurationItemsAdded.class;
+    }
+
+    @Override
+    public EventDTO toDTO(Event event) {
+        Preconditions.checkArgument(event instanceof ConfigurationItemsAdded);
+        return DLPConfigurationItemAddedDTO
+            .from((ConfigurationItemsAdded) event, DLP_CONFIGURATION_STORE);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemDTO.java
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemDTO.java b/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemDTO.java
new file mode 100644
index 0000000..02b6e4e
--- /dev/null
+++ b/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemDTO.java
@@ -0,0 +1,147 @@
+/****************************************************************
+ * 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.dlp.eventsourcing.cassandra;
+
+import static com.github.steveash.guavate.Guavate.toImmutableList;
+
+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.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Preconditions;
+
+public class DLPConfigurationItemDTO {
+
+    public static DLPConfigurationItemDTO from(DLPConfigurationItem dlpConfiguration) {
+        DLPConfigurationItem.Targets targets = dlpConfiguration.getTargets();
+
+        return new DLPConfigurationItemDTO(
+            dlpConfiguration.getId().asString(),
+            dlpConfiguration.getExplanation(),
+            dlpConfiguration.getRegexp(),
+            targets.isContentTargeted(),
+            targets.isSenderTargeted(),
+            targets.isRecipientTargeted());
+    }
+
+    public static List<DLPConfigurationItemDTO> from(List<DLPConfigurationItem> configurationItems) {
+        Preconditions.checkNotNull(configurationItems);
+
+        return configurationItems
+            .stream()
+            .map(DLPConfigurationItemDTO::from)
+            .collect(toImmutableList());
+    }
+
+    public static List<DLPConfigurationItem> fromDTOs(List<DLPConfigurationItemDTO> configurationItems) {
+        Preconditions.checkNotNull(configurationItems);
+
+        return configurationItems
+            .stream()
+            .map(DLPConfigurationItemDTO::toDLPConfiguration)
+            .collect(toImmutableList());
+    }
+
+    private final String id;
+    private final Optional<String> explanation;
+    private final String expression;
+    private final boolean targetsContent;
+    private final boolean targetsSender;
+    private final boolean targetsRecipients;
+
+    @JsonCreator
+    private DLPConfigurationItemDTO(@JsonProperty("id") String id,
+                                   @JsonProperty("explanation") Optional<String> explanation,
+                                   @JsonProperty("expression") String expression,
+                                   @JsonProperty("targetsContent") boolean targetsContent,
+                                   @JsonProperty("targetsSender") boolean targetsSender,
+                                   @JsonProperty("targetsRecipients") boolean targetsRecipients) {
+        Preconditions.checkNotNull(id);
+        Preconditions.checkNotNull(expression);
+
+        this.id = id;
+        this.explanation = explanation;
+        this.expression = expression;
+        this.targetsContent = targetsContent;
+        this.targetsSender = targetsSender;
+        this.targetsRecipients = targetsRecipients;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public Optional<String> getExplanation() {
+        return explanation;
+    }
+
+    public String getExpression() {
+        return expression;
+    }
+
+    public boolean isTargetsContent() {
+        return targetsContent;
+    }
+
+    public boolean isTargetsSender() {
+        return targetsSender;
+    }
+
+    public boolean isTargetsRecipients() {
+        return targetsRecipients;
+    }
+
+    @JsonIgnore
+    public DLPConfigurationItem toDLPConfiguration() {
+        return DLPConfigurationItem.builder()
+            .id(DLPConfigurationItem.Id.of(id))
+            .expression(expression)
+            .explanation(explanation)
+            .targetsSender(targetsSender)
+            .targetsContent(targetsContent)
+            .targetsRecipients(targetsRecipients)
+            .build();
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof DLPConfigurationItemDTO) {
+            DLPConfigurationItemDTO that = (DLPConfigurationItemDTO) o;
+
+            return Objects.equals(this.targetsContent, that.targetsContent)
+                && Objects.equals(this.targetsSender, that.targetsSender)
+                && Objects.equals(this.targetsRecipients, that.targetsRecipients)
+                && Objects.equals(this.explanation, that.explanation)
+                && Objects.equals(this.expression, that.expression)
+                && Objects.equals(this.id, that.id);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(id, explanation, expression, targetsContent, targetsSender, targetsRecipients);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemsRemovedDTO.java
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemsRemovedDTO.java b/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemsRemovedDTO.java
new file mode 100644
index 0000000..6cdd865
--- /dev/null
+++ b/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemsRemovedDTO.java
@@ -0,0 +1,110 @@
+/****************************************************************
+ * 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.dlp.eventsourcing.cassandra;
+
+import static org.apache.james.dlp.eventsourcing.cassandra.DLPConfigurationItemDTO.fromDTOs;
+
+import java.util.List;
+import java.util.Objects;
+
+import org.apache.james.dlp.eventsourcing.aggregates.DLPAggregateId;
+import org.apache.james.dlp.eventsourcing.events.ConfigurationItemsRemoved;
+import org.apache.james.eventsourcing.EventId;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Preconditions;
+
+class DLPConfigurationItemsRemovedDTO implements EventDTO {
+
+    public static DLPConfigurationItemsRemovedDTO from(ConfigurationItemsRemoved event, String type) {
+        return new DLPConfigurationItemsRemovedDTO(
+            type,
+            event.eventId().serialize(),
+            event.getAggregateId().asAggregateKey(),
+            DLPConfigurationItemDTO.from(event.getRules()));
+    }
+
+    private final String type;
+    private final int eventId;
+    private final String aggregateId;
+    private final List<DLPConfigurationItemDTO> configurationItems;
+
+    @JsonCreator
+    private DLPConfigurationItemsRemovedDTO(
+            @JsonProperty("type") String type,
+            @JsonProperty("eventId") int eventId,
+            @JsonProperty("aggregateId") String aggregateId,
+            @JsonProperty("configurationItems") List<DLPConfigurationItemDTO> configurationItems) {
+        Preconditions.checkNotNull(type);
+        Preconditions.checkNotNull(aggregateId);
+        Preconditions.checkNotNull(configurationItems);
+        Preconditions.checkArgument(!configurationItems.isEmpty());
+
+        this.type = type;
+        this.eventId = eventId;
+        this.aggregateId = aggregateId;
+        this.configurationItems = configurationItems;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public long getEventId() {
+        return eventId;
+    }
+
+    public String getAggregateId() {
+        return aggregateId;
+    }
+
+    public List<DLPConfigurationItemDTO> getConfigurationItems() {
+        return configurationItems;
+    }
+
+    @JsonIgnore
+    @Override
+    public ConfigurationItemsRemoved toEvent() {
+        return new ConfigurationItemsRemoved(
+            DLPAggregateId.parse(aggregateId),
+            EventId.fromSerialized(eventId),
+            fromDTOs(configurationItems));
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof DLPConfigurationItemsRemovedDTO) {
+            DLPConfigurationItemsRemovedDTO that = (DLPConfigurationItemsRemovedDTO) o;
+
+            return Objects.equals(this.eventId, that.eventId)
+                && Objects.equals(this.type, that.type)
+                && Objects.equals(this.aggregateId, that.aggregateId);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(type, eventId, aggregateId);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemsRemovedDTOModule.java
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemsRemovedDTOModule.java b/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemsRemovedDTOModule.java
new file mode 100644
index 0000000..9e259cd
--- /dev/null
+++ b/server/data/data-cassandra/src/main/java/org/apache/james/dlp/eventsourcing/cassandra/DLPConfigurationItemsRemovedDTOModule.java
@@ -0,0 +1,53 @@
+/****************************************************************
+ * 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.dlp.eventsourcing.cassandra;
+
+import org.apache.james.dlp.eventsourcing.events.ConfigurationItemsRemoved;
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
+
+import com.google.common.base.Preconditions;
+
+public class DLPConfigurationItemsRemovedDTOModule implements EventDTOModule {
+    private static final String DLP_CONFIGURATION_CLEAR = "dlp-configuration-clear";
+
+    @Override
+    public String getType() {
+        return DLP_CONFIGURATION_CLEAR;
+    }
+
+    @Override
+    public Class<? extends EventDTO> getDTOClass() {
+        return DLPConfigurationItemsRemovedDTO.class;
+    }
+
+    @Override
+    public Class<? extends Event> getEventClass() {
+        return ConfigurationItemsRemoved.class;
+    }
+
+    @Override
+    public EventDTO toDTO(Event event) {
+        Preconditions.checkArgument(event instanceof ConfigurationItemsRemoved);
+        return DLPConfigurationItemsRemovedDTO
+            .from((ConfigurationItemsRemoved) event, DLP_CONFIGURATION_CLEAR);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/data/data-cassandra/src/test/java/org/apache/james/dlp/eventsourcing/cassandra/CassandraEventSourcingDLPConfigurationStoreExtension.java
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/test/java/org/apache/james/dlp/eventsourcing/cassandra/CassandraEventSourcingDLPConfigurationStoreExtension.java b/server/data/data-cassandra/src/test/java/org/apache/james/dlp/eventsourcing/cassandra/CassandraEventSourcingDLPConfigurationStoreExtension.java
new file mode 100644
index 0000000..ba2d72a
--- /dev/null
+++ b/server/data/data-cassandra/src/test/java/org/apache/james/dlp/eventsourcing/cassandra/CassandraEventSourcingDLPConfigurationStoreExtension.java
@@ -0,0 +1,90 @@
+/****************************************************************
+ * 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.dlp.eventsourcing.cassandra;
+
+import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.backends.cassandra.DockerCassandraExtension;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.dlp.api.DLPConfigurationStore;
+import org.apache.james.dlp.eventsourcing.EventSourcingDLPConfigurationStore;
+import org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStore;
+import org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStoreModule;
+import org.apache.james.eventsourcing.eventstore.cassandra.EventStoreDao;
+import org.apache.james.eventsourcing.eventstore.cassandra.JsonEventSerializer;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+import org.junit.jupiter.api.extension.ParameterResolver;
+import org.testcontainers.shaded.com.google.common.collect.ImmutableSet;
+
+public class CassandraEventSourcingDLPConfigurationStoreExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback, ParameterResolver {
+
+    private final DockerCassandraExtension dockerCassandraExtension;
+    private CassandraCluster cassandra;
+
+    public CassandraEventSourcingDLPConfigurationStoreExtension() {
+        dockerCassandraExtension = new DockerCassandraExtension();
+    }
+
+    @Override
+    public void beforeAll(ExtensionContext context) throws Exception {
+        dockerCassandraExtension.beforeAll(context);
+    }
+
+    @Override
+    public void afterAll(ExtensionContext context) throws Exception {
+        dockerCassandraExtension.afterAll(context);
+    }
+
+    @Override
+    public void beforeEach(ExtensionContext context) {
+        cassandra = CassandraCluster.create(
+            new CassandraEventStoreModule(),
+            dockerCassandraExtension.getDockerCassandra().getIp(),
+            dockerCassandraExtension.getDockerCassandra().getBindingPort());
+    }
+
+    @Override
+    public void afterEach(ExtensionContext context) {
+        cassandra.close();
+    }
+
+    @Override
+    public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        return (parameterContext.getParameter().getType() == DLPConfigurationStore.class);
+    }
+
+    @Override
+    public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        JsonEventSerializer jsonEventSerializer = new JsonEventSerializer(
+            ImmutableSet.of(new DLPConfigurationItemAddedDTOModule(), new DLPConfigurationItemsRemovedDTOModule()));
+
+        EventStoreDao eventStoreDao = new EventStoreDao(
+            cassandra.getConf(),
+            CassandraUtils.WITH_DEFAULT_CONFIGURATION,
+            jsonEventSerializer);
+
+        return new EventSourcingDLPConfigurationStore(new CassandraEventStore(eventStoreDao));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/data/data-cassandra/src/test/java/org/apache/james/dlp/eventsourcing/cassandra/CassandraEventSourcingDLPConfigurationStoreTest.java
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/test/java/org/apache/james/dlp/eventsourcing/cassandra/CassandraEventSourcingDLPConfigurationStoreTest.java b/server/data/data-cassandra/src/test/java/org/apache/james/dlp/eventsourcing/cassandra/CassandraEventSourcingDLPConfigurationStoreTest.java
new file mode 100644
index 0000000..9fdcb44
--- /dev/null
+++ b/server/data/data-cassandra/src/test/java/org/apache/james/dlp/eventsourcing/cassandra/CassandraEventSourcingDLPConfigurationStoreTest.java
@@ -0,0 +1,28 @@
+/****************************************************************
+ * 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.dlp.eventsourcing.cassandra;
+
+import org.apache.james.dlp.api.DLPConfigurationStoreContract;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(CassandraEventSourcingDLPConfigurationStoreExtension.class)
+public class CassandraEventSourcingDLPConfigurationStoreTest implements DLPConfigurationStoreContract {
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/data/data-cassandra/src/test/java/org/apache/james/dlp/eventsourcing/cassandra/DTOTest.java
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/test/java/org/apache/james/dlp/eventsourcing/cassandra/DTOTest.java b/server/data/data-cassandra/src/test/java/org/apache/james/dlp/eventsourcing/cassandra/DTOTest.java
new file mode 100644
index 0000000..7828b60
--- /dev/null
+++ b/server/data/data-cassandra/src/test/java/org/apache/james/dlp/eventsourcing/cassandra/DTOTest.java
@@ -0,0 +1,150 @@
+/****************************************************************
+ * 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.dlp.eventsourcing.cassandra;
+
+import static net.javacrumbs.jsonunit.fluent.JsonFluentAssert.assertThatJson;
+import static org.apache.james.util.ClassLoaderUtils.getSystemResourceAsString;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.util.List;
+
+import org.apache.james.core.Domain;
+import org.apache.james.dlp.api.DLPConfigurationItem;
+import org.apache.james.dlp.eventsourcing.aggregates.DLPAggregateId;
+import org.apache.james.dlp.eventsourcing.events.ConfigurationItemsAdded;
+import org.apache.james.dlp.eventsourcing.events.ConfigurationItemsRemoved;
+import org.apache.james.eventsourcing.EventId;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.testcontainers.shaded.com.google.common.collect.ImmutableList;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+
+public class DTOTest {
+
+    private static final DLPConfigurationItem CONFIGURATION_ITEM_1 = DLPConfigurationItem.builder()
+        .id(DLPConfigurationItem.Id.of("1"))
+        .explanation("Find whatever contains james.org")
+        .expression("james.org")
+        .targetsSender()
+        .targetsRecipients()
+        .targetsContent()
+        .build();
+    private static final DLPConfigurationItemDTO DLP_CONFIGURATION_DTO_1 = DLPConfigurationItemDTO.from(CONFIGURATION_ITEM_1);
+    private static final DLPConfigurationItem CONFIGURATION_ITEM_2 = DLPConfigurationItem.builder()
+        .id(DLPConfigurationItem.Id.of("2"))
+        .explanation("Find senders have domain apache.org")
+        .expression("apache.org")
+        .targetsSender()
+        .build();
+    private static final DLPConfigurationItem CONFIGURATION_ITEM_3 = DLPConfigurationItem.builder()
+        .id(DLPConfigurationItem.Id.of("3"))
+        .expression("linagora.org")
+        .targetsSender()
+        .targetsContent()
+        .build();
+
+    private static final List<DLPConfigurationItem> DLP_CONFIGURATION_ITEMS = ImmutableList.of(
+        CONFIGURATION_ITEM_1,
+        CONFIGURATION_ITEM_2,
+        CONFIGURATION_ITEM_3);
+
+    private static final DLPAggregateId DLP_AGGREGATE_ID = new DLPAggregateId(Domain.of("james.org"));
+
+    private static final DLPConfigurationItemsRemovedDTO ITEMS_REMOVED_EVENT_DTO_2 = DLPConfigurationItemsRemovedDTO.from(
+        new ConfigurationItemsRemoved(DLP_AGGREGATE_ID, EventId.first(), DLP_CONFIGURATION_ITEMS),
+        "dlp-configuration-clear");
+
+    private static final DLPConfigurationItemAddedDTO ITEMS_ADDED_EVENT_DTO_2 = DLPConfigurationItemAddedDTO.from(
+        new ConfigurationItemsAdded(DLP_AGGREGATE_ID, EventId.first(), DLP_CONFIGURATION_ITEMS),
+        "dlp-configuration-store");
+
+    private static final String ITEMS_REMOVED_EVENT_JSON_1 = getSystemResourceAsString("json/dlp/eventsourcing/items_removed_event_1.json");
+    private static final String ITEMS_REMOVED_EVENT_JSON_2 = getSystemResourceAsString("json/dlp/eventsourcing/items_removed_event_2.json");
+    private static final String CONFIGURATION_ITEMS_JSON_1 = getSystemResourceAsString("json/dlp/eventsourcing/configuration_item_1.json");
+    private static final String ITEMS_ADDED_EVENT_JSON_1 = getSystemResourceAsString("json/dlp/eventsourcing/items_added_event_1.json");
+    private static final String ITEMS_ADDED_EVENT_JSON_2 = getSystemResourceAsString("json/dlp/eventsourcing/items_added_event_2.json");
+
+    private ObjectMapper objectMapper;
+
+    @BeforeEach
+    void setUp() {
+        objectMapper = new ObjectMapper();
+        objectMapper.registerModule(new Jdk8Module());
+        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
+    }
+
+    @Test
+    void shouldThrowsExceptionWhenDeserializeRemovedEventWithEmptyItems() throws Exception {
+        assertThatThrownBy(
+            () -> objectMapper.readValue(ITEMS_REMOVED_EVENT_JSON_1, DLPConfigurationItemsRemovedDTO.class));
+    }
+
+    @Test
+    void shouldSerializeDLPConfigurationRemovedEventDTO() throws Exception {
+        assertThatJson(
+            objectMapper.writeValueAsString(ITEMS_REMOVED_EVENT_DTO_2))
+            .isEqualTo(ITEMS_REMOVED_EVENT_JSON_2);
+    }
+
+    @Test
+    void shouldDeserializeDLPConfigurationRemovedEventDTO() throws Exception {
+        assertThat(
+            objectMapper.readValue(ITEMS_REMOVED_EVENT_JSON_2, DLPConfigurationItemsRemovedDTO.class))
+            .isEqualTo(ITEMS_REMOVED_EVENT_DTO_2);
+    }
+
+    @Test
+    void shouldThrowsExceptionWhenDeserializeAddedEventWithEmptyItems() throws Exception {
+        assertThatThrownBy(
+            () -> objectMapper.readValue(ITEMS_ADDED_EVENT_JSON_1, DLPConfigurationItemAddedDTO.class));
+    }
+
+    @Test
+    void shouldSerializeDLPConfigurationItemAddedEventDTO() throws Exception {
+        assertThatJson(
+            objectMapper.writeValueAsString(ITEMS_ADDED_EVENT_DTO_2))
+            .isEqualTo(ITEMS_ADDED_EVENT_JSON_2);
+    }
+
+    @Test
+    void shouldDeserializeDLPConfigurationItemAddedEventDTO() throws Exception {
+        assertThat(
+            objectMapper.readValue(ITEMS_ADDED_EVENT_JSON_2, DLPConfigurationItemAddedDTO.class))
+            .isEqualTo(ITEMS_ADDED_EVENT_DTO_2);
+    }
+
+    @Test
+    void shouldSerializeDLPConfigurationItemDTO() throws Exception {
+        assertThatJson(
+            objectMapper.writeValueAsString(DLP_CONFIGURATION_DTO_1))
+            .isEqualTo(CONFIGURATION_ITEMS_JSON_1);
+    }
+
+    @Test
+    void shouldDeserializeDLPConfigurationItemDTO() throws Exception {
+        assertThat(
+            objectMapper.readValue(CONFIGURATION_ITEMS_JSON_1, DLPConfigurationItemDTO.class))
+            .isEqualTo(DLP_CONFIGURATION_DTO_1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/configuration_item_1.json
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/configuration_item_1.json b/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/configuration_item_1.json
new file mode 100644
index 0000000..39a2a26
--- /dev/null
+++ b/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/configuration_item_1.json
@@ -0,0 +1,8 @@
+{
+  "id": "1",
+  "explanation": "Find whatever contains james.org",
+  "expression": "james.org",
+  "targetsContent": true,
+  "targetsSender": true,
+  "targetsRecipients": true
+ }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/items_added_event_1.json
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/items_added_event_1.json b/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/items_added_event_1.json
new file mode 100644
index 0000000..3d8d160
--- /dev/null
+++ b/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/items_added_event_1.json
@@ -0,0 +1,6 @@
+{
+ "type": "dlp-configuration-store",
+ "eventId": 0,
+ "aggregateId":"DLPRule/james.org",
+ "configurationItems": []
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/items_added_event_2.json
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/items_added_event_2.json b/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/items_added_event_2.json
new file mode 100644
index 0000000..a4081d9
--- /dev/null
+++ b/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/items_added_event_2.json
@@ -0,0 +1,30 @@
+{
+ "type": "dlp-configuration-store",
+ "eventId": 0,
+ "aggregateId":"DLPRule/james.org",
+ "configurationItems": [
+  {
+   "id": "1",
+   "explanation": "Find whatever contains james.org",
+   "expression": "james.org",
+   "targetsContent": true,
+   "targetsSender": true,
+   "targetsRecipients": true
+  },
+  {
+   "id": "2",
+   "explanation": "Find senders have domain apache.org",
+   "expression": "apache.org",
+   "targetsContent": false,
+   "targetsSender": true,
+   "targetsRecipients": false
+  },
+  {
+   "id": "3",
+   "expression": "linagora.org",
+   "targetsContent": true,
+   "targetsSender": true,
+   "targetsRecipients": false
+  }
+ ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/items_removed_event_1.json
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/items_removed_event_1.json b/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/items_removed_event_1.json
new file mode 100644
index 0000000..3f0b19a
--- /dev/null
+++ b/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/items_removed_event_1.json
@@ -0,0 +1,6 @@
+{
+ "type": "dlp-configuration-clear",
+ "eventId": 0,
+ "aggregateId":"DLPRule/james.org",
+ "configurationItems": []
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/items_removed_event_2.json
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/items_removed_event_2.json b/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/items_removed_event_2.json
new file mode 100644
index 0000000..7185898
--- /dev/null
+++ b/server/data/data-cassandra/src/test/resources/json/dlp/eventsourcing/items_removed_event_2.json
@@ -0,0 +1,30 @@
+{
+ "type": "dlp-configuration-clear",
+ "eventId": 0,
+ "aggregateId":"DLPRule/james.org",
+ "configurationItems": [
+  {
+   "id": "1",
+   "explanation": "Find whatever contains james.org",
+   "expression": "james.org",
+   "targetsContent": true,
+   "targetsSender": true,
+   "targetsRecipients": true
+  },
+  {
+   "id": "2",
+   "explanation": "Find senders have domain apache.org",
+   "expression": "apache.org",
+   "targetsContent": false,
+   "targetsSender": true,
+   "targetsRecipients": false
+  },
+  {
+   "id": "3",
+   "expression": "linagora.org",
+   "targetsContent": true,
+   "targetsSender": true,
+   "targetsRecipients": false
+  }
+ ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/dc5cefcd/server/data/data-library/src/main/java/org/apache/james/dlp/eventsourcing/aggregates/DLPAggregateId.java
----------------------------------------------------------------------
diff --git a/server/data/data-library/src/main/java/org/apache/james/dlp/eventsourcing/aggregates/DLPAggregateId.java b/server/data/data-library/src/main/java/org/apache/james/dlp/eventsourcing/aggregates/DLPAggregateId.java
index 9e4a61b..f1e3120 100644
--- a/server/data/data-library/src/main/java/org/apache/james/dlp/eventsourcing/aggregates/DLPAggregateId.java
+++ b/server/data/data-library/src/main/java/org/apache/james/dlp/eventsourcing/aggregates/DLPAggregateId.java
@@ -30,6 +30,13 @@ public class DLPAggregateId implements AggregateId {
     private static final String SEPARATOR = "/";
     private static final String PREFIX = "DLPRule";
 
+    public static final DLPAggregateId parse(String rawString) {
+        Preconditions.checkArgument(rawString.startsWith(PREFIX + SEPARATOR));
+
+        return new DLPAggregateId(Domain.of(
+            rawString.substring(PREFIX.length() + SEPARATOR.length())));
+    }
+
     private final Domain domain;
 
     public DLPAggregateId(Domain domain) {


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