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

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

commit 1af080d298d8b4a0a97335b1650f38d5af21372b
Author: Matthieu Baechler <[email protected]>
AuthorDate: Mon Oct 21 16:08:50 2019 +0200

    JAMES-2813 handle nested AdditionInformation
---
 .../eventstore/cassandra/JsonEventSerializer.java  |  9 +--
 .../cassandra/CassandraEventStoreExtension.java    |  4 +-
 .../cassandra/JsonEventSerializerTest.java         |  1 +
 .../java/org/apache/james/json/DTOConverter.java   | 12 ++--
 .../apache/james/json/JsonGenericSerializer.java   |  9 +--
 .../james/modules/TaskSerializationModule.java     | 28 +++++----
 ...ventSourcingDLPConfigurationStoreExtension.java |  3 +-
 .../CassandraMailQueueViewTestFactory.java         |  2 +-
 .../distributed/TasksSerializationModule.java      | 40 ++++++------
 .../eventsourcing/distributed/TaskEventDTO.scala   | 72 ++++++++++++----------
 .../distributed/DistributedTaskManagerTest.java    | 10 ++-
 .../RabbitMQTerminationSubscriberTest.java         | 10 ++-
 .../distributed/TaskEventsSerializationTest.java   | 29 +++++----
 .../JsonTaskAdditionalInformationSerializer.java   |  5 +-
 .../james/server/task/json/JsonTaskSerializer.java |  8 +--
 15 files changed, 136 insertions(+), 106 deletions(-)

diff --git 
a/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.java
 
b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.java
index 0bc17a1..15f8005 100644
--- 
a/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.java
+++ 
b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.java
@@ -27,6 +27,8 @@ import javax.inject.Inject;
 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 org.apache.james.json.DTOConverter;
+import org.apache.james.json.DTOModule;
 import org.apache.james.json.JsonGenericSerializer;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -49,13 +51,12 @@ public class JsonEventSerializer {
     private JsonGenericSerializer<Event, EventDTO> jsonGenericSerializer;
 
     @Inject
-    public JsonEventSerializer(Set<EventDTOModule<?, ?>> modules) {
-        //FIXME
-        jsonGenericSerializer = new JsonGenericSerializer(modules, null);
+    public JsonEventSerializer(DTOConverter<Event, EventDTO> converter, 
Set<EventDTOModule<?, ?>> modules, Set<DTOModule<?, ?>> nestedTypesModules) {
+        jsonGenericSerializer = new JsonGenericSerializer<>(modules, 
nestedTypesModules, converter);
     }
     
     public JsonEventSerializer(EventDTOModule<?, ?>... modules) {
-        this(ImmutableSet.copyOf(modules));
+        this(new DTOConverter<>(ImmutableSet.copyOf(modules)), 
ImmutableSet.copyOf(modules), ImmutableSet.of());
     }
 
     public String serialize(Event event) throws JsonProcessingException {
diff --git 
a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreExtension.java
 
b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreExtension.java
index f9372c2..bed4553 100644
--- 
a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreExtension.java
+++ 
b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreExtension.java
@@ -19,12 +19,12 @@
 
 package org.apache.james.eventsourcing.eventstore.cassandra;
 
-import java.util.Arrays;
 import java.util.Set;
 
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
 import org.apache.james.eventsourcing.eventstore.EventStore;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
+import org.apache.james.json.DTOConverter;
 import org.junit.jupiter.api.extension.AfterAllCallback;
 import org.junit.jupiter.api.extension.AfterEachCallback;
 import org.junit.jupiter.api.extension.BeforeAllCallback;
@@ -63,7 +63,7 @@ public class CassandraEventStoreExtension implements 
BeforeAllCallback, AfterAll
 
     @Override
     public void beforeEach(ExtensionContext context) {
-        JsonEventSerializer jsonEventSerializer = new 
JsonEventSerializer(modules);
+        JsonEventSerializer jsonEventSerializer = new 
JsonEventSerializer(modules.toArray(new EventDTOModule[0]));
 
         eventStoreDao = new 
EventStoreDao(cassandra.getCassandraCluster().getConf(), jsonEventSerializer);
     }
diff --git 
a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializerTest.java
 
b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializerTest.java
index d042a44..043532a 100644
--- 
a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializerTest.java
+++ 
b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializerTest.java
@@ -28,6 +28,7 @@ import org.apache.james.eventsourcing.TestAggregateId;
 import org.apache.james.eventsourcing.TestEvent;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.OtherEvent;
 import 
org.apache.james.eventsourcing.eventstore.cassandra.dto.TestEventDTOModules;
+import org.apache.james.json.DTOModule;
 import org.junit.jupiter.api.Test;
 
 class JsonEventSerializerTest {
diff --git a/json/src/main/java/org/apache/james/json/DTOConverter.java 
b/json/src/main/java/org/apache/james/json/DTOConverter.java
index 1fe27f3..d49b623 100644
--- a/json/src/main/java/org/apache/james/json/DTOConverter.java
+++ b/json/src/main/java/org/apache/james/json/DTOConverter.java
@@ -29,15 +29,15 @@ import com.google.common.collect.ImmutableSet;
 
 public class DTOConverter<T, U extends DTO> {
 
-    private final Map<String, DTOModule<T, U>> typeToModule;
-    private final Map<Class<? extends T>, DTOModule<T, U>> domainClassToModule;
+    private final Map<String, DTOModule<? extends T, ? extends U>> 
typeToModule;
+    private final Map<Class<? extends T>, DTOModule<? extends T, ? extends U>> 
domainClassToModule;
 
     @SafeVarargs
-    public static <T, U extends DTO> DTOConverter<T, U> of(DTOModule<T, U>... 
modules) {
+    public static <T, U extends DTO> DTOConverter<T, U> of(DTOModule<? extends 
T, ? extends U>... modules) {
         return new DTOConverter<>(ImmutableSet.copyOf(modules));
     }
 
-    public DTOConverter(Set<DTOModule<T, U>> modules) {
+    public DTOConverter(Set<? extends DTOModule<? extends T, ? extends U>> 
modules) {
         typeToModule = modules.stream()
             .collect(Guavate.toImmutableMap(
                 DTOModule::getDomainObjectType,
@@ -49,16 +49,20 @@ public class DTOConverter<T, U extends DTO> {
                 Function.identity()));
     }
 
+    @SuppressWarnings("unchecked")
     public Optional<U> convert(T domainObject) {
         return Optional
             .ofNullable(domainClassToModule.get(domainObject.getClass()))
+            .map(module -> (DTOModule<T, U>) module)
             .map(module -> module.toDTO(domainObject));
     }
 
+    @SuppressWarnings("unchecked")
     public Optional<T> convert(U dto) {
         String type = dto.getType();
         return Optional
             .ofNullable(typeToModule.get(type))
+            .map(module -> (DTOModule<T, U>) module)
             .map(DTOModule::getToDomainObjectConverter)
             .map(convert -> convert.convert(dto));
     }
diff --git 
a/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java 
b/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
index ceb3066..a9cfdcc 100644
--- a/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
+++ b/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
@@ -35,6 +35,7 @@ import com.fasterxml.jackson.datatype.guava.GuavaModule;
 import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
 
 public class JsonGenericSerializer<T, U extends DTO> {
 
@@ -59,15 +60,15 @@ public class JsonGenericSerializer<T, U extends DTO> {
 
     @SafeVarargs
     public static <T, U extends DTO> JsonGenericSerializer<T, U> 
of(DTOModule<T, U>... modules) {
-        return new JsonGenericSerializer<>(ImmutableSet.copyOf(modules), 
DTOConverter.of(modules));
+        return new JsonGenericSerializer<>(ImmutableSet.copyOf(modules), 
ImmutableSet.of(), DTOConverter.of(modules));
     }
 
-    public JsonGenericSerializer(Set<DTOModule<T, U>> modules, DTOConverter<T, 
U> converter) {
+    public JsonGenericSerializer(Set<? extends DTOModule<? extends T, ? 
extends U>> modules, Set<? extends DTOModule<?, ?>> nestedTypesModules, 
DTOConverter<T, U> converter) {
         this.dtoConverter = converter;
-        this.objectMapper = buildObjectMapper(modules);
+        this.objectMapper = buildObjectMapper(Sets.union(modules, 
nestedTypesModules));
     }
 
-    private ObjectMapper buildObjectMapper(Set<DTOModule<T, U>> modules) {
+    private ObjectMapper buildObjectMapper(Set<? extends DTOModule<?, ?>> 
modules) {
         ObjectMapper objectMapper = new ObjectMapper()
             .registerModule(new Jdk8Module())
             .registerModule(new JavaTimeModule())
diff --git 
a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/TaskSerializationModule.java
 
b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/TaskSerializationModule.java
index 6c8fc00..cea90ed 100644
--- 
a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/TaskSerializationModule.java
+++ 
b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/TaskSerializationModule.java
@@ -24,6 +24,7 @@ import 
org.apache.james.backends.cassandra.migration.MigrationTask;
 import 
org.apache.james.backends.cassandra.migration.MigrationTaskAdditionalInformationDTO;
 import org.apache.james.backends.cassandra.migration.MigrationTaskDTO;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
+import org.apache.james.json.DTOConverter;
 import 
org.apache.james.mailbox.cassandra.mail.task.MailboxMergingTaskAdditionalInformationDTO;
 import org.apache.james.mailbox.cassandra.mail.task.MailboxMergingTaskDTO;
 import org.apache.james.mailbox.cassandra.mail.task.MailboxMergingTaskRunner;
@@ -34,10 +35,11 @@ import org.apache.james.queue.api.ManageableMailQueue;
 import org.apache.james.rrt.cassandra.CassandraMappingsSourcesDAO;
 import org.apache.james.rrt.cassandra.migration.MappingsSourcesMigration;
 import 
org.apache.james.rrt.cassandra.migration.MappingsSourcesMigrationTaskAdditionalInformationDTO;
-import 
org.apache.james.server.task.json.JsonTaskAdditionalInformationSerializer;
 import org.apache.james.server.task.json.JsonTaskSerializer;
+import org.apache.james.server.task.json.dto.AdditionalInformationDTO;
 import org.apache.james.server.task.json.dto.AdditionalInformationDTOModule;
 import org.apache.james.server.task.json.dto.TaskDTOModule;
+import org.apache.james.task.TaskExecutionDetails;
 import 
org.apache.james.task.eventsourcing.distributed.TasksSerializationModule;
 import org.apache.james.vault.blob.BlobStoreVaultGarbageCollectionTask;
 import 
org.apache.james.vault.blob.BlobStoreVaultGarbageCollectionTaskAdditionalInformationDTO;
@@ -91,33 +93,33 @@ import com.google.inject.multibindings.ProvidesIntoSet;
 public class TaskSerializationModule extends AbstractModule {
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskCreatedSerialization(JsonTaskSerializer 
jsonTaskSerializer, JsonTaskAdditionalInformationSerializer 
jsonTaskAdditionalInformationSerializer) {
-        return TasksSerializationModule.CREATED.create(jsonTaskSerializer, 
jsonTaskAdditionalInformationSerializer);
+    public EventDTOModule<?, ?> taskCreatedSerialization(JsonTaskSerializer 
jsonTaskSerializer, DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter) {
+        return TasksSerializationModule.CREATED.create(jsonTaskSerializer, 
additionalInformationConverter);
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskStartedSerialization(JsonTaskSerializer 
jsonTaskSerializer, JsonTaskAdditionalInformationSerializer 
jsonTaskAdditionalInformationSerializer) {
-        return TasksSerializationModule.STARTED.create(jsonTaskSerializer, 
jsonTaskAdditionalInformationSerializer);
+    public EventDTOModule<?, ?> taskStartedSerialization(JsonTaskSerializer 
jsonTaskSerializer, DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter) {
+        return TasksSerializationModule.STARTED.create(jsonTaskSerializer, 
additionalInformationConverter);
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> 
taskCancelRequestedSerialization(JsonTaskSerializer jsonTaskSerializer, 
JsonTaskAdditionalInformationSerializer 
jsonTaskAdditionalInformationSerializer) {
-        return 
TasksSerializationModule.CANCEL_REQUESTED.create(jsonTaskSerializer, 
jsonTaskAdditionalInformationSerializer);
+    public EventDTOModule<?, ?> 
taskCancelRequestedSerialization(JsonTaskSerializer jsonTaskSerializer, 
DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter) {
+        return 
TasksSerializationModule.CANCEL_REQUESTED.create(jsonTaskSerializer, 
additionalInformationConverter);
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskCancelledSerialization(JsonTaskSerializer 
jsonTaskSerializer, JsonTaskAdditionalInformationSerializer 
jsonTaskAdditionalInformationSerializer) {
-        return TasksSerializationModule.CANCELLED.create(jsonTaskSerializer, 
jsonTaskAdditionalInformationSerializer);
+    public EventDTOModule<?, ?> taskCancelledSerialization(JsonTaskSerializer 
jsonTaskSerializer, DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter) {
+        return TasksSerializationModule.CANCELLED.create(jsonTaskSerializer, 
additionalInformationConverter);
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskCompletedSerialization(JsonTaskSerializer 
jsonTaskSerializer, JsonTaskAdditionalInformationSerializer 
jsonTaskAdditionalInformationSerializer) {
-        return TasksSerializationModule.COMPLETED.create(jsonTaskSerializer, 
jsonTaskAdditionalInformationSerializer);
+    public EventDTOModule<?, ?> taskCompletedSerialization(JsonTaskSerializer 
jsonTaskSerializer, DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter) {
+        return TasksSerializationModule.COMPLETED.create(jsonTaskSerializer, 
additionalInformationConverter);
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskFailedSerialization(JsonTaskSerializer 
jsonTaskSerializer, JsonTaskAdditionalInformationSerializer 
jsonTaskAdditionalInformationSerializer) {
-        return TasksSerializationModule.FAILED.create(jsonTaskSerializer, 
jsonTaskAdditionalInformationSerializer);
+    public EventDTOModule<?, ?> taskFailedSerialization(JsonTaskSerializer 
jsonTaskSerializer, DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter) {
+        return TasksSerializationModule.FAILED.create(jsonTaskSerializer, 
additionalInformationConverter);
     }
 
     @ProvidesIntoSet
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
index f47b2cb..bc81db2 100644
--- 
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
@@ -73,9 +73,8 @@ public class 
CassandraEventSourcingDLPConfigurationStoreExtension implements Bef
     @Override
     public Object resolveParameter(ParameterContext parameterContext, 
ExtensionContext extensionContext) throws ParameterResolutionException {
         JsonEventSerializer jsonEventSerializer = new JsonEventSerializer(
-            ImmutableSet.of(
                 DLPConfigurationModules.DLP_CONFIGURATION_STORE,
-                DLPConfigurationModules.DLP_CONFIGURATION_CLEAR));
+                DLPConfigurationModules.DLP_CONFIGURATION_CLEAR);
 
         EventStoreDao eventStoreDao = new EventStoreDao(
             cassandra.getConf(),
diff --git 
a/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/CassandraMailQueueViewTestFactory.java
 
b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/CassandraMailQueueViewTestFactory.java
index 4181be1..5ce44f7 100644
--- 
a/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/CassandraMailQueueViewTestFactory.java
+++ 
b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/CassandraMailQueueViewTestFactory.java
@@ -54,7 +54,7 @@ public class CassandraMailQueueViewTestFactory {
 
 
         EventsourcingConfigurationManagement 
eventsourcingConfigurationManagement = new 
EventsourcingConfigurationManagement(new CassandraEventStore(new 
EventStoreDao(session,
-            new 
JsonEventSerializer(ImmutableSet.of(CassandraMailQueueViewConfigurationModule.MAIL_QUEUE_VIEW_CONFIGURATION)))));
+            new 
JsonEventSerializer(CassandraMailQueueViewConfigurationModule.MAIL_QUEUE_VIEW_CONFIGURATION))));
 
         return new CassandraMailQueueView.Factory(
             cassandraMailQueueMailStore,
diff --git 
a/server/task/task-distributed/src/main/java/org/apache/james/task/eventsourcing/distributed/TasksSerializationModule.java
 
b/server/task/task-distributed/src/main/java/org/apache/james/task/eventsourcing/distributed/TasksSerializationModule.java
index 2e56172..f613479 100644
--- 
a/server/task/task-distributed/src/main/java/org/apache/james/task/eventsourcing/distributed/TasksSerializationModule.java
+++ 
b/server/task/task-distributed/src/main/java/org/apache/james/task/eventsourcing/distributed/TasksSerializationModule.java
@@ -23,8 +23,10 @@ import java.util.Set;
 import java.util.stream.Stream;
 
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
-import 
org.apache.james.server.task.json.JsonTaskAdditionalInformationSerializer;
+import org.apache.james.json.DTOConverter;
 import org.apache.james.server.task.json.JsonTaskSerializer;
+import org.apache.james.server.task.json.dto.AdditionalInformationDTO;
+import org.apache.james.task.TaskExecutionDetails;
 import org.apache.james.task.eventsourcing.AdditionalInformationUpdated;
 import org.apache.james.task.eventsourcing.CancelRequested;
 import org.apache.james.task.eventsourcing.Cancelled;
@@ -38,10 +40,10 @@ import com.github.steveash.guavate.Guavate;
 public interface TasksSerializationModule {
     @FunctionalInterface
     interface TaskSerializationModuleFactory {
-        EventDTOModule<?, ?> create(JsonTaskSerializer taskSerializer, 
JsonTaskAdditionalInformationSerializer additionalInformationSerializer);
+        EventDTOModule<?, ?> create(JsonTaskSerializer taskSerializer, 
DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter);
     }
 
-    TaskSerializationModuleFactory CREATED = (jsonTaskSerializer, 
additionalInformationSerializer) -> EventDTOModule
+    TaskSerializationModuleFactory CREATED = (jsonTaskSerializer, 
additionalInformationConverter) -> EventDTOModule
         .forEvent(Created.class)
         .convertToDTO(CreatedDTO.class)
         .toDomainObjectConverter(dto -> dto.toDomainObject(jsonTaskSerializer))
@@ -49,7 +51,7 @@ public interface TasksSerializationModule {
         .typeName("task-manager-created")
         .withFactory(EventDTOModule::new);
 
-    TaskSerializationModuleFactory STARTED = (jsonTaskSerializer, 
additionalInformationSerializer) -> EventDTOModule
+    TaskSerializationModuleFactory STARTED = (jsonTaskSerializer, 
additionalInformationConverter) -> EventDTOModule
         .forEvent(Started.class)
         .convertToDTO(StartedDTO.class)
         .toDomainObjectConverter(StartedDTO::toDomainObject)
@@ -57,7 +59,7 @@ public interface TasksSerializationModule {
         .typeName("task-manager-started")
         .withFactory(EventDTOModule::new);
 
-    TaskSerializationModuleFactory CANCEL_REQUESTED = (jsonTaskSerializer, 
additionalInformationSerializer) -> EventDTOModule
+    TaskSerializationModuleFactory CANCEL_REQUESTED = (jsonTaskSerializer, 
additionalInformationConverter) -> EventDTOModule
         .forEvent(CancelRequested.class)
         .convertToDTO(CancelRequestedDTO.class)
         .toDomainObjectConverter(CancelRequestedDTO::toDomainObject)
@@ -65,42 +67,42 @@ public interface TasksSerializationModule {
         .typeName("task-manager-cancel-requested")
         .withFactory(EventDTOModule::new);
 
-    TaskSerializationModuleFactory COMPLETED = (jsonTaskSerializer, 
additionalInformationSerializer) -> EventDTOModule
+    TaskSerializationModuleFactory COMPLETED = (jsonTaskSerializer, 
additionalInformationConverter) -> EventDTOModule
         .forEvent(Completed.class)
         .convertToDTO(CompletedDTO.class)
-        .toDomainObjectConverter(dto -> 
dto.toDomainObject(additionalInformationSerializer))
-        .toDTOConverter((event, typeName) -> 
CompletedDTO.fromDomainObject(additionalInformationSerializer, event, typeName))
+        .toDomainObjectConverter(dto -> 
dto.toDomainObject(additionalInformationConverter))
+        .toDTOConverter((event, typeName) -> 
CompletedDTO.fromDomainObject(additionalInformationConverter, event, typeName))
         .typeName("task-manager-completed")
         .withFactory(EventDTOModule::new);
 
-    TaskSerializationModuleFactory FAILED = (jsonTaskSerializer, 
additionalInformationSerializer) -> EventDTOModule
+    TaskSerializationModuleFactory FAILED = (jsonTaskSerializer, 
additionalInformationConverter) -> EventDTOModule
         .forEvent(Failed.class)
         .convertToDTO(FailedDTO.class)
-        .toDomainObjectConverter(dto -> 
dto.toDomainObject(additionalInformationSerializer))
-        .toDTOConverter((event, typeName) -> 
FailedDTO.fromDomainObject(additionalInformationSerializer, event, typeName))
+        .toDomainObjectConverter(dto -> 
dto.toDomainObject(additionalInformationConverter))
+        .toDTOConverter((event, typeName) -> 
FailedDTO.fromDomainObject(additionalInformationConverter, event, typeName))
         .typeName("task-manager-failed")
         .withFactory(EventDTOModule::new);
 
-    TaskSerializationModuleFactory CANCELLED = (jsonTaskSerializer, 
additionalInformationSerializer) -> EventDTOModule
+    TaskSerializationModuleFactory CANCELLED = (jsonTaskSerializer, 
additionalInformationConverter) -> EventDTOModule
         .forEvent(Cancelled.class)
         .convertToDTO(CancelledDTO.class)
-        .toDomainObjectConverter(dto -> 
dto.toDomainObject(additionalInformationSerializer))
-        .toDTOConverter((event, typeName) -> 
CancelledDTO.fromDomainObject(additionalInformationSerializer, event, typeName))
+        .toDomainObjectConverter(dto -> 
dto.toDomainObject(additionalInformationConverter))
+        .toDTOConverter((event, typeName) -> 
CancelledDTO.fromDomainObject(additionalInformationConverter, event, typeName))
         .typeName("task-manager-cancelled")
         .withFactory(EventDTOModule::new);
 
-    TaskSerializationModuleFactory UPDATED = (jsonTaskSerializer, 
additionalInformationSerializer) -> EventDTOModule
+    TaskSerializationModuleFactory UPDATED = (jsonTaskSerializer, 
additionalInformationConverter) -> EventDTOModule
         .forEvent(AdditionalInformationUpdated.class)
         .convertToDTO(AdditionalInformationUpdatedDTO.class)
-        .toDomainObjectConverter(dto -> 
dto.toDomainObject(additionalInformationSerializer))
-        .toDTOConverter((event, typeName) -> 
AdditionalInformationUpdatedDTO.fromDomainObject(additionalInformationSerializer,
 event, typeName))
+        .toDomainObjectConverter(dto -> 
dto.toDomainObject(additionalInformationConverter))
+        .toDTOConverter((event, typeName) -> 
AdditionalInformationUpdatedDTO.fromDomainObject(additionalInformationConverter,
 event, typeName))
         .typeName("task-manager-updated")
         .withFactory(EventDTOModule::new);
 
-    static Set<EventDTOModule<?, ?>> list(JsonTaskSerializer 
jsonTaskSerializer, JsonTaskAdditionalInformationSerializer 
jsonTaskAdditionalInformationSerializer) {
+    static Set<EventDTOModule<?, ?>> list(JsonTaskSerializer 
jsonTaskSerializer, DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter) {
         return Stream
             .of(CREATED, STARTED, CANCEL_REQUESTED, CANCELLED, COMPLETED, 
FAILED, UPDATED)
-            .map(moduleFactory -> moduleFactory.create(jsonTaskSerializer, 
jsonTaskAdditionalInformationSerializer))
+            .map(moduleFactory -> moduleFactory.create(jsonTaskSerializer, 
additionalInformationConverter))
             .collect(Guavate.toImmutableSet());
     }
 }
diff --git 
a/server/task/task-distributed/src/main/scala/org/apache/james/task/eventsourcing/distributed/TaskEventDTO.scala
 
b/server/task/task-distributed/src/main/scala/org/apache/james/task/eventsourcing/distributed/TaskEventDTO.scala
index fb0e104..51761ad 100644
--- 
a/server/task/task-distributed/src/main/scala/org/apache/james/task/eventsourcing/distributed/TaskEventDTO.scala
+++ 
b/server/task/task-distributed/src/main/scala/org/apache/james/task/eventsourcing/distributed/TaskEventDTO.scala
@@ -20,19 +20,28 @@
 package org.apache.james.task.eventsourcing.distributed
 
 import java.util.Optional
+import java.util.function.Function
 
 import com.fasterxml.jackson.annotation.JsonProperty
 import org.apache.james.eventsourcing.EventId
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO
-import 
org.apache.james.server.task.json.{JsonTaskAdditionalInformationSerializer, 
JsonTaskSerializer}
+import org.apache.james.json.DTOConverter
+import org.apache.james.server.task.json.JsonTaskSerializer
+import org.apache.james.server.task.json.dto.AdditionalInformationDTO
 import org.apache.james.task.eventsourcing._
-import org.apache.james.task.{Hostname, Task, TaskId}
+import 
org.apache.james.task.eventsourcing.distributed.distributed.AdditionalInformationConverter
+import org.apache.james.task.{Hostname, Task, TaskExecutionDetails, TaskId}
 
 import scala.compat.java8.OptionConverters._
 
+package object distributed {
+  type AdditionalInformationConverter = 
DTOConverter[TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO]
+}
+
 sealed abstract class TaskEventDTO(val getType: String, val getAggregate: 
String, val getEvent: Int) extends EventDTO {
   protected def domainAggregateId: TaskAggregateId = 
TaskAggregateId(TaskId.fromString(getAggregate))
   protected def domainEventId: EventId = EventId.fromSerialized(getEvent)
+
 }
 
 case class CreatedDTO(@JsonProperty("type") typeName: String,
@@ -79,12 +88,11 @@ case class CompletedDTO(@JsonProperty("type") typeName: 
String,
                         @JsonProperty("aggregate") aggregateId: String,
                         @JsonProperty("event") eventId: Int,
                         @JsonProperty("result") getResult: String,
-                        @JsonProperty("additionalInformation") 
getAdditionalInformation: Optional[String])
+                        @JsonProperty("additionalInformation") 
getAdditionalInformation: Optional[AdditionalInformationDTO])
   extends TaskEventDTO(typeName, aggregateId, eventId) {
-  def toDomainObject(jsonTaskAdditionalInformationSerializer: 
JsonTaskAdditionalInformationSerializer): Completed = {
-    val deserializedAdditionalInformation = 
getAdditionalInformation.asScala.map(jsonTaskAdditionalInformationSerializer.deserialize)
-    Completed(domainAggregateId, domainEventId, domainResult, 
deserializedAdditionalInformation)
-
+  def toDomainObject(additionalInformationConverter: 
AdditionalInformationConverter): Completed = {
+    val additionalInformation: 
Optional[TaskExecutionDetails.AdditionalInformation] = 
getAdditionalInformation.map(additionalInformationConverter.convert(_).orElseThrow())
+    Completed(domainAggregateId, domainEventId, domainResult, 
additionalInformation.asScala)
   }
   private def domainResult: Task.Result = getResult match {
     case "COMPLETED" => Task.Result.COMPLETED
@@ -93,9 +101,9 @@ case class CompletedDTO(@JsonProperty("type") typeName: 
String,
 }
 
 object CompletedDTO {
-  def fromDomainObject(jsonTaskAdditionalInformationSerializer: 
JsonTaskAdditionalInformationSerializer)(event: Completed, typeName: String): 
CompletedDTO = {
-    val serializedAdditionalInformation = 
event.additionalInformation.map(jsonTaskAdditionalInformationSerializer.serialize).asJava
-    CompletedDTO(typeName, event.aggregateId.taskId.asString(), 
event.eventId.serialize(), resultToString(event.result), 
serializedAdditionalInformation)
+  def fromDomainObject(dtoConverter: AdditionalInformationConverter)(event: 
Completed, typeName: String): CompletedDTO = {
+    val additionalInformationDTO: Optional[AdditionalInformationDTO] = 
event.additionalInformation.asJava.map(dtoConverter.convert(_).orElseThrow())
+    CompletedDTO(typeName, event.aggregateId.taskId.asString(), 
event.eventId.serialize(), resultToString(event.result), 
additionalInformationDTO)
   }
 
   private def resultToString(result: Task.Result): String = result match {
@@ -107,55 +115,57 @@ object CompletedDTO {
 case class FailedDTO(@JsonProperty("type") typeName: String,
                      @JsonProperty("aggregate") aggregateId: String,
                      @JsonProperty("event") eventId: Int,
-                     @JsonProperty("additionalInformation") 
getAdditionalInformation: Optional[String],
+                     @JsonProperty("additionalInformation") 
getAdditionalInformation: Optional[AdditionalInformationDTO],
                      @JsonProperty("errorMessage") getErrorMessage: 
Optional[String],
                      @JsonProperty("exception") getException: Optional[String])
   extends TaskEventDTO(typeName, aggregateId, eventId) {
-  def toDomainObject(jsonTaskAdditionalInformationSerializer: 
JsonTaskAdditionalInformationSerializer): Failed = {
-    val deserializedAdditionalInformation = 
getAdditionalInformation.asScala.map(jsonTaskAdditionalInformationSerializer.deserialize)
-    Failed(domainAggregateId, domainEventId, 
deserializedAdditionalInformation, getErrorMessage.asScala, 
getException.asScala)
+  def toDomainObject(additionalInformationConverter: 
AdditionalInformationConverter): Failed = {
+    val additionalInformation: 
Optional[TaskExecutionDetails.AdditionalInformation] = 
getAdditionalInformation.map(additionalInformationConverter.convert(_).orElseThrow())
+    Failed(domainAggregateId, domainEventId, additionalInformation.asScala, 
getErrorMessage.asScala, getException.asScala)
   }
 }
 
 object FailedDTO {
-  def fromDomainObject(jsonTaskAdditionalInformationSerializer: 
JsonTaskAdditionalInformationSerializer)(event: Failed, typeName: String): 
FailedDTO = {
-    val serializedAdditionalInformation = 
event.additionalInformation.map(jsonTaskAdditionalInformationSerializer.serialize).asJava
-    FailedDTO(typeName, event.aggregateId.taskId.asString(), 
event.eventId.serialize(), serializedAdditionalInformation, 
event.errorMessage.asJava, event.exception.asJava)
+  def fromDomainObject(dtoConverter: AdditionalInformationConverter)(event: 
Failed, typeName: String): FailedDTO = {
+    val additionalInformationDTO: Optional[AdditionalInformationDTO] = 
event.additionalInformation.asJava.map(dtoConverter.convert(_).orElseThrow())
+    FailedDTO(typeName, event.aggregateId.taskId.asString(), 
event.eventId.serialize(), additionalInformationDTO, event.errorMessage.asJava, 
event.exception.asJava)
   }
 }
 
 case class CancelledDTO(@JsonProperty("type") typeName: String,
                         @JsonProperty("aggregate") aggregateId: String,
                         @JsonProperty("event") eventId: Int,
-                        @JsonProperty("additionalInformation") 
getAdditionalInformation: Optional[String])
+                        @JsonProperty("additionalInformation") 
getAdditionalInformation: Optional[AdditionalInformationDTO])
   extends TaskEventDTO(typeName, aggregateId, eventId) {
-  def toDomainObject(jsonTaskAdditionalInformationSerializer: 
JsonTaskAdditionalInformationSerializer): Cancelled = {
-    val deserializedAdditionalInformation = 
getAdditionalInformation.asScala.map(jsonTaskAdditionalInformationSerializer.deserialize)
-    Cancelled(domainAggregateId, domainEventId, 
deserializedAdditionalInformation)
+  def toDomainObject(additionalInformationConverter: 
AdditionalInformationConverter): Cancelled = {
+    val additionalInformation: 
Optional[TaskExecutionDetails.AdditionalInformation] = 
getAdditionalInformation.map(additionalInformationConverter.convert(_).orElseThrow())
+    Cancelled(domainAggregateId, domainEventId, additionalInformation.asScala)
   }
 }
 
 object CancelledDTO {
-  def fromDomainObject(jsonTaskAdditionalInformationSerializer: 
JsonTaskAdditionalInformationSerializer)(event: Cancelled, typeName: String): 
CancelledDTO = {
-    val serializedAdditionalInformation = 
event.additionalInformation.map(jsonTaskAdditionalInformationSerializer.serialize).asJava
-    CancelledDTO(typeName, event.aggregateId.taskId.asString(), 
event.eventId.serialize(), serializedAdditionalInformation)
+  def fromDomainObject(additionalInformationConverter: 
AdditionalInformationConverter)(event: Cancelled, typeName: String): 
CancelledDTO = {
+    val additionalInformationDTO: Optional[AdditionalInformationDTO] = 
event.additionalInformation.asJava.map(additionalInformationConverter.convert(_).orElseThrow())
+    CancelledDTO(typeName, event.aggregateId.taskId.asString(), 
event.eventId.serialize(), additionalInformationDTO)
   }
 }
 
 case class AdditionalInformationUpdatedDTO(@JsonProperty("type") typeName: 
String,
                      @JsonProperty("aggregate") aggregateId: String,
                      @JsonProperty("event") eventId: Int,
-                     @JsonProperty("additionalInformation") 
getAdditionalInformation: String)
+                     @JsonProperty("additionalInformation") 
getAdditionalInformation: AdditionalInformationDTO)
   extends TaskEventDTO(typeName, aggregateId, eventId) {
-  def toDomainObject(jsonTaskAdditionalInformationSerializer: 
JsonTaskAdditionalInformationSerializer): AdditionalInformationUpdated = {
-    val deserializedAdditionalInformation = 
jsonTaskAdditionalInformationSerializer.deserialize(getAdditionalInformation)
-    AdditionalInformationUpdated(domainAggregateId, domainEventId, 
deserializedAdditionalInformation)
+  def toDomainObject(additionalInformationConverter: 
AdditionalInformationConverter): AdditionalInformationUpdated = {
+    val additionalInformation = 
additionalInformationConverter.convert(getAdditionalInformation)
+        .orElseThrow()
+    AdditionalInformationUpdated(domainAggregateId, domainEventId, 
additionalInformation)
   }
 }
 
 object AdditionalInformationUpdatedDTO {
-  def fromDomainObject(jsonTaskAdditionalInformationSerializer: 
JsonTaskAdditionalInformationSerializer)(event: AdditionalInformationUpdated, 
typeName: String): AdditionalInformationUpdatedDTO = {
-    val serializedAdditionalInformation = 
jsonTaskAdditionalInformationSerializer.serialize(event.additionalInformation)
-    AdditionalInformationUpdatedDTO(typeName, 
event.aggregateId.taskId.asString(), event.eventId.serialize(), 
serializedAdditionalInformation)
+  def fromDomainObject(additionalInformationConverter: 
AdditionalInformationConverter)(event: AdditionalInformationUpdated, typeName: 
String): AdditionalInformationUpdatedDTO = {
+    val additionalInformationDTO = 
additionalInformationConverter.convert(event.additionalInformation)
+        .orElseThrow()
+    AdditionalInformationUpdatedDTO(typeName, 
event.aggregateId.taskId.asString(), event.eventId.serialize(), 
additionalInformationDTO)
   }
 }
diff --git 
a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/DistributedTaskManagerTest.java
 
b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/DistributedTaskManagerTest.java
index 73170a5..ff98f90 100644
--- 
a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/DistributedTaskManagerTest.java
+++ 
b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/DistributedTaskManagerTest.java
@@ -41,8 +41,10 @@ import 
org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStoreEx
 import 
org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStoreModule;
 import org.apache.james.eventsourcing.eventstore.cassandra.JsonEventSerializer;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
+import org.apache.james.json.DTOConverter;
 import 
org.apache.james.server.task.json.JsonTaskAdditionalInformationSerializer;
 import org.apache.james.server.task.json.JsonTaskSerializer;
+import org.apache.james.server.task.json.dto.AdditionalInformationDTO;
 import org.apache.james.server.task.json.dto.MemoryReferenceTaskStore;
 import 
org.apache.james.server.task.json.dto.MemoryReferenceWithCounterTaskAdditionalInformationDTO;
 import 
org.apache.james.server.task.json.dto.MemoryReferenceWithCounterTaskStore;
@@ -70,7 +72,7 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-import com.github.steveash.guavate.Guavate;
+import com.google.common.collect.ImmutableSet;
 
 class DistributedTaskManagerTest implements TaskManagerContract {
 
@@ -98,12 +100,14 @@ class DistributedTaskManagerTest implements 
TaskManagerContract {
     }
 
     static final JsonTaskAdditionalInformationSerializer 
JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = new 
JsonTaskAdditionalInformationSerializer(MemoryReferenceWithCounterTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
+    static final DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> DTO_CONVERTER = 
DTOConverter.of(MemoryReferenceWithCounterTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
     static final Hostname HOSTNAME = new Hostname("foo");
     static final Hostname HOSTNAME_2 = new Hostname("bar");
 
     @RegisterExtension
     static final RabbitMQExtension RABBIT_MQ_EXTENSION = 
RabbitMQExtension.singletonRabbitMQ();
 
+
     @RegisterExtension
     static final CassandraClusterExtension CASSANDRA_CLUSTER = new 
CassandraClusterExtension(
         CassandraModule.aggregateModules(
@@ -119,7 +123,7 @@ class DistributedTaskManagerTest implements 
TaskManagerContract {
         TestTaskDTOModules.MEMORY_REFERENCE_TASK_MODULE.apply(new 
MemoryReferenceTaskStore()),
         TestTaskDTOModules.MEMORY_REFERENCE_WITH_COUNTER_TASK_MODULE.apply(new 
MemoryReferenceWithCounterTaskStore()));
 
-    Set<EventDTOModule<?, ?>> eventDtoModule = 
TasksSerializationModule.list(taskSerializer, 
JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER).stream().collect(Guavate.toImmutableSet());
+    Set<EventDTOModule<?, ?>> eventDtoModule = 
TasksSerializationModule.list(taskSerializer, DTO_CONVERTER);
 
     @RegisterExtension
     CassandraEventStoreExtension eventStoreExtension = new 
CassandraEventStoreExtension(CASSANDRA_CLUSTER, eventDtoModule);
@@ -141,7 +145,7 @@ class DistributedTaskManagerTest implements 
TaskManagerContract {
         this.workQueueSupplier = new 
TrackedRabbitMQWorkQueueSupplier(RABBIT_MQ_EXTENSION.getRabbitChannelPool(), 
taskSerializer);
         this.eventStore = eventStore;
         this.terminationSubscribers = new ArrayList<>();
-        this.eventSerializer = new JsonEventSerializer(eventDtoModule);
+        this.eventSerializer = new JsonEventSerializer(new 
DTOConverter<>(eventDtoModule), eventDtoModule, ImmutableSet.of());
     }
 
     @AfterEach
diff --git 
a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/RabbitMQTerminationSubscriberTest.java
 
b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/RabbitMQTerminationSubscriberTest.java
index c736c50..db2c02b 100644
--- 
a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/RabbitMQTerminationSubscriberTest.java
+++ 
b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/RabbitMQTerminationSubscriberTest.java
@@ -31,7 +31,7 @@ import org.apache.james.backends.rabbitmq.RabbitMQExtension;
 import org.apache.james.eventsourcing.Event;
 import org.apache.james.eventsourcing.eventstore.cassandra.JsonEventSerializer;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
-import 
org.apache.james.server.task.json.JsonTaskAdditionalInformationSerializer;
+import org.apache.james.json.DTOConverter;
 import org.apache.james.server.task.json.JsonTaskSerializer;
 import org.apache.james.task.eventsourcing.TerminationSubscriber;
 import org.apache.james.task.eventsourcing.TerminationSubscriberContract;
@@ -39,15 +39,13 @@ import org.awaitility.Awaitility;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-import com.github.steveash.guavate.Guavate;
-
+import com.google.common.collect.ImmutableSet;
 import reactor.core.publisher.Flux;
 
 class RabbitMQTerminationSubscriberTest implements 
TerminationSubscriberContract {
     private static final JsonTaskSerializer TASK_SERIALIZER = new 
JsonTaskSerializer();
-    private static final JsonTaskAdditionalInformationSerializer 
JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = new 
JsonTaskAdditionalInformationSerializer();
-    private static final Set<EventDTOModule<?, ?>> MODULES = 
TasksSerializationModule.list(TASK_SERIALIZER, 
JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER).stream().collect(Guavate.toImmutableSet());
-    private static final JsonEventSerializer SERIALIZER = new 
JsonEventSerializer(MODULES);
+    private static final Set<EventDTOModule<?, ?>> MODULES = 
TasksSerializationModule.list(TASK_SERIALIZER, DTOConverter.of());
+    private static final JsonEventSerializer SERIALIZER = new 
JsonEventSerializer(new DTOConverter<>(MODULES), MODULES, ImmutableSet.of());
 
     @RegisterExtension
     static RabbitMQExtension rabbitMQExtension = 
RabbitMQExtension.singletonRabbitMQ();
diff --git 
a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/TaskEventsSerializationTest.java
 
b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/TaskEventsSerializationTest.java
index 1ad3921..4edfa51 100644
--- 
a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/TaskEventsSerializationTest.java
+++ 
b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/TaskEventsSerializationTest.java
@@ -22,12 +22,16 @@ package org.apache.james.task.eventsourcing.distributed;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.time.Instant;
+import java.util.Set;
 import java.util.stream.Stream;
 
 import org.apache.james.eventsourcing.EventId;
 import org.apache.james.eventsourcing.eventstore.cassandra.JsonEventSerializer;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
+import org.apache.james.json.DTOConverter;
 import 
org.apache.james.server.task.json.JsonTaskAdditionalInformationSerializer;
 import org.apache.james.server.task.json.JsonTaskSerializer;
+import org.apache.james.server.task.json.dto.AdditionalInformationDTO;
 import 
org.apache.james.server.task.json.dto.MemoryReferenceWithCounterTaskAdditionalInformationDTO;
 import 
org.apache.james.server.task.json.dto.MemoryReferenceWithCounterTaskStore;
 import org.apache.james.server.task.json.dto.TestTaskDTOModules;
@@ -35,6 +39,7 @@ import org.apache.james.task.CompletedTask;
 import org.apache.james.task.Hostname;
 import org.apache.james.task.MemoryReferenceWithCounterTask;
 import org.apache.james.task.Task;
+import org.apache.james.task.TaskExecutionDetails;
 import org.apache.james.task.TaskId;
 import org.apache.james.task.eventsourcing.CancelRequested;
 import org.apache.james.task.eventsourcing.Cancelled;
@@ -48,11 +53,13 @@ import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 
+import com.google.common.collect.ImmutableSet;
 import net.javacrumbs.jsonunit.assertj.JsonAssertions;
 import scala.Option;
 
 class TaskEventsSerializationTest {
     static final Instant TIMESTAMP = Instant.parse("2018-11-13T12:00:55Z");
+    static final DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> ADDITIONAL_INFORMATION_CONVERTER = 
DTOConverter.of(MemoryReferenceWithCounterTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
     static final JsonTaskAdditionalInformationSerializer 
TASK_ADDITIONNAL_INFORMATION_SERIALIZER = new 
JsonTaskAdditionalInformationSerializer(MemoryReferenceWithCounterTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
     static final TaskAggregateId AGGREGATE_ID = new 
TaskAggregateId(TaskId.fromString("2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd"));
     static final EventId EVENT_ID = EventId.fromSerialized(42);
@@ -60,13 +67,13 @@ class TaskEventsSerializationTest {
     static final Hostname HOSTNAME = new Hostname("foo");
     static final MemoryReferenceWithCounterTask.AdditionalInformation 
COUNTER_ADDITIONAL_INFORMATION = new 
MemoryReferenceWithCounterTask.AdditionalInformation(3, TIMESTAMP);
 
-    JsonEventSerializer serializer =
-        new JsonEventSerializer(
-            TasksSerializationModule.list(
-                new JsonTaskSerializer(
-                    TestTaskDTOModules.COMPLETED_TASK_MODULE,
-                    
TestTaskDTOModules.MEMORY_REFERENCE_WITH_COUNTER_TASK_MODULE.apply(new 
MemoryReferenceWithCounterTaskStore())),
-                TASK_ADDITIONNAL_INFORMATION_SERIALIZER));
+    private final Set<EventDTOModule<?, ?>> list = 
TasksSerializationModule.list(
+        new JsonTaskSerializer(
+            TestTaskDTOModules.COMPLETED_TASK_MODULE,
+            
TestTaskDTOModules.MEMORY_REFERENCE_WITH_COUNTER_TASK_MODULE.apply(new 
MemoryReferenceWithCounterTaskStore())),
+        ADDITIONAL_INFORMATION_CONVERTER);
+
+    JsonEventSerializer serializer = new JsonEventSerializer(new 
DTOConverter<>(list), list, 
ImmutableSet.of(MemoryReferenceWithCounterTaskAdditionalInformationDTO.SERIALIZATION_MODULE));
 
     @ParameterizedTest
     @MethodSource
@@ -98,10 +105,10 @@ class TaskEventsSerializationTest {
             Arguments.of(new Failed(AGGREGATE_ID, EVENT_ID, Option.empty(), 
Option.empty(), Option.empty()), 
"{\"aggregate\":\"2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd\",\"event\":42,\"type\":\"task-manager-failed\"}"),
             Arguments.of(new Failed(AGGREGATE_ID, EVENT_ID, Option.empty(), 
Option.apply("contextual message"), Option.apply("my exception")), 
"{\"aggregate\":\"2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd\",\"event\":42,\"type\":\"task-manager-failed\",
 \"errorMessage\": \"contextual message\", \"exception\": \"my exception\"}"),
             Arguments.of(new Cancelled(AGGREGATE_ID, EVENT_ID, 
Option.empty()), 
"{\"aggregate\":\"2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd\",\"event\":42,\"type\":\"task-manager-cancelled\"}"),
-            Arguments.of(new Completed(AGGREGATE_ID, EVENT_ID, 
Task.Result.COMPLETED, Option.apply(COUNTER_ADDITIONAL_INFORMATION)), 
"{\"result\":\"COMPLETED\",\"aggregate\":\"2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd\",\"event\":42,\"type\":\"task-manager-completed\",\"additionalInformation\":\"{\\\"type\\\":\\\"memory-reference-task-with-counter\\\",\\\"count\\\":3,\\\"timestamp\\\":\\\"2018-11-13T12:00:55Z\\\"}\"}"),
-            Arguments.of(new Completed(AGGREGATE_ID, EVENT_ID, 
Task.Result.PARTIAL, Option.apply(COUNTER_ADDITIONAL_INFORMATION)), 
"{\"result\":\"PARTIAL\",\"aggregate\":\"2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd\",\"event\":42,\"type\":\"task-manager-completed\",\"additionalInformation\":\"{\\\"type\\\":\\\"memory-reference-task-with-counter\\\",\\\"count\\\":3,\\\"timestamp\\\":\\\"2018-11-13T12:00:55Z\\\"}\"}"),
-            Arguments.of(new Failed(AGGREGATE_ID, EVENT_ID, 
Option.apply(COUNTER_ADDITIONAL_INFORMATION), Option.empty(), Option.empty()), 
"{\"aggregate\":\"2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd\",\"event\":42,\"type\":\"task-manager-failed\",\"additionalInformation\":\"{\\\"type\\\":\\\"memory-reference-task-with-counter\\\",\\\"count\\\":3,\\\"timestamp\\\":\\\"2018-11-13T12:00:55Z\\\"}\"}"),
-            Arguments.of(new Cancelled(AGGREGATE_ID, EVENT_ID, 
Option.apply(COUNTER_ADDITIONAL_INFORMATION)), 
"{\"aggregate\":\"2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd\",\"event\":42,\"type\":\"task-manager-cancelled\",\"additionalInformation\":\"{\\\"type\\\":\\\"memory-reference-task-with-counter\\\",\\\"count\\\":3,\\\"timestamp\\\":\\\"2018-11-13T12:00:55Z\\\"}\"}")
+            Arguments.of(new Completed(AGGREGATE_ID, EVENT_ID, 
Task.Result.COMPLETED, Option.apply(COUNTER_ADDITIONAL_INFORMATION)), 
"{\"result\":\"COMPLETED\",\"aggregate\":\"2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd\",\"event\":42,\"type\":\"task-manager-completed\",\"additionalInformation\":{\"type\":\"memory-reference-task-with-counter\",\"count\":3,\"timestamp\":\"2018-11-13T12:00:55Z\"}}"),
+            Arguments.of(new Completed(AGGREGATE_ID, EVENT_ID, 
Task.Result.PARTIAL, Option.apply(COUNTER_ADDITIONAL_INFORMATION)), 
"{\"result\":\"PARTIAL\",\"aggregate\":\"2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd\",\"event\":42,\"type\":\"task-manager-completed\",\"additionalInformation\":{\"type\":\"memory-reference-task-with-counter\",\"count\":3,\"timestamp\":\"2018-11-13T12:00:55Z\"}}"),
+            Arguments.of(new Failed(AGGREGATE_ID, EVENT_ID, 
Option.apply(COUNTER_ADDITIONAL_INFORMATION), Option.empty(), Option.empty()), 
"{\"aggregate\":\"2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd\",\"event\":42,\"type\":\"task-manager-failed\",\"additionalInformation\":{\"type\":\"memory-reference-task-with-counter\",\"count\":3,\"timestamp\":\"2018-11-13T12:00:55Z\"}}"),
+            Arguments.of(new Cancelled(AGGREGATE_ID, EVENT_ID, 
Option.apply(COUNTER_ADDITIONAL_INFORMATION)), 
"{\"aggregate\":\"2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd\",\"event\":42,\"type\":\"task-manager-cancelled\",\"additionalInformation\":{\"type\":\"memory-reference-task-with-counter\",\"count\":3,\"timestamp\":\"2018-11-13T12:00:55Z\"}}")
         );
     }
 
diff --git 
a/server/task/task-json/src/main/java/org/apache/james/server/task/json/JsonTaskAdditionalInformationSerializer.java
 
b/server/task/task-json/src/main/java/org/apache/james/server/task/json/JsonTaskAdditionalInformationSerializer.java
index 5d0cc48..eb68ef9 100644
--- 
a/server/task/task-json/src/main/java/org/apache/james/server/task/json/JsonTaskAdditionalInformationSerializer.java
+++ 
b/server/task/task-json/src/main/java/org/apache/james/server/task/json/JsonTaskAdditionalInformationSerializer.java
@@ -23,6 +23,7 @@ import java.util.Set;
 
 import javax.inject.Inject;
 
+import org.apache.james.json.DTOConverter;
 import org.apache.james.json.JsonGenericSerializer;
 import org.apache.james.server.task.json.dto.AdditionalInformationDTO;
 import org.apache.james.server.task.json.dto.AdditionalInformationDTOModule;
@@ -49,8 +50,7 @@ public class JsonTaskAdditionalInformationSerializer {
 
     @Inject
     public 
JsonTaskAdditionalInformationSerializer(Set<AdditionalInformationDTOModule<?, 
?>> modules) {
-        //FIXME
-        jsonGenericSerializer = new JsonGenericSerializer(modules, null);
+        jsonGenericSerializer = new JsonGenericSerializer(modules, 
ImmutableSet.of(), new DTOConverter<>(modules));
     }
 
     public 
JsonTaskAdditionalInformationSerializer(@SuppressWarnings("rawtypes") 
AdditionalInformationDTOModule... modules) {
@@ -74,4 +74,5 @@ public class JsonTaskAdditionalInformationSerializer {
             throw new InvalidAdditionalInformationException(e);
         }
     }
+
 }
diff --git 
a/server/task/task-json/src/main/java/org/apache/james/server/task/json/JsonTaskSerializer.java
 
b/server/task/task-json/src/main/java/org/apache/james/server/task/json/JsonTaskSerializer.java
index 90ebe54..313aa50 100644
--- 
a/server/task/task-json/src/main/java/org/apache/james/server/task/json/JsonTaskSerializer.java
+++ 
b/server/task/task-json/src/main/java/org/apache/james/server/task/json/JsonTaskSerializer.java
@@ -24,6 +24,7 @@ import java.util.Set;
 
 import javax.inject.Inject;
 
+import org.apache.james.json.DTOConverter;
 import org.apache.james.json.JsonGenericSerializer;
 import org.apache.james.server.task.json.dto.TaskDTO;
 import org.apache.james.server.task.json.dto.TaskDTOModule;
@@ -49,13 +50,12 @@ public class JsonTaskSerializer {
     private JsonGenericSerializer<Task, TaskDTO> jsonGenericSerializer;
 
     @Inject
-    public JsonTaskSerializer(Set<TaskDTOModule<?, ?>> modules) {
-        //FIXME
-        jsonGenericSerializer = new JsonGenericSerializer(modules, null);
+    public JsonTaskSerializer(DTOConverter<Task, TaskDTO> converter, 
Set<TaskDTOModule<?, ?>> modules) {
+        jsonGenericSerializer = new JsonGenericSerializer(modules, 
ImmutableSet.of(), converter);
     }
 
     public JsonTaskSerializer(@SuppressWarnings("rawtypes") TaskDTOModule... 
modules) {
-        this(ImmutableSet.copyOf(modules));
+        this(DTOConverter.of(modules), ImmutableSet.copyOf(modules));
     }
 
     public String serialize(Task task) throws JsonProcessingException {


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

Reply via email to