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

[james-project] branch master updated (caaed8b -> 9ed9a15)

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

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


    from caaed8b  JAMES-2773 add glowroot plugin to track put into blobstore
     new 016ef25  Changelog for recent ElasticSearch changes
     new cb2dcd6  Changelog for Distributed Task Management
     new cc10d4b  Changelog for various bug fixes
     new 772275c  Add some items contributed since last release
     new 366f867  Changelog entry for library upgrade
     new 8e1e4e2  Changelog entry for Cassandra authentication + SSL
     new 2a53b84  Changelog for Distributed Task Management
     new cda46ca  Changelog entry for ElasticSearch authentication + SSL
     new 1000123  Changelog entry for stricter mailbox name validation
     new a2a3ea2  Changelog for recent changes
     new a4c20b1  JAMES-2981 Changelog for Cassandra keyspace creation
     new 4debed2  JAMES-2981 update ugrade instructions
     new 4e7df2c  JAMES-2964 Changelog for negative quota creation
     new 28f01f2  JAMES-2813 fix bad copy/paste on DTO type
     new 7324d85  JAMES-2813 build a Set of modules as we always need a Set
     new 51a21c5  JAMES-2813 simplifies TasksSerializationModule code
     new f6e753f  JAMES-2813 make sure only constants are static and follow usual naming convention
     new ef1ec9c  JAMES-2813 split module finding into an inner class before further refactoring
     new 80bb186  JAMES-2813 use jackson built-in type detection for polymorphic types
     new 27f2845  JAMES-2813 Split JsonGenericSerializer between conversion and serialization
     new 475c539  JAMES-2813 demonstrate how to handle nested DTOs with some tests
     new 1af080d  JAMES-2813 handle nested AdditionInformation
     new 805ebca  JAMES-2813 use a staged builder to create serializers
     new ec1edc0  JAMES-2813 DTO <-> domain object must be a bijection for jackson to work
     new 109acad  JAMES-2813 take care of injection for DTO nested modules
     new d8a83b0  JAMES-2813 forbid duplicate typeid for DTO
     new 1549e77  JAMES-2813 give DTOConvert methods more explicit names
     new 22b3b48  JAMES-2813 extract EventNestedTypes string to a constant
     new 419f5b1  JAMES-2813 cassandra-guice product doesn't need nested event types, bind a default empty one
     new d9bdff3  JAMES-2813 Add throws in TaskEventDTO
     new 5e582a5  JAMES-2979 add test to ensure that dequeuing from the mailqueue should be done multiple elements at the same time
     new 438bb45  JAMES-2979 fix spooler mail dequeue
     new bce3f38  JAMES-2979 fix delivery runnable mail dequeue
     new c4b9d18  JAMES-2979 fix concurent dequeue for MemoryMailQueue
     new 36a9e57  JAMES-2949 DefaultJamesUser is never used
     new 0226e13  JAMES-2949 User::hasUsername is never used
     new 89251a2  JAMES-2949 JamesUser is no longer implemented
     new 128fe63  [Refactoring] Remove exceptions not thrown by methods in test classes in james-server-util module
     new 40a00cb  [Refactoring] Refactor james-server-util test classes with correct access modifiers
     new 3b1fc18  JAMES-2949 Remove FIXME-USERNAME annotations by using lower case comparison
     new 9ed9a15  Add news about Benoît's presentation at ApacheCon

The 41 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 CHANGELOG.md                                       |  31 +++++
 .../migration/MigrationTaskSerializationTest.java  |   4 +-
 .../main/java/org/apache/james/core/Username.java  |  11 ++
 .../java/org/apache/james/core/UsernameTest.java   |  48 ++++++++
 .../eventstore/cassandra/JsonEventSerializer.java  |  43 ++++++-
 .../CassandraEventSourcingSystemTest.java          |   2 +-
 .../cassandra/CassandraEventStoreExtension.java    |  20 +---
 .../cassandra/CassandraEventStoreTest.java         |   2 +-
 .../cassandra/JsonEventSerializerTest.java         |  32 +++---
 json/src/main/java/org/apache/james/json/DTO.java  |   6 +
 .../java/org/apache/james/json/DTOConverter.java   |  69 +++++++++++
 .../apache/james/json/JsonGenericSerializer.java   | 126 ++++++++++++++-------
 .../src/test/java/org/apache/DTOConverterTest.java | 119 +++++++++++++++++++
 .../java/org/apache/JsonGenericSerializerTest.java |  81 +++++++++----
 json/src/test/java/org/apache/dto/FirstDTO.java    |  14 ++-
 .../java/org/apache/dto/FirstDomainObject.java     |  11 +-
 .../test/java/org/apache/dto/FirstNestedDTO.java   |  24 ++--
 ...econdDomainObject.java => FirstNestedType.java} |  26 ++---
 .../apache/dto/{BaseType.java => NestedType.java}  |   2 +-
 json/src/test/java/org/apache/dto/SecondDTO.java   |  15 ++-
 .../java/org/apache/dto/SecondDomainObject.java    |  12 +-
 .../test/java/org/apache/dto/SecondNestedDTO.java  |  25 ++--
 ...condDomainObject.java => SecondNestedType.java} |  26 ++---
 json/src/test/java/org/apache/dto/TestModules.java |  39 +++++--
 .../dto/{TestModule.java => TestNestedModule.java} |   4 +-
 .../apache/james/mailbox/model/MailboxPath.java    |   2 +-
 ...ailboxPathV2MigrationTaskSerializationTest.java |  19 ++--
 .../mail/task/MailboxMergingTaskTest.java          |   6 +-
 ...aultGarbageCollectionTaskSerializationTest.java |  10 +-
 .../james/mailbox/quota/cassandra/dto/DTOTest.java |  18 +--
 ...sandraQuotaMailingListenersIntegrationTest.java |   4 +-
 .../indexer/ReprocessingContextInformationDTO.java |  46 ++++++--
 ...rorRecoveryIndexationTaskSerializationTest.java |   5 +-
 .../FullReindexingTaskSerializationTest.java       |   4 +-
 .../MessageIdReindexingTaskSerializationTest.java  |   4 +-
 ...ngleMailboxReindexingTaskSerializationTest.java |   4 +-
 ...ngleMessageReindexingTaskSerializationTest.java |   4 +-
 .../UserReindexingTaskSerializationTest.java       |   4 +-
 .../james/transport/mailets/AbstractSign.java      |   2 +-
 .../CassandraRabbitMQAwsS3SmtpTestRuleFactory.java |   2 +-
 .../org/apache/james/CassandraJamesServerMain.java |  18 ++-
 .../james/CassandraRabbitMQJamesServerMain.java    |   8 +-
 .../james/modules/TaskSerializationModule.java     |  50 +++++---
 .../james/util/BodyOffsetInputStreamTest.java      |   2 +-
 .../james/util/CommutativityCheckerTest.java       |  18 +--
 .../java/org/apache/james/util/GuavaUtilsTest.java |   2 +-
 .../test/java/org/apache/james/util/HostTest.java  |   2 +-
 .../org/apache/james/util/IteratorWrapperTest.java |   2 +-
 .../org/apache/james/util/LoggingLevelTest.java    |  12 +-
 .../java/org/apache/james/util/MDCBuilderTest.java |   2 +-
 .../org/apache/james/util/OptionalUtilsTest.java   |  10 +-
 .../test/java/org/apache/james/util/PortTest.java  |   2 +-
 .../java/org/apache/james/util/SizeFormatTest.java |   2 +-
 .../test/java/org/apache/james/util/SizeTest.java  |   4 +-
 .../org/apache/james/util/StreamUtilsTest.java     |   2 +-
 .../java/org/apache/james/util/ValuePatchTest.java |  10 +-
 .../util/concurrency/ConcurrentTestRunnerTest.java |   8 +-
 .../james/util/date/ImapDateTimeFormatterTest.java |   2 +-
 .../util/mime/MessageContentExtractorTest.java     |   2 +-
 .../util/retry/DoublingRetryScheduleTest.java      |   2 +-
 .../util/retry/ExceptionRetryHandlerTest.java      |   4 +-
 .../naming/NamingExceptionRetryHandlerTest.java    |   2 +-
 .../util/streams/ImmutableCollectorsTest.java      |   2 +-
 .../apache/james/util/streams/IteratorsTest.java   |   2 +-
 .../org/apache/james/util/streams/LimitTest.java   |   2 +-
 .../org/apache/james/util/streams/OffsetTest.java  |   2 +-
 .../user/api/UsersRepositoryManagementMBean.java   |  51 ---------
 .../org/apache/james/user/api/model/JamesUser.java |  88 --------------
 .../java/org/apache/james/user/api/model/User.java |   7 --
 ...ventSourcingDLPConfigurationStoreExtension.java |   9 +-
 .../james/dlp/eventsourcing/cassandra/DTOTest.java |   4 +
 ...pingsSourcesMigrationTaskSerializationTest.java |   6 +-
 ...sandraEventSourcingFilteringManagementTest.java |   4 +-
 .../james/jmap/cassandra/filtering/DTOTest.java    |   5 +
 .../james/user/lib/UsersRepositoryManagement.java  |  69 -----------
 .../james/user/lib/model/DefaultJamesUser.java     | 119 -------------------
 .../mailetcontainer/impl/JamesMailSpooler.java     |   3 +-
 .../james/transport/mailets/WhiteListManager.java  |  27 -----
 .../mailets/delivery/SimpleMailStore.java          |   2 +-
 .../mailets/remote/delivery/DeliveryRunnable.java  |   3 +-
 .../matchers/AbstractSQLWhitelistMatcher.java      |  21 ----
 .../SenderAuthIdentifyVerificationRcptHook.java    |   7 +-
 ...sandraMappingsSolveInconsistenciesTaskTest.java |   6 +-
 ...edMessagesVaultDeleteTaskSerializationTest.java |   4 +-
 ...edMessagesVaultExportTaskSerializationTest.java |   4 +-
 ...dMessagesVaultRestoreTaskSerializationTest.java |   4 +-
 .../WebadminApiQuerySerializationContractTest.java |   2 +-
 ...tersRedeliveryTaskAdditionalInformationDTO.java |  78 +++++++++----
 .../service/EventDeadLettersRedeliverTaskTest.java |   4 +-
 .../webadmin/service/ClearMailQueueTaskTest.java   |   8 +-
 .../service/DeleteMailsFromMailQueueTaskTest.java  |  10 +-
 .../service/ClearMailRepositoryTaskTest.java       |   8 +-
 .../service/ReprocessingAllMailsTaskTest.java      |   8 +-
 .../service/ReprocessingOneMailTaskTest.java       |   8 +-
 .../queue/activemq/ActiveMQMailQueueBlobTest.java  |   4 +
 .../queue/activemq/ActiveMQMailQueueTest.java      |   6 +-
 .../apache/james/queue/api/MailQueueContract.java  |  35 +++++-
 .../apache/james/queue/jms/JMSMailQueueTest.java   |   6 +-
 .../james/queue/memory/MemoryMailQueueFactory.java |   5 +-
 .../CassandraMailQueueViewTestFactory.java         |   4 +-
 .../view/cassandra/configuration/DTOTest.java      |   3 +
 .../EventsourcingConfigurationManagementTest.java  |   6 +-
 .../distributed/TasksSerializationModule.java      |  52 +++++----
 .../eventsourcing/distributed/TaskEventDTO.scala   |  92 ++++++++++-----
 ...andraTaskExecutionDetailsProjectionDAOTest.java |   2 +-
 ...assandraTaskExecutionDetailsProjectionTest.java |   5 +-
 .../distributed/DistributedTaskManagerTest.java    |  72 ++++++------
 .../RabbitMQTerminationSubscriberTest.java         |  11 +-
 .../distributed/RabbitMQWorkQueueTest.java         |   4 +-
 .../distributed/TaskEventsSerializationTest.java   |  53 +++++----
 .../JsonTaskAdditionalInformationSerializer.java   |  13 ++-
 .../james/server/task/json/JsonTaskSerializer.java |  12 +-
 .../server/task/json/TaskDeserializerTest.java     |   2 +-
 .../server/task/json/TaskSerializationTest.java    |   8 +-
 .../james/server/task/json/TaskSerializerTest.java |   2 +-
 .../server/task/json/dto/TestTaskDTOModules.java   |   6 +-
 .../_posts/2019-11-19-apache-con-eu.markdown       |  13 +++
 upgrade-instructions.md                            |  20 ++++
 118 files changed, 1187 insertions(+), 918 deletions(-)
 create mode 100644 json/src/main/java/org/apache/james/json/DTOConverter.java
 create mode 100644 json/src/test/java/org/apache/DTOConverterTest.java
 copy server/task/task-json/src/test/java/org/apache/james/server/task/json/dto/TestTaskDTO.java => json/src/test/java/org/apache/dto/FirstNestedDTO.java (75%)
 copy json/src/test/java/org/apache/dto/{SecondDomainObject.java => FirstNestedType.java} (72%)
 copy json/src/test/java/org/apache/dto/{BaseType.java => NestedType.java} (97%)
 copy server/task/task-json/src/test/java/org/apache/james/server/task/json/dto/TestTaskDTO.java => json/src/test/java/org/apache/dto/SecondNestedDTO.java (74%)
 copy json/src/test/java/org/apache/dto/{SecondDomainObject.java => SecondNestedType.java} (72%)
 copy json/src/test/java/org/apache/dto/{TestModule.java => TestNestedModule.java} (83%)
 delete mode 100644 server/data/data-api/src/main/java/org/apache/james/user/api/model/JamesUser.java
 delete mode 100644 server/data/data-library/src/main/java/org/apache/james/user/lib/model/DefaultJamesUser.java
 create mode 100644 src/homepage/_posts/2019-11-19-apache-con-eu.markdown


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


[james-project] 16/41: JAMES-2813 simplifies TasksSerializationModule code

Posted by bt...@apache.org.
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 51a21c55f104287501d5c649326a88cd1adfda2c
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Thu Oct 17 16:54:08 2019 +0200

    JAMES-2813 simplifies TasksSerializationModule code
---
 .../distributed/TasksSerializationModule.java      | 46 +++++++++++-----------
 .../distributed/DistributedTaskManagerTest.java    |  2 +-
 .../RabbitMQTerminationSubscriberTest.java         |  2 +-
 .../distributed/TaskEventsSerializationTest.java   |  2 +-
 4 files changed, 26 insertions(+), 26 deletions(-)

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 5e06f1c..2e56172 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
@@ -20,7 +20,6 @@
 package org.apache.james.task.eventsourcing.distributed;
 
 import java.util.Set;
-import java.util.function.BiFunction;
 import java.util.stream.Stream;
 
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
@@ -33,17 +32,16 @@ import org.apache.james.task.eventsourcing.Completed;
 import org.apache.james.task.eventsourcing.Created;
 import org.apache.james.task.eventsourcing.Failed;
 import org.apache.james.task.eventsourcing.Started;
-import org.apache.james.task.eventsourcing.TaskEvent;
 
 import com.github.steveash.guavate.Guavate;
 
 public interface TasksSerializationModule {
     @FunctionalInterface
-    interface TaskSerializationModuleFactory<T extends TaskEvent, U extends TaskEventDTO> {
-        EventDTOModule<T, U> create(JsonTaskSerializer taskSerializer, JsonTaskAdditionalInformationSerializer additionalInformationSerializer);
+    interface TaskSerializationModuleFactory {
+        EventDTOModule<?, ?> create(JsonTaskSerializer taskSerializer, JsonTaskAdditionalInformationSerializer additionalInformationSerializer);
     }
 
-    TaskSerializationModuleFactory<Created, CreatedDTO> CREATED = (jsonTaskSerializer, jsonTaskAdditionalInformationSerializer) -> EventDTOModule
+    TaskSerializationModuleFactory CREATED = (jsonTaskSerializer, additionalInformationSerializer) -> EventDTOModule
         .forEvent(Created.class)
         .convertToDTO(CreatedDTO.class)
         .toDomainObjectConverter(dto -> dto.toDomainObject(jsonTaskSerializer))
@@ -51,7 +49,7 @@ public interface TasksSerializationModule {
         .typeName("task-manager-created")
         .withFactory(EventDTOModule::new);
 
-    TaskSerializationModuleFactory<Started, StartedDTO> STARTED = (jsonTaskSerializer, jsonTaskAdditionalInformationSerializer) -> EventDTOModule
+    TaskSerializationModuleFactory STARTED = (jsonTaskSerializer, additionalInformationSerializer) -> EventDTOModule
         .forEvent(Started.class)
         .convertToDTO(StartedDTO.class)
         .toDomainObjectConverter(StartedDTO::toDomainObject)
@@ -59,7 +57,7 @@ public interface TasksSerializationModule {
         .typeName("task-manager-started")
         .withFactory(EventDTOModule::new);
 
-    TaskSerializationModuleFactory<CancelRequested, CancelRequestedDTO> CANCEL_REQUESTED = (jsonTaskSerializer, jsonTaskAdditionalInformationSerializer) -> EventDTOModule
+    TaskSerializationModuleFactory CANCEL_REQUESTED = (jsonTaskSerializer, additionalInformationSerializer) -> EventDTOModule
         .forEvent(CancelRequested.class)
         .convertToDTO(CancelRequestedDTO.class)
         .toDomainObjectConverter(CancelRequestedDTO::toDomainObject)
@@ -67,40 +65,42 @@ public interface TasksSerializationModule {
         .typeName("task-manager-cancel-requested")
         .withFactory(EventDTOModule::new);
 
-    TaskSerializationModuleFactory<Completed, CompletedDTO> COMPLETED = (jsonTaskSerializer, jsonTaskAdditionalInformationSerializer) -> EventDTOModule
+    TaskSerializationModuleFactory COMPLETED = (jsonTaskSerializer, additionalInformationSerializer) -> EventDTOModule
         .forEvent(Completed.class)
         .convertToDTO(CompletedDTO.class)
-        .toDomainObjectConverter(dto -> dto.toDomainObject(jsonTaskAdditionalInformationSerializer))
-        .toDTOConverter((event, typeName) -> CompletedDTO.fromDomainObject(jsonTaskAdditionalInformationSerializer, event, typeName))
+        .toDomainObjectConverter(dto -> dto.toDomainObject(additionalInformationSerializer))
+        .toDTOConverter((event, typeName) -> CompletedDTO.fromDomainObject(additionalInformationSerializer, event, typeName))
         .typeName("task-manager-completed")
         .withFactory(EventDTOModule::new);
 
-    TaskSerializationModuleFactory<Failed, FailedDTO> FAILED = (jsonTaskSerializer, jsonTaskAdditionalInformationSerializer) -> EventDTOModule
+    TaskSerializationModuleFactory FAILED = (jsonTaskSerializer, additionalInformationSerializer) -> EventDTOModule
         .forEvent(Failed.class)
         .convertToDTO(FailedDTO.class)
-        .toDomainObjectConverter(dto -> dto.toDomainObject(jsonTaskAdditionalInformationSerializer))
-        .toDTOConverter((event, typeName) -> FailedDTO.fromDomainObject(jsonTaskAdditionalInformationSerializer, event, typeName))
+        .toDomainObjectConverter(dto -> dto.toDomainObject(additionalInformationSerializer))
+        .toDTOConverter((event, typeName) -> FailedDTO.fromDomainObject(additionalInformationSerializer, event, typeName))
         .typeName("task-manager-failed")
         .withFactory(EventDTOModule::new);
 
-    TaskSerializationModuleFactory<Cancelled, CancelledDTO> CANCELLED = (jsonTaskSerializer, jsonTaskAdditionalInformationSerializer) -> EventDTOModule
+    TaskSerializationModuleFactory CANCELLED = (jsonTaskSerializer, additionalInformationSerializer) -> EventDTOModule
         .forEvent(Cancelled.class)
         .convertToDTO(CancelledDTO.class)
-        .toDomainObjectConverter(dto -> dto.toDomainObject(jsonTaskAdditionalInformationSerializer))
-        .toDTOConverter((event, typeName) -> CancelledDTO.fromDomainObject(jsonTaskAdditionalInformationSerializer, event, typeName))
+        .toDomainObjectConverter(dto -> dto.toDomainObject(additionalInformationSerializer))
+        .toDTOConverter((event, typeName) -> CancelledDTO.fromDomainObject(additionalInformationSerializer, event, typeName))
         .typeName("task-manager-cancelled")
         .withFactory(EventDTOModule::new);
 
-    TaskSerializationModuleFactory<AdditionalInformationUpdated, AdditionalInformationUpdatedDTO> UPDATED = (jsonTaskSerializer, jsonTaskAdditionalInformationSerializer) -> EventDTOModule
+    TaskSerializationModuleFactory UPDATED = (jsonTaskSerializer, additionalInformationSerializer) -> EventDTOModule
         .forEvent(AdditionalInformationUpdated.class)
         .convertToDTO(AdditionalInformationUpdatedDTO.class)
-        .toDomainObjectConverter(dto -> dto.toDomainObject(jsonTaskAdditionalInformationSerializer))
-        .toDTOConverter((event, typeName) -> AdditionalInformationUpdatedDTO.fromDomainObject(jsonTaskAdditionalInformationSerializer, event, typeName))
+        .toDomainObjectConverter(dto -> dto.toDomainObject(additionalInformationSerializer))
+        .toDTOConverter((event, typeName) -> AdditionalInformationUpdatedDTO.fromDomainObject(additionalInformationSerializer, event, typeName))
         .typeName("task-manager-updated")
         .withFactory(EventDTOModule::new);
 
-    BiFunction<JsonTaskSerializer, JsonTaskAdditionalInformationSerializer, Set<EventDTOModule<?, ?>>> MODULES = (jsonTaskSerializer, jsonTaskAdditionalInformationSerializer) -> Stream
-        .of(CREATED, STARTED, CANCEL_REQUESTED, CANCELLED, COMPLETED, FAILED, UPDATED)
-        .map(moduleFactory -> moduleFactory.create(jsonTaskSerializer, jsonTaskAdditionalInformationSerializer))
-        .collect(Guavate.toImmutableSet());
+    static Set<EventDTOModule<?, ?>> list(JsonTaskSerializer jsonTaskSerializer, JsonTaskAdditionalInformationSerializer jsonTaskAdditionalInformationSerializer) {
+        return Stream
+            .of(CREATED, STARTED, CANCEL_REQUESTED, CANCELLED, COMPLETED, FAILED, UPDATED)
+            .map(moduleFactory -> moduleFactory.create(jsonTaskSerializer, jsonTaskAdditionalInformationSerializer))
+            .collect(Guavate.toImmutableSet());
+    }
 }
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 d6ed9d3..2b60b6e 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
@@ -108,7 +108,7 @@ class DistributedTaskManagerTest implements TaskManagerContract {
 
     private static final Hostname HOSTNAME = new Hostname("foo");
     private static final Hostname HOSTNAME_2 = new Hostname("bar");
-    private static final Set<EventDTOModule<?, ?>> MODULES = TasksSerializationModule.MODULES.apply(TASK_SERIALIZER, JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER).stream().collect(Guavate.toImmutableSet());
+    private static final Set<EventDTOModule<?, ?>> MODULES = TasksSerializationModule.list(TASK_SERIALIZER, JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER).stream().collect(Guavate.toImmutableSet());
     private static final JsonEventSerializer EVENT_SERIALIZER = new JsonEventSerializer(MODULES);
 
 
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 e826690..c736c50 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
@@ -46,7 +46,7 @@ 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.MODULES.apply(TASK_SERIALIZER, JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER).stream().collect(Guavate.toImmutableSet());
+    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);
 
     @RegisterExtension
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 5d53c4b..bcb2a6d 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
@@ -59,7 +59,7 @@ class TaskEventsSerializationTest {
     private static final JsonTaskSerializer TASK_SERIALIZER = new JsonTaskSerializer(TestTaskDTOModules.COMPLETED_TASK_MODULE,
         TestTaskDTOModules.MEMORY_REFERENCE_WITH_COUNTER_TASK_MODULE.apply(new MemoryReferenceWithCounterTaskStore()));
     private static final JsonTaskAdditionalInformationSerializer TASK_ADDITIONNAL_INFORMATION_SERIALIZER = new JsonTaskAdditionalInformationSerializer(MemoryReferenceWithCounterTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
-    private static final Set<EventDTOModule<?, ?>> MODULES = TasksSerializationModule.MODULES.apply(TASK_SERIALIZER, TASK_ADDITIONNAL_INFORMATION_SERIALIZER);
+    private static final Set<EventDTOModule<?, ?>> MODULES = TasksSerializationModule.list(TASK_SERIALIZER, TASK_ADDITIONNAL_INFORMATION_SERIALIZER);
     private static final JsonEventSerializer SERIALIZER = new JsonEventSerializer(MODULES.stream().collect(Guavate.toImmutableSet()));
     private static final TaskAggregateId AGGREGATE_ID = new TaskAggregateId(TaskId.fromString("2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd"));
     private static final EventId EVENT_ID = EventId.fromSerialized(42);


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


[james-project] 09/41: Changelog entry for stricter mailbox name validation

Posted by bt...@apache.org.
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 1000123a05b26440af6079611062427a1bdabb25
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Nov 15 09:48:16 2019 +0700

    Changelog entry for stricter mailbox name validation
---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 458a8eb..302fd7a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -35,6 +35,7 @@ of tasks being currently executed.
 - JAMES-2739 fixed browse mails from queue over JMX
 - JAMES-2375 DSNBounce mailet should provide a subject
 - JAMES-2097 RemoteDelivery: Avoid retrying already succeeded recipients when sendPartial
+- MAILBOX-392 Mailbox name validation upon mailbox creation is stricter: forbid `#&*%` and empty sub-mailboxes names.
 
 ### Removed
 - Classes marked as deprecated whose removal was planned after 3.4.0 release (See JAMES-2703). This includes:


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


[james-project] 10/41: Changelog for recent changes

Posted by bt...@apache.org.
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 a2a3ea2aac381c4cc4a038f185ac63609f1e477f
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Nov 18 11:40:14 2019 +0700

    Changelog for recent changes
---
 CHANGELOG.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 302fd7a..289f9f5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -36,6 +36,8 @@ of tasks being currently executed.
 - JAMES-2375 DSNBounce mailet should provide a subject
 - JAMES-2097 RemoteDelivery: Avoid retrying already succeeded recipients when sendPartial
 - MAILBOX-392 Mailbox name validation upon mailbox creation is stricter: forbid `#&*%` and empty sub-mailboxes names.
+- JAMES-2972 Incorrect attribute name in the mailet configuration thanks to jtconsol
+- JAMES-2632 JMAP Draft GetMailboxes performance enhancements when retrieving all mailboxes of a user
 
 ### Removed
 - Classes marked as deprecated whose removal was planned after 3.4.0 release (See JAMES-2703). This includes:


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


[james-project] 25/41: JAMES-2813 take care of injection for DTO nested modules

Posted by bt...@apache.org.
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 109acadaee7c7aab671d2a77916ff24cd621daaa
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Wed Oct 23 14:33:36 2019 +0200

    JAMES-2813 take care of injection for DTO nested modules
---
 .../eventstore/cassandra/JsonEventSerializer.java    |  3 ++-
 .../james/modules/TaskSerializationModule.java       | 20 ++++++++++++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)

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 3acdd58..9c3b447 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
@@ -25,6 +25,7 @@ import java.util.Collection;
 import java.util.Set;
 
 import javax.inject.Inject;
+import javax.inject.Named;
 
 import org.apache.james.eventsourcing.Event;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
@@ -81,7 +82,7 @@ public class JsonEventSerializer {
     private JsonGenericSerializer<Event, EventDTO> jsonGenericSerializer;
 
     @Inject
-    private JsonEventSerializer(Set<EventDTOModule<?, ?>> modules, Set<DTOModule<?, ?>> nestedTypesModules) {
+    private JsonEventSerializer(Set<EventDTOModule<?, ?>> modules, @Named("EventNestedTypes") Set<DTOModule<?, ?>> nestedTypesModules) {
         jsonGenericSerializer = JsonGenericSerializer.forModules(modules).withNestedTypeModules(nestedTypesModules);
     }
     
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 cea90ed..f901b57 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
@@ -19,12 +19,16 @@
 package org.apache.james.modules;
 
 import java.time.Clock;
+import java.util.Set;
+
+import javax.inject.Named;
 
 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.json.DTOModule;
 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;
@@ -87,11 +91,20 @@ import org.apache.mailbox.tools.indexer.UserReindexingTask;
 import org.apache.mailbox.tools.indexer.UserReindexingTaskAdditionalInformationDTO;
 import org.apache.mailbox.tools.indexer.UserReindexingTaskDTO;
 
+import com.google.common.collect.Sets;
 import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+import com.google.inject.Singleton;
 import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class TaskSerializationModule extends AbstractModule {
 
+    @Provides
+    @Singleton
+    public DTOConverter<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> additionalInformationDTOConverter(Set<AdditionalInformationDTOModule<?, ?>> modules) {
+        return new DTOConverter<>(modules);
+    }
+
     @ProvidesIntoSet
     public EventDTOModule<?, ?> taskCreatedSerialization(JsonTaskSerializer jsonTaskSerializer, DTOConverter<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> additionalInformationConverter) {
         return TasksSerializationModule.CREATED.create(jsonTaskSerializer, additionalInformationConverter);
@@ -331,4 +344,11 @@ public class TaskSerializationModule extends AbstractModule {
     public AdditionalInformationDTOModule<?, ?> userReindexingAdditionalInformation(MailboxId.Factory mailboxIdFactory) {
         return UserReindexingTaskAdditionalInformationDTO.serializationModule(mailboxIdFactory);
     }
+
+    @Named("EventNestedTypes")
+    @Provides
+    public Set<DTOModule<?, ?>> eventNestedTypes(Set<AdditionalInformationDTOModule<?, ?>> additionalInformationDTOModules,
+                                            Set<TaskDTOModule<?, ?>> taskDTOModules) {
+        return Sets.union(additionalInformationDTOModules, taskDTOModules);
+    }
 }


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


[james-project] 29/41: JAMES-2813 cassandra-guice product doesn't need nested event types, bind a default empty one

Posted by bt...@apache.org.
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 419f5b1b7da1388f23232dfab5ad65c1905799c1
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Tue Nov 5 17:21:21 2019 +0100

    JAMES-2813 cassandra-guice product doesn't need nested event types, bind a default empty one
---
 .../CassandraRabbitMQAwsS3SmtpTestRuleFactory.java     |  2 +-
 .../org/apache/james/CassandraJamesServerMain.java     | 18 ++++++++++++++++--
 .../apache/james/CassandraRabbitMQJamesServerMain.java |  8 ++------
 3 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/mpt/impl/smtp/cassandra-rabbitmq-object-storage/src/test/java/org/apache/james/mpt/smtp/CassandraRabbitMQAwsS3SmtpTestRuleFactory.java b/mpt/impl/smtp/cassandra-rabbitmq-object-storage/src/test/java/org/apache/james/mpt/smtp/CassandraRabbitMQAwsS3SmtpTestRuleFactory.java
index 91cebea..d320e63 100644
--- a/mpt/impl/smtp/cassandra-rabbitmq-object-storage/src/test/java/org/apache/james/mpt/smtp/CassandraRabbitMQAwsS3SmtpTestRuleFactory.java
+++ b/mpt/impl/smtp/cassandra-rabbitmq-object-storage/src/test/java/org/apache/james/mpt/smtp/CassandraRabbitMQAwsS3SmtpTestRuleFactory.java
@@ -22,8 +22,8 @@ import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
 import org.apache.james.CassandraJamesServerMain;
 import org.apache.james.CleanupTasksPerformer;
 import org.apache.james.GuiceJamesServer;
-import org.apache.james.backends.rabbitmq.DockerRabbitMQSingleton;
 import org.apache.james.backends.cassandra.init.configuration.ClusterConfiguration;
+import org.apache.james.backends.rabbitmq.DockerRabbitMQSingleton;
 import org.apache.james.dnsservice.api.DNSService;
 import org.apache.james.modules.TestAwsS3BlobStoreModule;
 import org.apache.james.modules.TestRabbitMQModule;
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 9ff2b63..d6c1a37 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
@@ -19,6 +19,11 @@
 
 package org.apache.james;
 
+import static org.apache.james.eventsourcing.eventstore.cassandra.JsonEventSerializer.EVENT_NESTED_TYPES_INJECTION_NAME;
+
+import java.util.Set;
+
+import org.apache.james.json.DTOModule;
 import org.apache.james.modules.BlobExportMechanismModule;
 import org.apache.james.modules.MailboxModule;
 import org.apache.james.modules.activemq.ActiveMQQueueModule;
@@ -67,7 +72,10 @@ import org.apache.james.modules.spamassassin.SpamAssassinListenerModule;
 import org.apache.james.modules.vault.DeletedMessageVaultRoutesModule;
 import org.apache.james.server.core.configuration.Configuration;
 
+import com.google.common.collect.ImmutableSet;
 import com.google.inject.Module;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Names;
 import com.google.inject.util.Modules;
 
 public class CassandraJamesServerMain {
@@ -105,6 +113,10 @@ public class CassandraJamesServerMain {
         new BlobStoreAPIModule(),
         new BlobExportMechanismModule());
 
+    private static final Module CASSANDRA_EVENT_STORE_JSON_SERIALIZATION_DEFAULT_MODULE = binder ->
+        binder.bind(new TypeLiteral<Set<DTOModule<?, ?>>>() {}).annotatedWith(Names.named(EVENT_NESTED_TYPES_INJECTION_NAME))
+            .toInstance(ImmutableSet.of());
+
     public static final Module CASSANDRA_SERVER_CORE_MODULE = Modules.combine(
         new ActiveMQQueueModule(),
         new CassandraDomainListModule(),
@@ -117,7 +129,8 @@ public class CassandraJamesServerMain {
         new CassandraSessionModule(),
         new CassandraSieveRepositoryModule(),
         new CassandraUsersRepositoryModule(),
-        BLOB_MODULE);
+        BLOB_MODULE,
+        CASSANDRA_EVENT_STORE_JSON_SERIALIZATION_DEFAULT_MODULE);
 
     public static final Module CASSANDRA_MAILBOX_MODULE = Modules.combine(
         new CassandraMailboxModule(),
@@ -138,7 +151,8 @@ public class CassandraJamesServerMain {
 
     public static Module ALL_BUT_JMX_CASSANDRA_MODULE = Modules.combine(
         REQUIRE_TASK_MANAGER_MODULE,
-        new TaskManagerModule()
+        new TaskManagerModule(),
+        CASSANDRA_EVENT_STORE_JSON_SERIALIZATION_DEFAULT_MODULE
     );
 
     public static void main(String[] args) throws Exception {
diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/CassandraRabbitMQJamesServerMain.java b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/CassandraRabbitMQJamesServerMain.java
index 017b4aa..c702613 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/CassandraRabbitMQJamesServerMain.java
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/CassandraRabbitMQJamesServerMain.java
@@ -35,12 +35,8 @@ import com.google.inject.util.Modules;
 public class CassandraRabbitMQJamesServerMain {
     public static final Module MODULES =
         Modules
-            .override(
-                Modules.combine(
-                    REQUIRE_TASK_MANAGER_MODULE,
-                    new DistributedTaskManagerModule(),
-                    new TaskSerializationModule()))
-            .with(new RabbitMQModule(), new BlobStoreChoosingModule(), new RabbitMQEventBusModule());
+            .override(Modules.combine(REQUIRE_TASK_MANAGER_MODULE, new DistributedTaskManagerModule()))
+            .with(new RabbitMQModule(), new BlobStoreChoosingModule(), new RabbitMQEventBusModule(), new TaskSerializationModule());
 
     public static void main(String[] args) throws Exception {
         Configuration configuration = Configuration.builder()


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


[james-project] 37/41: JAMES-2949 JamesUser is no longer implemented

Posted by bt...@apache.org.
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 89251a2f685b9b6f885335631b7e1833d5eb63c4
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Nov 18 14:33:32 2019 +0700

    JAMES-2949 JamesUser is no longer implemented
    
    Specific handling, as well as this model, is thus no longer required, after
    removal of JamesUsersRepository & UsersFileRepository
    
    See https://github.com/linagora/james-project/pull/2843
---
 .../user/api/UsersRepositoryManagementMBean.java   | 51 -------------
 .../org/apache/james/user/api/model/JamesUser.java | 88 ----------------------
 .../james/user/lib/UsersRepositoryManagement.java  | 69 -----------------
 .../james/transport/mailets/WhiteListManager.java  | 27 -------
 .../matchers/AbstractSQLWhitelistMatcher.java      | 21 ------
 5 files changed, 256 deletions(-)

diff --git a/server/data/data-api/src/main/java/org/apache/james/user/api/UsersRepositoryManagementMBean.java b/server/data/data-api/src/main/java/org/apache/james/user/api/UsersRepositoryManagementMBean.java
index 8e262b1..08fc593 100644
--- a/server/data/data-api/src/main/java/org/apache/james/user/api/UsersRepositoryManagementMBean.java
+++ b/server/data/data-api/src/main/java/org/apache/james/user/api/UsersRepositoryManagementMBean.java
@@ -19,8 +19,6 @@
 
 package org.apache.james.user.api;
 
-import org.apache.james.core.Username;
-
 /**
  * Expose user account management functionality through JMX.
  */
@@ -92,55 +90,6 @@ public interface UsersRepositoryManagementMBean {
     void setPassword(String userName, String password) throws Exception;
 
     /**
-     * Removes a user's alias which terminates local mail forwarding
-     * 
-     * 
-     * @param userName
-     *            The name of the user whose alias is unset
-     * @throws UsersRepositoryException
-     *             if error
-     */
-    @Deprecated
-    void unsetAlias(Username userName) throws Exception;
-
-    /**
-     * Retrieves the user's alias, if set
-     * 
-     * 
-     * @return User's alias, or NULL, if no alias is set
-     * @throws UsersRepositoryException
-     *             if error
-     */
-    @Deprecated
-    String getAlias(Username userName) throws Exception;
-
-    /**
-     * Removes a user's forward email address which terminates remote mail
-     * forwarding
-     * 
-     * 
-     * @param userName
-     *            The name of the user whose forward is unset
-     * @throws UsersRepositoryException
-     *             if error
-     */
-    @Deprecated
-    void unsetForwardAddress(Username userName) throws Exception;
-
-    /**
-     * Retrieves the user's forward, if set
-     * 
-     * 
-     * @param userName
-     *            The name of the user whose forward is set
-     * @return User's forward email address, or NULL, if no forward is set
-     * @throws UsersRepositoryException
-     *             if error
-     */
-    @Deprecated
-    String getForwardAddress(Username userName) throws Exception;
-
-    /**
      * Return true if the UserRepository has VirtualHosting enabled
      * 
      * @return virtual
diff --git a/server/data/data-api/src/main/java/org/apache/james/user/api/model/JamesUser.java b/server/data/data-api/src/main/java/org/apache/james/user/api/model/JamesUser.java
deleted file mode 100644
index 1db501d..0000000
--- a/server/data/data-api/src/main/java/org/apache/james/user/api/model/JamesUser.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************
- * 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.user.api.model;
-
-import org.apache.james.core.MailAddress;
-
-/**
- * Interface for objects representing users of an email/ messaging system.
- * 
- * @deprecated Just use the User interface for Users. Forwarding and Aliasing
- *             should get done via RecipientRewriteTable
- */
-@Deprecated
-public interface JamesUser extends User {
-
-    /**
-     * Indicate if mail for this user should be forwarded to some other mail
-     * server.
-     * 
-     * @param forward
-     *            whether email for this user should be forwarded
-     */
-    void setForwarding(boolean forward);
-
-    /**
-     * Return true if mail for this user should be forwarded
-     */
-    boolean getForwarding();
-
-    /**
-     * <p>
-     * Set destination for forwading mail
-     * </p>
-     * <p>
-     * TODO: Should we use a MailAddress?
-     * </p>
-     * 
-     * @param address
-     *            the forwarding address for this user
-     */
-    boolean setForwardingDestination(MailAddress address);
-
-    /**
-     * Return the destination to which email should be forwarded
-     */
-    MailAddress getForwardingDestination();
-
-    /**
-     * Indicate if mail received for this user should be delivered locally to a
-     * different address.
-     */
-    void setAliasing(boolean alias);
-
-    /**
-     * Return true if emails should be delivered locally to an alias.
-     */
-    boolean getAliasing();
-
-    /**
-     * Set local address to which email should be delivered.
-     * 
-     * @return true if successful
-     */
-    boolean setAlias(String address);
-
-    /**
-     * Get local address to which mail should be delivered.
-     */
-    String getAlias();
-
-}
diff --git a/server/data/data-library/src/main/java/org/apache/james/user/lib/UsersRepositoryManagement.java b/server/data/data-library/src/main/java/org/apache/james/user/lib/UsersRepositoryManagement.java
index ad5d55a..dded302 100644
--- a/server/data/data-library/src/main/java/org/apache/james/user/lib/UsersRepositoryManagement.java
+++ b/server/data/data-library/src/main/java/org/apache/james/user/lib/UsersRepositoryManagement.java
@@ -30,10 +30,8 @@ import org.apache.james.core.Username;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.user.api.UsersRepositoryManagementMBean;
-import org.apache.james.user.api.model.JamesUser;
 import org.apache.james.user.api.model.User;
 
-@SuppressWarnings("deprecation")
 public class UsersRepositoryManagement extends StandardMBean implements UsersRepositoryManagementMBean {
 
     /**
@@ -50,18 +48,6 @@ public class UsersRepositoryManagement extends StandardMBean implements UsersRep
         super(UsersRepositoryManagementMBean.class);
     }
 
-    private JamesUser getJamesUser(Username userName) throws UsersRepositoryException {
-        User baseuser = usersRepository.getUserByName(userName);
-        if (baseuser == null) {
-            throw new IllegalArgumentException("user not found: " + userName.asString());
-        }
-        if (!(baseuser instanceof JamesUser)) {
-            throw new IllegalArgumentException("user is not of type JamesUser: " + userName.asString());
-        }
-
-        return (JamesUser) baseuser;
-    }
-
     @Override
     public void addUser(String rawUsername, String password) throws Exception {
         try {
@@ -135,61 +121,6 @@ public class UsersRepositoryManagement extends StandardMBean implements UsersRep
     }
 
     @Override
-    public void unsetAlias(Username userName) throws Exception {
-        try {
-            JamesUser user = getJamesUser(userName);
-            if (!user.getAliasing()) {
-                throw new UsersRepositoryException("User " + user + " is no alias");
-            }
-            user.setAliasing(false);
-            usersRepository.updateUser(user);
-        } catch (UsersRepositoryException e) {
-            throw new Exception(e.getMessage());
-        }
-    }
-
-    @Override
-    public String getAlias(Username userName) throws Exception {
-        try {
-            JamesUser user = getJamesUser(userName);
-            if (!user.getAliasing()) {
-                return null;
-            }
-            return user.getAlias();
-        } catch (UsersRepositoryException e) {
-            throw new Exception(e.getMessage());
-
-        }
-    }
-
-    @Override
-    public void unsetForwardAddress(Username userName) throws Exception {
-        try {
-            JamesUser user = getJamesUser(userName);
-            if (!user.getForwarding()) {
-                throw new UsersRepositoryException("User " + user + " is no forward");
-            }
-            user.setForwarding(false);
-            usersRepository.updateUser(user);
-        } catch (UsersRepositoryException e) {
-            throw new Exception(e.getMessage());
-        }
-    }
-
-    @Override
-    public String getForwardAddress(Username userName) throws Exception {
-        try {
-            JamesUser user = getJamesUser(userName);
-            if (!user.getForwarding()) {
-                return null;
-            }
-            return user.getForwardingDestination().toString();
-        } catch (UsersRepositoryException e) {
-            throw new Exception(e.getMessage());
-        }
-    }
-
-    @Override
     public boolean getVirtualHostingEnabled() throws Exception {
         try {
             return usersRepository.supportVirtualHosting();
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/WhiteListManager.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/WhiteListManager.java
index 12c35a0..4e78ea1 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/WhiteListManager.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/WhiteListManager.java
@@ -48,9 +48,7 @@ import javax.sql.DataSource;
 
 import org.apache.james.core.Domain;
 import org.apache.james.core.MailAddress;
-import org.apache.james.core.Username;
 import org.apache.james.user.api.UsersRepository;
-import org.apache.james.user.api.model.JamesUser;
 import org.apache.james.util.sql.JDBCUtil;
 import org.apache.james.util.sql.SqlResources;
 import org.apache.mailet.Experimental;
@@ -296,8 +294,6 @@ public class WhiteListManager extends GenericMailet {
         String senderUser = senderMailAddress.getLocalPart().toLowerCase(Locale.US);
         Domain senderHost = senderMailAddress.getDomain();
 
-        senderUser = getPrimaryName(senderUser);
-
         Connection conn = null;
         PreparedStatement selectStmt = null;
         PreparedStatement insertStmt = null;
@@ -380,8 +376,6 @@ public class WhiteListManager extends GenericMailet {
         String senderUser = senderMailAddress.getLocalPart().toLowerCase(Locale.US);
         Domain senderHost = senderMailAddress.getDomain();
 
-        senderUser = getPrimaryName(senderUser);
-
         Connection conn = null;
         PreparedStatement selectStmt = null;
         ResultSet selectRS = null;
@@ -428,8 +422,6 @@ public class WhiteListManager extends GenericMailet {
         String senderUser = senderMailAddress.getLocalPart().toLowerCase(Locale.US);
         Domain senderHost = senderMailAddress.getDomain();
 
-        senderUser = getPrimaryName(senderUser);
-
         Connection conn = null;
         PreparedStatement selectStmt = null;
         PreparedStatement insertStmt = null;
@@ -549,8 +541,6 @@ public class WhiteListManager extends GenericMailet {
         String senderUser = senderMailAddress.getLocalPart().toLowerCase(Locale.US);
         Domain senderHost = senderMailAddress.getDomain();
 
-        senderUser = getPrimaryName(senderUser);
-
         Connection conn = null;
         PreparedStatement selectStmt = null;
         PreparedStatement deleteStmt = null;
@@ -718,23 +708,6 @@ public class WhiteListManager extends GenericMailet {
     }
 
     /**
-     * Gets the main name of a local customer, handling alias
-     */
-    private String getPrimaryName(String originalUsername) {
-        String username;
-        try {
-            username = originalUsername;
-            JamesUser user = (JamesUser) localusers.getUserByName(Username.of(username));
-            if (user.getAliasing()) {
-                username = user.getAlias();
-            }
-        } catch (Exception e) {
-            username = originalUsername;
-        }
-        return username;
-    }
-
-    /**
      * Initializes the sql query environment from the SqlResources file. Will
      * look for conf/sqlResources.xml.
      * 
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/AbstractSQLWhitelistMatcher.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/AbstractSQLWhitelistMatcher.java
index d088f1c..409ff3c 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/AbstractSQLWhitelistMatcher.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/AbstractSQLWhitelistMatcher.java
@@ -36,11 +36,9 @@ import javax.sql.DataSource;
 
 import org.apache.james.core.Domain;
 import org.apache.james.core.MailAddress;
-import org.apache.james.core.Username;
 import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.transport.mailets.WhiteListManager;
 import org.apache.james.user.api.UsersRepository;
-import org.apache.james.user.api.model.JamesUser;
 import org.apache.james.util.sql.JDBCUtil;
 import org.apache.james.util.sql.SqlResources;
 import org.apache.mailet.Experimental;
@@ -162,8 +160,6 @@ public abstract class AbstractSQLWhitelistMatcher extends GenericMatcher {
                 continue;
             }
 
-            recipientUser = getPrimaryName(recipientUser);
-
             if (matchedWhitelist(recipientMailAddress, mail)) {
                 // This address was already in the list
                 inWhiteList.add(recipientMailAddress);
@@ -178,23 +174,6 @@ public abstract class AbstractSQLWhitelistMatcher extends GenericMatcher {
     protected abstract boolean matchedWhitelist(MailAddress recipient, Mail mail) throws MessagingException;
 
     /**
-     * Gets the main name of a local customer, handling alias
-     */
-    protected String getPrimaryName(String originalUsername) {
-        String username;
-        try {
-            username = originalUsername;
-            JamesUser user = (JamesUser) localusers.getUserByName(Username.of(username));
-            if (user.getAliasing()) {
-                username = user.getAlias();
-            }
-        } catch (Exception e) {
-            username = originalUsername;
-        }
-        return username;
-    }
-
-    /**
      * Initializes the sql query environment from the SqlResources file.<br>
      * Will look for conf/sqlResources.xml.<br>
      * Will <strong>not</<strong> create the database resources, if missing<br>


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


[james-project] 32/41: JAMES-2979 fix spooler mail dequeue

Posted by bt...@apache.org.
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 438bb45b76690dce5467fd3a12393ca3ea8e1934
Author: Rémi KOWALSKI <rk...@linagora.com>
AuthorDate: Thu Nov 14 14:01:46 2019 +0100

    JAMES-2979 fix spooler mail dequeue
---
 .../java/org/apache/james/mailetcontainer/impl/JamesMailSpooler.java   | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/JamesMailSpooler.java b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/JamesMailSpooler.java
index e2101d1..2bd7ed0 100644
--- a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/JamesMailSpooler.java
+++ b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/JamesMailSpooler.java
@@ -107,8 +107,7 @@ public class JamesMailSpooler implements Disposable, Configurable, MailSpoolerMB
         LOGGER.info("Queue={}", queue);
 
         disposable = Flux.from(queue.deQueue())
-            .publishOn(spooler)
-            .flatMap(this::handleOnQueueItem)
+            .flatMap(item -> handleOnQueueItem(item).subscribeOn(spooler))
             .onErrorContinue((throwable, item) -> LOGGER.error("Exception processing mail while spooling {}", item, throwable))
             .subscribeOn(Schedulers.boundedElastic())
             .subscribe();


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


[james-project] 08/41: Changelog entry for ElasticSearch authentication + SSL

Posted by bt...@apache.org.
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 cda46cad786eeeb148a379c461402b03d54c0404
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed Nov 13 13:21:44 2019 +0700

    Changelog entry for ElasticSearch authentication + SSL
---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index f73b608..458a8eb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 of tasks being currently executed.
 - JAMES-2563 Health check for ElasticSearch
 - JAMES-2904 Authentication and SSL support for Cassandra backend
+- JAMES-2904 Authentication and SSL support for ElasticSearch backend
 
 ### Changed
 - Multiple changes have been made to enhance ElasticSearch performance:


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


[james-project] 27/41: JAMES-2813 give DTOConvert methods more explicit names

Posted by bt...@apache.org.
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 1549e776d9e91448516e8371edde310ecfa36c94
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Fri Oct 25 11:23:15 2019 +0200

    JAMES-2813 give DTOConvert methods more explicit names
---
 .../main/java/org/apache/james/json/DTOConverter.java    |  4 ++--
 .../org/apache/james/json/JsonGenericSerializer.java     |  4 ++--
 json/src/test/java/org/apache/DTOConverterTest.java      | 12 ++++++------
 json/src/test/java/org/apache/dto/FirstDTO.java          |  2 +-
 json/src/test/java/org/apache/dto/SecondDTO.java         |  2 +-
 json/src/test/java/org/apache/dto/TestModules.java       |  4 ++--
 .../james/mailbox/quota/cassandra/dto/DTOTest.java       |  2 ++
 .../james/dlp/eventsourcing/cassandra/DTOTest.java       |  4 ++++
 .../apache/james/jmap/cassandra/filtering/DTOTest.java   |  5 +++++
 .../rabbitmq/view/cassandra/configuration/DTOTest.java   |  3 +++
 .../task/eventsourcing/distributed/TaskEventDTO.scala    | 16 ++++++++--------
 11 files changed, 36 insertions(+), 22 deletions(-)

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 d49b623..80b9390 100644
--- a/json/src/main/java/org/apache/james/json/DTOConverter.java
+++ b/json/src/main/java/org/apache/james/json/DTOConverter.java
@@ -50,7 +50,7 @@ public class DTOConverter<T, U extends DTO> {
     }
 
     @SuppressWarnings("unchecked")
-    public Optional<U> convert(T domainObject) {
+    public Optional<U> toDTO(T domainObject) {
         return Optional
             .ofNullable(domainClassToModule.get(domainObject.getClass()))
             .map(module -> (DTOModule<T, U>) module)
@@ -58,7 +58,7 @@ public class DTOConverter<T, U extends DTO> {
     }
 
     @SuppressWarnings("unchecked")
-    public Optional<T> convert(U dto) {
+    public Optional<T> toDomainObject(U dto) {
         String type = dto.getType();
         return Optional
             .ofNullable(typeToModule.get(type))
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 0cf11dc..6ebb443 100644
--- a/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
+++ b/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
@@ -120,7 +120,7 @@ public class JsonGenericSerializer<T, U extends DTO> {
     }
 
     public String serialize(T domainObject) throws JsonProcessingException {
-        U dto = dtoConverter.convert(domainObject)
+        U dto = dtoConverter.toDTO(domainObject)
             .orElseThrow(() -> new UnknownTypeException("unknown type " + domainObject.getClass()));
         return objectMapper.writeValueAsString(dto);
     }
@@ -128,7 +128,7 @@ public class JsonGenericSerializer<T, U extends DTO> {
 
     public T deserialize(String value) throws IOException {
         U dto = jsonToDTO(value);
-        return dtoConverter.convert(dto)
+        return dtoConverter.toDomainObject(dto)
             .orElseThrow(() -> new UnknownTypeException("unknown type " + dto.getType()));
     }
 
diff --git a/json/src/test/java/org/apache/DTOConverterTest.java b/json/src/test/java/org/apache/DTOConverterTest.java
index 6783b0e..1c34498 100644
--- a/json/src/test/java/org/apache/DTOConverterTest.java
+++ b/json/src/test/java/org/apache/DTOConverterTest.java
@@ -53,14 +53,14 @@ class DTOConverterTest {
     void shouldConvertFromKnownDTO() throws Exception {
         assertThat(DTOConverter
             .<BaseType, DTO>of(TestModules.FIRST_TYPE)
-            .convert(FIRST_DTO))
+            .toDomainObject(FIRST_DTO))
             .contains(FIRST);
     }
 
     @Test
     void shouldReturnEmptyWhenConvertingFromUnknownDTO() {
         assertThat(DTOConverter.of()
-            .convert(FIRST_DTO))
+            .toDomainObject(FIRST_DTO))
             .isEmpty();
     }
 
@@ -72,7 +72,7 @@ class DTOConverterTest {
                 TestModules.FIRST_TYPE,
                 TestModules.SECOND_TYPE);
 
-        assertThat(serializer.convert(domainObject))
+        assertThat(serializer.toDTO(domainObject))
             .hasValueSatisfying(result -> assertThat(result).isInstanceOf(dto.getClass()).isEqualToComparingFieldByField(dto));
     }
 
@@ -88,7 +88,7 @@ class DTOConverterTest {
                 TestModules.FIRST_TYPE,
                 TestModules.SECOND_TYPE);
 
-        assertThat(serializer.convert(dto))
+        assertThat(serializer.toDomainObject(dto))
             .hasValueSatisfying(result -> assertThat(result).isInstanceOf(domainObject.getClass()).isEqualToComparingFieldByField(domainObject));
     }
 
@@ -107,13 +107,13 @@ class DTOConverterTest {
     @Test
     void shouldConvertFromKnownDomainObject() throws Exception {
         assertThat(DTOConverter.<BaseType, DTO>of(TestModules.FIRST_TYPE)
-            .convert(FIRST))
+            .toDTO(FIRST))
             .hasValueSatisfying(result -> assertThat(result).isInstanceOf(FirstDTO.class).isEqualToComparingFieldByField(FIRST_DTO));
     }
 
     @Test
     void shouldReturnEmptyWhenConvertUnknownDomainObject() {
-        assertThat(DTOConverter.of().convert(FIRST))
+        assertThat(DTOConverter.of().toDTO(FIRST))
             .isEmpty();
     }
 }
diff --git a/json/src/test/java/org/apache/dto/FirstDTO.java b/json/src/test/java/org/apache/dto/FirstDTO.java
index b1bdf23..16c1041 100644
--- a/json/src/test/java/org/apache/dto/FirstDTO.java
+++ b/json/src/test/java/org/apache/dto/FirstDTO.java
@@ -72,6 +72,6 @@ public class FirstDTO implements DTO {
 
     @JsonIgnore
     public FirstDomainObject toDomainObject(DTOConverter<NestedType, DTO> converter) {
-        return new FirstDomainObject(id, ZonedDateTime.parse(time), payload, child.flatMap(converter::convert));
+        return new FirstDomainObject(id, ZonedDateTime.parse(time), payload, child.flatMap(converter::toDomainObject));
     }
 }
diff --git a/json/src/test/java/org/apache/dto/SecondDTO.java b/json/src/test/java/org/apache/dto/SecondDTO.java
index be66948..91204a8 100644
--- a/json/src/test/java/org/apache/dto/SecondDTO.java
+++ b/json/src/test/java/org/apache/dto/SecondDTO.java
@@ -65,6 +65,6 @@ public class SecondDTO implements DTO {
 
     @JsonIgnore
     public SecondDomainObject toDomainObject(DTOConverter<NestedType, DTO> converter) {
-        return new SecondDomainObject(UUID.fromString(id), payload, child.flatMap(converter::convert));
+        return new SecondDomainObject(UUID.fromString(id), payload, child.flatMap(converter::toDomainObject));
     }
 }
diff --git a/json/src/test/java/org/apache/dto/TestModules.java b/json/src/test/java/org/apache/dto/TestModules.java
index d7cb781..a8de0b3 100644
--- a/json/src/test/java/org/apache/dto/TestModules.java
+++ b/json/src/test/java/org/apache/dto/TestModules.java
@@ -55,7 +55,7 @@ public interface TestModules {
             domainObject.getId(),
             domainObject.getTime().toString(),
             domainObject.getPayload(),
-            domainObject.getChild().flatMap(NESTED_CONVERTERS::convert)))
+            domainObject.getChild().flatMap(NESTED_CONVERTERS::toDTO)))
         .typeName("first")
         .withFactory(TestModule::new);
 
@@ -67,7 +67,7 @@ public interface TestModules {
             typeName,
             domainObject.getId().toString(),
             domainObject.getPayload(),
-            domainObject.getChild().flatMap(NESTED_CONVERTERS::convert)))
+            domainObject.getChild().flatMap(NESTED_CONVERTERS::toDTO)))
         .typeName("second")
         .withFactory(TestModule::new);
 
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java
index 394bf6f..3e3d824 100644
--- a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java
@@ -44,6 +44,7 @@ import org.junit.jupiter.api.Test;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.jsontype.NamedType;
 import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
 
 class DTOTest {
@@ -104,6 +105,7 @@ class DTOTest {
         objectMapper = new ObjectMapper();
         objectMapper.registerModule(new Jdk8Module());
         objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
+        objectMapper.registerSubtypes(new NamedType(QuotaThresholdChangedEventDTO.class, "quota-threshold-change"));
     }
 
     @Test
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
index 3357ba8..062b132 100644
--- 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
@@ -37,6 +37,7 @@ import org.junit.jupiter.api.Test;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.jsontype.NamedType;
 import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
 import com.google.common.collect.ImmutableList;
 
@@ -92,6 +93,9 @@ public class DTOTest {
         objectMapper = new ObjectMapper();
         objectMapper.registerModule(new Jdk8Module());
         objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
+        objectMapper.registerSubtypes(
+            new NamedType(DLPConfigurationItemsRemovedDTO.class, "dlp-configuration-clear"),
+            new NamedType(DLPConfigurationItemAddedDTO.class, "dlp-configuration-store"));
     }
 
     @Test
diff --git a/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/filtering/DTOTest.java b/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/filtering/DTOTest.java
index fbfddb9..a3e4d29 100644
--- a/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/filtering/DTOTest.java
+++ b/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/filtering/DTOTest.java
@@ -33,6 +33,8 @@ import org.apache.james.eventsourcing.EventId;
 import org.apache.james.jmap.api.filtering.impl.FilteringAggregateId;
 import org.apache.james.jmap.api.filtering.impl.RuleSetDefined;
 import org.apache.james.util.ClassLoaderUtils;
+
+import com.fasterxml.jackson.databind.jsontype.NamedType;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -68,6 +70,9 @@ public class DTOTest {
         objectMapper = new ObjectMapper();
         objectMapper.registerModule(new Jdk8Module());
         objectMapper.registerModule(new GuavaModule());
+        objectMapper.registerSubtypes(
+            new NamedType(FilteringRuleSetDefinedDTO.class, "filtering-rule-set-defined"));
+
     }
 
     @Test
diff --git a/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/DTOTest.java b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/DTOTest.java
index 4bf2658..be2c32a 100644
--- a/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/DTOTest.java
+++ b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/DTOTest.java
@@ -26,6 +26,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 import java.time.Duration;
 
+import com.fasterxml.jackson.databind.jsontype.NamedType;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -56,6 +57,8 @@ class DTOTest {
         objectMapper.registerModule(new Jdk8Module());
         objectMapper.registerModule(new JavaTimeModule());
         objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
+        objectMapper.registerSubtypes(
+            new NamedType(ConfigurationChangedDTO.class, "cassandra-mail-queue-view-configuration"));
     }
 
     @Test
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 51761ad..ce4184c 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
@@ -91,7 +91,7 @@ case class CompletedDTO(@JsonProperty("type") typeName: String,
                         @JsonProperty("additionalInformation") getAdditionalInformation: Optional[AdditionalInformationDTO])
   extends TaskEventDTO(typeName, aggregateId, eventId) {
   def toDomainObject(additionalInformationConverter: AdditionalInformationConverter): Completed = {
-    val additionalInformation: Optional[TaskExecutionDetails.AdditionalInformation] = getAdditionalInformation.map(additionalInformationConverter.convert(_).orElseThrow())
+    val additionalInformation: Optional[TaskExecutionDetails.AdditionalInformation] = getAdditionalInformation.map(additionalInformationConverter.toDomainObject(_).orElseThrow())
     Completed(domainAggregateId, domainEventId, domainResult, additionalInformation.asScala)
   }
   private def domainResult: Task.Result = getResult match {
@@ -102,7 +102,7 @@ case class CompletedDTO(@JsonProperty("type") typeName: String,
 
 object CompletedDTO {
   def fromDomainObject(dtoConverter: AdditionalInformationConverter)(event: Completed, typeName: String): CompletedDTO = {
-    val additionalInformationDTO: Optional[AdditionalInformationDTO] = event.additionalInformation.asJava.map(dtoConverter.convert(_).orElseThrow())
+    val additionalInformationDTO: Optional[AdditionalInformationDTO] = event.additionalInformation.asJava.map(dtoConverter.toDTO(_).orElseThrow())
     CompletedDTO(typeName, event.aggregateId.taskId.asString(), event.eventId.serialize(), resultToString(event.result), additionalInformationDTO)
   }
 
@@ -120,14 +120,14 @@ case class FailedDTO(@JsonProperty("type") typeName: String,
                      @JsonProperty("exception") getException: Optional[String])
   extends TaskEventDTO(typeName, aggregateId, eventId) {
   def toDomainObject(additionalInformationConverter: AdditionalInformationConverter): Failed = {
-    val additionalInformation: Optional[TaskExecutionDetails.AdditionalInformation] = getAdditionalInformation.map(additionalInformationConverter.convert(_).orElseThrow())
+    val additionalInformation: Optional[TaskExecutionDetails.AdditionalInformation] = getAdditionalInformation.map(additionalInformationConverter.toDomainObject(_).orElseThrow())
     Failed(domainAggregateId, domainEventId, additionalInformation.asScala, getErrorMessage.asScala, getException.asScala)
   }
 }
 
 object FailedDTO {
   def fromDomainObject(dtoConverter: AdditionalInformationConverter)(event: Failed, typeName: String): FailedDTO = {
-    val additionalInformationDTO: Optional[AdditionalInformationDTO] = event.additionalInformation.asJava.map(dtoConverter.convert(_).orElseThrow())
+    val additionalInformationDTO: Optional[AdditionalInformationDTO] = event.additionalInformation.asJava.map(dtoConverter.toDTO(_).orElseThrow())
     FailedDTO(typeName, event.aggregateId.taskId.asString(), event.eventId.serialize(), additionalInformationDTO, event.errorMessage.asJava, event.exception.asJava)
   }
 }
@@ -138,14 +138,14 @@ case class CancelledDTO(@JsonProperty("type") typeName: String,
                         @JsonProperty("additionalInformation") getAdditionalInformation: Optional[AdditionalInformationDTO])
   extends TaskEventDTO(typeName, aggregateId, eventId) {
   def toDomainObject(additionalInformationConverter: AdditionalInformationConverter): Cancelled = {
-    val additionalInformation: Optional[TaskExecutionDetails.AdditionalInformation] = getAdditionalInformation.map(additionalInformationConverter.convert(_).orElseThrow())
+    val additionalInformation: Optional[TaskExecutionDetails.AdditionalInformation] = getAdditionalInformation.map(additionalInformationConverter.toDomainObject(_).orElseThrow())
     Cancelled(domainAggregateId, domainEventId, additionalInformation.asScala)
   }
 }
 
 object CancelledDTO {
   def fromDomainObject(additionalInformationConverter: AdditionalInformationConverter)(event: Cancelled, typeName: String): CancelledDTO = {
-    val additionalInformationDTO: Optional[AdditionalInformationDTO] = event.additionalInformation.asJava.map(additionalInformationConverter.convert(_).orElseThrow())
+    val additionalInformationDTO: Optional[AdditionalInformationDTO] = event.additionalInformation.asJava.map(additionalInformationConverter.toDTO(_).orElseThrow())
     CancelledDTO(typeName, event.aggregateId.taskId.asString(), event.eventId.serialize(), additionalInformationDTO)
   }
 }
@@ -156,7 +156,7 @@ case class AdditionalInformationUpdatedDTO(@JsonProperty("type") typeName: Strin
                      @JsonProperty("additionalInformation") getAdditionalInformation: AdditionalInformationDTO)
   extends TaskEventDTO(typeName, aggregateId, eventId) {
   def toDomainObject(additionalInformationConverter: AdditionalInformationConverter): AdditionalInformationUpdated = {
-    val additionalInformation = additionalInformationConverter.convert(getAdditionalInformation)
+    val additionalInformation = additionalInformationConverter.toDomainObject(getAdditionalInformation)
         .orElseThrow()
     AdditionalInformationUpdated(domainAggregateId, domainEventId, additionalInformation)
   }
@@ -164,7 +164,7 @@ case class AdditionalInformationUpdatedDTO(@JsonProperty("type") typeName: Strin
 
 object AdditionalInformationUpdatedDTO {
   def fromDomainObject(additionalInformationConverter: AdditionalInformationConverter)(event: AdditionalInformationUpdated, typeName: String): AdditionalInformationUpdatedDTO = {
-    val additionalInformationDTO = additionalInformationConverter.convert(event.additionalInformation)
+    val additionalInformationDTO = additionalInformationConverter.toDTO(event.additionalInformation)
         .orElseThrow()
     AdditionalInformationUpdatedDTO(typeName, event.aggregateId.taskId.asString(), event.eventId.serialize(), additionalInformationDTO)
   }


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


[james-project] 11/41: JAMES-2981 Changelog for Cassandra keyspace creation

Posted by bt...@apache.org.
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 a4c20b152d6949186788a35f960264553dc2ce78
Author: Rémi KOWALSKI <rk...@linagora.com>
AuthorDate: Fri Nov 15 15:21:09 2019 +0100

    JAMES-2981 Changelog for Cassandra keyspace creation
---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 289f9f5..0c96758 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,7 @@ of tasks being currently executed.
   - Disable dynamic mapping thanks to a change of the header structure 
   - Read related [upgrade instructions](upgrade-instructions.md)
 - JAMES-2855 Multiple library/plugin/docker images/build tool upgrades
+- By default the cassandra keyspace creation by James is now disabled by default. This allow to have credentials limited to a keyspace. It can be enabled by setting cassandra.keyspace.create=true in the cassandra.properties file.
   
 ### Fixed
 - JAMES-2828 & JAMES-2929 bugs affecting JDBCMailRepository usage with PostgresSQL thanks to Jörg Thomas & Sergey B


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


[james-project] 15/41: JAMES-2813 build a Set of modules as we always need a Set

Posted by bt...@apache.org.
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 7324d85ec041a031f927a6880f4307a330caf107
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Thu Oct 17 16:17:09 2019 +0200

    JAMES-2813 build a Set of modules as we always need a Set
---
 .../task/eventsourcing/distributed/TasksSerializationModule.java    | 6 +++---
 .../task/eventsourcing/distributed/TaskEventsSerializationTest.java | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

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 22ad061..5e06f1c 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
@@ -19,7 +19,7 @@
 
 package org.apache.james.task.eventsourcing.distributed;
 
-import java.util.List;
+import java.util.Set;
 import java.util.function.BiFunction;
 import java.util.stream.Stream;
 
@@ -99,8 +99,8 @@ public interface TasksSerializationModule {
         .typeName("task-manager-updated")
         .withFactory(EventDTOModule::new);
 
-    BiFunction<JsonTaskSerializer, JsonTaskAdditionalInformationSerializer, List<EventDTOModule<?, ?>>> MODULES = (jsonTaskSerializer, jsonTaskAdditionalInformationSerializer) -> Stream
+    BiFunction<JsonTaskSerializer, JsonTaskAdditionalInformationSerializer, Set<EventDTOModule<?, ?>>> MODULES = (jsonTaskSerializer, jsonTaskAdditionalInformationSerializer) -> Stream
         .of(CREATED, STARTED, CANCEL_REQUESTED, CANCELLED, COMPLETED, FAILED, UPDATED)
         .map(moduleFactory -> moduleFactory.create(jsonTaskSerializer, jsonTaskAdditionalInformationSerializer))
-        .collect(Guavate.toImmutableList());
+        .collect(Guavate.toImmutableSet());
 }
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 aba2449..5d53c4b 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,7 +22,7 @@ package org.apache.james.task.eventsourcing.distributed;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.time.Instant;
-import java.util.List;
+import java.util.Set;
 import java.util.stream.Stream;
 
 import org.apache.james.eventsourcing.EventId;
@@ -59,7 +59,7 @@ class TaskEventsSerializationTest {
     private static final JsonTaskSerializer TASK_SERIALIZER = new JsonTaskSerializer(TestTaskDTOModules.COMPLETED_TASK_MODULE,
         TestTaskDTOModules.MEMORY_REFERENCE_WITH_COUNTER_TASK_MODULE.apply(new MemoryReferenceWithCounterTaskStore()));
     private static final JsonTaskAdditionalInformationSerializer TASK_ADDITIONNAL_INFORMATION_SERIALIZER = new JsonTaskAdditionalInformationSerializer(MemoryReferenceWithCounterTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
-    private static final List<EventDTOModule<?, ?>> MODULES = TasksSerializationModule.MODULES.apply(TASK_SERIALIZER, TASK_ADDITIONNAL_INFORMATION_SERIALIZER);
+    private static final Set<EventDTOModule<?, ?>> MODULES = TasksSerializationModule.MODULES.apply(TASK_SERIALIZER, TASK_ADDITIONNAL_INFORMATION_SERIALIZER);
     private static final JsonEventSerializer SERIALIZER = new JsonEventSerializer(MODULES.stream().collect(Guavate.toImmutableSet()));
     private static final TaskAggregateId AGGREGATE_ID = new TaskAggregateId(TaskId.fromString("2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd"));
     private static final EventId EVENT_ID = EventId.fromSerialized(42);


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


[james-project] 07/41: Changelog for Distributed Task Management

Posted by bt...@apache.org.
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 2a53b84c7197c44d5c6add6c7c2e75255cf4b32a
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Nov 11 14:37:20 2019 +0700

    Changelog for Distributed Task Management
---
 CHANGELOG.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 94c2b87..f73b608 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 ## [Unreleased]
 
 ### Added
-- Distributed task management for Guice cassandra-rabbitmq product. This enables two James servers to share a consistent view
+- Distributed task management for Guice cassandra-rabbitmq product. This enables several James servers to share a consistent view
 of tasks being currently executed.
 - JAMES-2563 Health check for ElasticSearch
 - JAMES-2904 Authentication and SSL support for Cassandra backend


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


[james-project] 03/41: Changelog for various bug fixes

Posted by bt...@apache.org.
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 cc10d4b674604c1da0cde0077aac512cc271d1c5
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Nov 1 18:07:32 2019 +0700

    Changelog for various bug fixes
---
 CHANGELOG.md            | 13 ++++++++++++-
 upgrade-instructions.md |  2 +-
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 07e0744..1f9241c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 ## [Unreleased]
 
 ### Added
-- Distributed task management for Guice cassandra-rabbitmq product. This enables two James server to share a consistent view
+- Distributed task management for Guice cassandra-rabbitmq product. This enables two James servers to share a consistent view
 of tasks being currently executed.
 
 ### Changed
@@ -16,6 +16,17 @@ of tasks being currently executed.
   - Removed unnecessary fields from mailbox mapping
   - Disable dynamic mapping thanks to a change of the header structure 
   - Read related [upgrade instructions](upgrade-instructions.md)
+  
+### Fixed
+- JAMES-2828 & JAMES-2929 bugs affecting JDBCMailRepository usage with PostgresSQL thanks to Jörg Thomas & Sergey B
+- JAMES-2936 Creating a mailbox using consecutive delimiter character leads to creation of list of unnamed mailbox
+- JAMES-2911 Unable to send mail from James using an SMTP gateway
+- JAMES-2944 Inlined attachments should be wrapped in multipart/related by JMAP draft
+- JAMES-2941 Return NO when an IMAP command unexpectedly fails
+- JAMES-2943 Deleting auto detected domain should fail
+- JAMES-2957 dlp.Dlp matcher should parse emails containing attachments
+- JAMES-2958 Limit domain name size to not longer than 255 characters
+- JAMES-2939 Prevent mixed case INBOX creation
 
 ### Removed
 - Classes marked as deprecated whose removal was planned after 3.4.0 release (See JAMES-2703). This includes:
diff --git a/upgrade-instructions.md b/upgrade-instructions.md
index 0566952..f4f9b5a 100644
--- a/upgrade-instructions.md
+++ b/upgrade-instructions.md
@@ -52,7 +52,7 @@ We significantly improved our usage of ElasticSearch. Underlying changes include
  level synchronisation, and thus enhance throughput, latencies and scalability.
  - Disabling dynamic mapping. We now represent headers as nested objects.
  - Removing some not needed fields from the mapping
- - No longer index raw HTML. This was possible under some configuration combinaison, and caused the data stored in elasticSearch
+ - No longer index raw HTML. This was possible under some configuration combination, and caused the data stored in elasticSearch
  to be significantly larger than required.
 
 The downside of these changes is that a reindex is needed, implying a downtime on search:


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


[james-project] 30/41: JAMES-2813 Add throws in TaskEventDTO

Posted by bt...@apache.org.
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 d9bdff3c2634917cdf964331ec5cde713cd3138c
Author: Gautier DI FOLCO <gd...@linagora.com>
AuthorDate: Wed Nov 13 15:40:55 2019 +0100

    JAMES-2813 Add throws in TaskEventDTO
---
 .../eventsourcing/distributed/TaskEventDTO.scala   | 40 ++++++++++++++++------
 1 file changed, 30 insertions(+), 10 deletions(-)

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 ce4184c..a886427 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
@@ -28,6 +28,7 @@ import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO
 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.AdditionalInformation
 import org.apache.james.task.eventsourcing._
 import org.apache.james.task.eventsourcing.distributed.distributed.AdditionalInformationConverter
 import org.apache.james.task.{Hostname, Task, TaskExecutionDetails, TaskId}
@@ -38,6 +39,12 @@ package object distributed {
   type AdditionalInformationConverter = DTOConverter[TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO]
 }
 
+class NestedAdditionalInformationDTODeserializerNotFound(val dto: AdditionalInformationDTO) extends RuntimeException("Unable to find a deserializer for " + dto) {
+}
+
+class NestedAdditionalInformationDTOSerializerNotFound(val domainObject: AdditionalInformation) extends RuntimeException("Unable to find a serializer for " + domainObject) {
+}
+
 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)
@@ -91,7 +98,8 @@ case class CompletedDTO(@JsonProperty("type") typeName: String,
                         @JsonProperty("additionalInformation") getAdditionalInformation: Optional[AdditionalInformationDTO])
   extends TaskEventDTO(typeName, aggregateId, eventId) {
   def toDomainObject(additionalInformationConverter: AdditionalInformationConverter): Completed = {
-    val additionalInformation: Optional[TaskExecutionDetails.AdditionalInformation] = getAdditionalInformation.map(additionalInformationConverter.toDomainObject(_).orElseThrow())
+    val additionalInformation: Optional[TaskExecutionDetails.AdditionalInformation] = getAdditionalInformation
+      .map(dto => additionalInformationConverter.toDomainObject(dto).orElseThrow(() => new NestedAdditionalInformationDTODeserializerNotFound(dto)))
     Completed(domainAggregateId, domainEventId, domainResult, additionalInformation.asScala)
   }
   private def domainResult: Task.Result = getResult match {
@@ -102,7 +110,10 @@ case class CompletedDTO(@JsonProperty("type") typeName: String,
 
 object CompletedDTO {
   def fromDomainObject(dtoConverter: AdditionalInformationConverter)(event: Completed, typeName: String): CompletedDTO = {
-    val additionalInformationDTO: Optional[AdditionalInformationDTO] = event.additionalInformation.asJava.map(dtoConverter.toDTO(_).orElseThrow())
+    val additionalInformationDTO: Optional[AdditionalInformationDTO] = event
+      .additionalInformation
+      .asJava
+      .map(domainObject => dtoConverter.toDTO(domainObject).orElseThrow(() => new NestedAdditionalInformationDTOSerializerNotFound(domainObject)))
     CompletedDTO(typeName, event.aggregateId.taskId.asString(), event.eventId.serialize(), resultToString(event.result), additionalInformationDTO)
   }
 
@@ -120,14 +131,17 @@ case class FailedDTO(@JsonProperty("type") typeName: String,
                      @JsonProperty("exception") getException: Optional[String])
   extends TaskEventDTO(typeName, aggregateId, eventId) {
   def toDomainObject(additionalInformationConverter: AdditionalInformationConverter): Failed = {
-    val additionalInformation: Optional[TaskExecutionDetails.AdditionalInformation] = getAdditionalInformation.map(additionalInformationConverter.toDomainObject(_).orElseThrow())
+    val additionalInformation: Optional[TaskExecutionDetails.AdditionalInformation] = getAdditionalInformation
+      .map(dto => additionalInformationConverter.toDomainObject(dto).orElseThrow(() => new NestedAdditionalInformationDTODeserializerNotFound(dto)))
     Failed(domainAggregateId, domainEventId, additionalInformation.asScala, getErrorMessage.asScala, getException.asScala)
   }
 }
 
 object FailedDTO {
   def fromDomainObject(dtoConverter: AdditionalInformationConverter)(event: Failed, typeName: String): FailedDTO = {
-    val additionalInformationDTO: Optional[AdditionalInformationDTO] = event.additionalInformation.asJava.map(dtoConverter.toDTO(_).orElseThrow())
+    val additionalInformationDTO: Optional[AdditionalInformationDTO] = event
+      .additionalInformation
+      .asJava.map(domainObject => dtoConverter.toDTO(domainObject).orElseThrow(() => new NestedAdditionalInformationDTOSerializerNotFound(domainObject)))
     FailedDTO(typeName, event.aggregateId.taskId.asString(), event.eventId.serialize(), additionalInformationDTO, event.errorMessage.asJava, event.exception.asJava)
   }
 }
@@ -138,14 +152,18 @@ case class CancelledDTO(@JsonProperty("type") typeName: String,
                         @JsonProperty("additionalInformation") getAdditionalInformation: Optional[AdditionalInformationDTO])
   extends TaskEventDTO(typeName, aggregateId, eventId) {
   def toDomainObject(additionalInformationConverter: AdditionalInformationConverter): Cancelled = {
-    val additionalInformation: Optional[TaskExecutionDetails.AdditionalInformation] = getAdditionalInformation.map(additionalInformationConverter.toDomainObject(_).orElseThrow())
+    val additionalInformation: Optional[TaskExecutionDetails.AdditionalInformation] = getAdditionalInformation
+      .map(dto => additionalInformationConverter.toDomainObject(dto).orElseThrow(() => new NestedAdditionalInformationDTODeserializerNotFound(dto)))
     Cancelled(domainAggregateId, domainEventId, additionalInformation.asScala)
   }
 }
 
 object CancelledDTO {
   def fromDomainObject(additionalInformationConverter: AdditionalInformationConverter)(event: Cancelled, typeName: String): CancelledDTO = {
-    val additionalInformationDTO: Optional[AdditionalInformationDTO] = event.additionalInformation.asJava.map(additionalInformationConverter.toDTO(_).orElseThrow())
+    val additionalInformationDTO: Optional[AdditionalInformationDTO] = event
+      .additionalInformation
+      .asJava
+      .map(domainObject => additionalInformationConverter.toDTO(domainObject).orElseThrow(() => new NestedAdditionalInformationDTOSerializerNotFound(domainObject)))
     CancelledDTO(typeName, event.aggregateId.taskId.asString(), event.eventId.serialize(), additionalInformationDTO)
   }
 }
@@ -156,16 +174,18 @@ case class AdditionalInformationUpdatedDTO(@JsonProperty("type") typeName: Strin
                      @JsonProperty("additionalInformation") getAdditionalInformation: AdditionalInformationDTO)
   extends TaskEventDTO(typeName, aggregateId, eventId) {
   def toDomainObject(additionalInformationConverter: AdditionalInformationConverter): AdditionalInformationUpdated = {
-    val additionalInformation = additionalInformationConverter.toDomainObject(getAdditionalInformation)
-        .orElseThrow()
+    val additionalInformation = additionalInformationConverter
+        .toDomainObject(getAdditionalInformation)
+        .orElseThrow(() => new NestedAdditionalInformationDTODeserializerNotFound(getAdditionalInformation))
     AdditionalInformationUpdated(domainAggregateId, domainEventId, additionalInformation)
   }
 }
 
 object AdditionalInformationUpdatedDTO {
   def fromDomainObject(additionalInformationConverter: AdditionalInformationConverter)(event: AdditionalInformationUpdated, typeName: String): AdditionalInformationUpdatedDTO = {
-    val additionalInformationDTO = additionalInformationConverter.toDTO(event.additionalInformation)
-        .orElseThrow()
+    val additionalInformationDTO = additionalInformationConverter
+        .toDTO(event.additionalInformation)
+        .orElseThrow(() => new NestedAdditionalInformationDTOSerializerNotFound(event.additionalInformation))
     AdditionalInformationUpdatedDTO(typeName, event.aggregateId.taskId.asString(), event.eventId.serialize(), additionalInformationDTO)
   }
 }


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


[james-project] 35/41: JAMES-2949 DefaultJamesUser is never used

Posted by bt...@apache.org.
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 36a9e5781b46cc4f2c1bd86eee06a17a8bfbde34
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Nov 18 14:23:29 2019 +0700

    JAMES-2949 DefaultJamesUser is never used
---
 .../james/user/lib/model/DefaultJamesUser.java     | 119 ---------------------
 1 file changed, 119 deletions(-)

diff --git a/server/data/data-library/src/main/java/org/apache/james/user/lib/model/DefaultJamesUser.java b/server/data/data-library/src/main/java/org/apache/james/user/lib/model/DefaultJamesUser.java
deleted file mode 100644
index ec6845f..0000000
--- a/server/data/data-library/src/main/java/org/apache/james/user/lib/model/DefaultJamesUser.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/****************************************************************
- * 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.user.lib.model;
-
-import org.apache.james.core.MailAddress;
-import org.apache.james.core.Username;
-import org.apache.james.user.api.model.JamesUser;
-
-/**
- * Implementation of User Interface.
- * 
- * @deprecated Use {@link DefaultUser}
- */
-@Deprecated
-public class DefaultJamesUser extends DefaultUser implements JamesUser {
-
-    private static final long serialVersionUID = 6323959976390389529L;
-
-    /**
-     * Whether forwarding is enabled for this user.
-     */
-    private boolean forwarding;
-
-    /**
-     * The mail address to which this user's email is forwarded.
-     */
-    private MailAddress forwardingDestination;
-
-    /**
-     * Is this user an alias for another username on the system.
-     */
-    private boolean aliasing;
-
-    /**
-     * The user name that this user name is aliasing.
-     */
-    private String alias;
-
-    public DefaultJamesUser(Username name, String alg) {
-        super(name, alg);
-        initialize();
-    }
-
-    public DefaultJamesUser(Username name, String passwordHash, String hashAlg) {
-        super(name, passwordHash, hashAlg);
-        initialize();
-    }
-
-    /**
-     * Initializes default values for local fields.
-     */
-    public void initialize() {
-        forwarding = false;
-        forwardingDestination = null;
-        aliasing = false;
-        alias = "";
-    }
-
-    @Override
-    public void setForwarding(boolean forward) {
-        forwarding = forward;
-    }
-
-    @Override
-    public boolean getForwarding() {
-        return forwarding;
-    }
-
-    @Override
-    public boolean setForwardingDestination(MailAddress address) {
-        /* TODO: Some verification would be good */
-        forwardingDestination = address;
-        return true;
-    }
-
-    @Override
-    public MailAddress getForwardingDestination() {
-        return forwardingDestination;
-    }
-
-    @Override
-    public void setAliasing(boolean alias) {
-        aliasing = alias;
-    }
-
-    @Override
-    public boolean getAliasing() {
-        return aliasing;
-    }
-
-    @Override
-    public boolean setAlias(String address) {
-        /* TODO: Some verification would be good */
-        alias = address;
-        return true;
-    }
-
-    @Override
-    public String getAlias() {
-        return alias;
-    }
-}


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


[james-project] 31/41: JAMES-2979 add test to ensure that dequeuing from the mailqueue should be done multiple elements at the same time

Posted by bt...@apache.org.
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 5e582a5eb829ed4b0571bd8e04d0ead48bf3294f
Author: Rémi KOWALSKI <rk...@linagora.com>
AuthorDate: Thu Nov 14 14:01:11 2019 +0100

    JAMES-2979 add test to ensure that dequeuing from the mailqueue should be done multiple elements at the same time
---
 .../queue/activemq/ActiveMQMailQueueBlobTest.java  |  4 +++
 .../queue/activemq/ActiveMQMailQueueTest.java      |  6 +++-
 .../apache/james/queue/api/MailQueueContract.java  | 35 +++++++++++++++++++++-
 .../apache/james/queue/jms/JMSMailQueueTest.java   |  6 +++-
 4 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueBlobTest.java b/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueBlobTest.java
index 1b021d0..b2c3cea 100644
--- a/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueBlobTest.java
+++ b/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueBlobTest.java
@@ -27,6 +27,7 @@ import java.io.InputStream;
 import java.time.temporal.ChronoUnit;
 
 import org.apache.activemq.ActiveMQConnectionFactory;
+import org.apache.activemq.ActiveMQPrefetchPolicy;
 import org.apache.activemq.broker.BrokerService;
 import org.apache.commons.io.FileUtils;
 import org.apache.james.filesystem.api.FileSystem;
@@ -65,6 +66,9 @@ public class ActiveMQMailQueueBlobTest implements DelayedManageableMailQueueCont
     public void setUp(BrokerService broker, MailQueueMetricExtension.MailQueueMetricTestSystem metricTestSystem) {
         fileSystem = new MyFileSystem();
         ActiveMQConnectionFactory connectionFactory = createConnectionFactory();
+        ActiveMQPrefetchPolicy prefetchPolicy = new ActiveMQPrefetchPolicy();
+        prefetchPolicy.setQueuePrefetch(0);
+        connectionFactory.setPrefetchPolicy(prefetchPolicy);
         FileSystemBlobTransferPolicy policy = new FileSystemBlobTransferPolicy();
         policy.setFileSystem(fileSystem);
         policy.setDefaultUploadUrl(BASE_DIR);
diff --git a/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueTest.java b/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueTest.java
index acfdbfb..609cef1 100644
--- a/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueTest.java
+++ b/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueTest.java
@@ -21,6 +21,7 @@ package org.apache.james.queue.activemq;
 import javax.jms.ConnectionFactory;
 
 import org.apache.activemq.ActiveMQConnectionFactory;
+import org.apache.activemq.ActiveMQPrefetchPolicy;
 import org.apache.activemq.broker.BrokerService;
 import org.apache.james.metrics.api.GaugeRegistry;
 import org.apache.james.metrics.api.MetricFactory;
@@ -51,7 +52,10 @@ public class ActiveMQMailQueueTest implements DelayedManageableMailQueueContract
 
     @BeforeEach
     public void setUp(BrokerService broker, MailQueueMetricExtension.MailQueueMetricTestSystem metricTestSystem) {
-        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?create=false");
+        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?create=false");
+        ActiveMQPrefetchPolicy prefetchPolicy = new ActiveMQPrefetchPolicy();
+        prefetchPolicy.setQueuePrefetch(0);
+        connectionFactory.setPrefetchPolicy(prefetchPolicy);
         RawMailQueueItemDecoratorFactory mailQueueItemDecoratorFactory = new RawMailQueueItemDecoratorFactory();
         MetricFactory metricFactory = metricTestSystem.getMetricFactory();
         GaugeRegistry gaugeRegistry = metricTestSystem.getSpyGaugeRegistry();
diff --git a/server/queue/queue-api/src/test/java/org/apache/james/queue/api/MailQueueContract.java b/server/queue/queue-api/src/test/java/org/apache/james/queue/api/MailQueueContract.java
index f1d57c8..cec9783 100644
--- a/server/queue/queue-api/src/test/java/org/apache/james/queue/api/MailQueueContract.java
+++ b/server/queue/queue-api/src/test/java/org/apache/james/queue/api/MailQueueContract.java
@@ -37,6 +37,7 @@ import java.util.concurrent.ConcurrentLinkedDeque;
 import java.util.concurrent.LinkedBlockingDeque;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.IntStream;
 import java.util.stream.Stream;
 
 import javax.mail.internet.MimeMessage;
@@ -49,12 +50,12 @@ import org.apache.mailet.Attribute;
 import org.apache.mailet.Mail;
 import org.apache.mailet.PerRecipientHeaders;
 import org.apache.mailet.base.test.FakeMail;
+import org.awaitility.Awaitility;
 import org.junit.jupiter.api.Test;
 
 import com.github.fge.lambdas.Throwing;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Strings;
-
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 import reactor.core.scheduler.Schedulers;
@@ -510,6 +511,38 @@ public interface MailQueueContract {
             .hasSize(totalDequeuedMessages);
     }
 
+    @Test
+    default void dequeueShouldBeConcurrent() {
+        MailQueue testee = getMailQueue();
+        int NB_MAILS = 1000;
+        IntStream.range(0, NB_MAILS)
+            .forEach(Throwing.intConsumer(i -> testee.enQueue(defaultMail()
+                .name("name" + i)
+                .build())));
+
+        ConcurrentLinkedDeque<Mail> dequeuedMails = new ConcurrentLinkedDeque<>();
+
+        Flux.from(testee.deQueue())
+            .flatMap(item -> Mono.defer(() -> {
+                    dequeuedMails.add(item.getMail());
+                    try {
+                        Thread.sleep(100);
+                        item.done(true);
+                        return Mono.empty();
+                    } catch (MailQueue.MailQueueException | InterruptedException e) {
+                        return Mono.error(e);
+                    }
+                }).subscribeOn(Schedulers.elastic()), 1000
+            )
+            .subscribeOn(Schedulers.newSingle("foo"))
+            .subscribe();
+
+        Awaitility.await()
+            .atMost(org.awaitility.Duration.ONE_MINUTE)
+            .until(() -> dequeuedMails.size() >= NB_MAILS);
+
+    }
+
     class SerializableAttribute implements Serializable {
         private final String value;
 
diff --git a/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSMailQueueTest.java b/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSMailQueueTest.java
index 8f92851..f436a1d 100644
--- a/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSMailQueueTest.java
+++ b/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSMailQueueTest.java
@@ -22,6 +22,7 @@ package org.apache.james.queue.jms;
 import javax.jms.ConnectionFactory;
 
 import org.apache.activemq.ActiveMQConnectionFactory;
+import org.apache.activemq.ActiveMQPrefetchPolicy;
 import org.apache.activemq.broker.BrokerService;
 import org.apache.james.metrics.api.GaugeRegistry;
 import org.apache.james.metrics.api.MetricFactory;
@@ -47,7 +48,10 @@ public class JMSMailQueueTest implements DelayedManageableMailQueueContract, Pri
 
     @BeforeEach
     void setUp(BrokerService broker, MailQueueMetricExtension.MailQueueMetricTestSystem metricTestSystem) {
-        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?create=false");
+        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?create=false");
+        ActiveMQPrefetchPolicy prefetchPolicy = new ActiveMQPrefetchPolicy();
+        prefetchPolicy.setQueuePrefetch(0);
+        connectionFactory.setPrefetchPolicy(prefetchPolicy);
         RawMailQueueItemDecoratorFactory mailQueueItemDecoratorFactory = new RawMailQueueItemDecoratorFactory();
         MetricFactory metricFactory = metricTestSystem.getMetricFactory();
         GaugeRegistry gaugeRegistry = metricTestSystem.getSpyGaugeRegistry();


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


[james-project] 36/41: JAMES-2949 User::hasUsername is never used

Posted by bt...@apache.org.
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 0226e13ff1c1162b928857bfe8fadbaa81b267e3
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Nov 18 14:27:59 2019 +0700

    JAMES-2949 User::hasUsername is never used
---
 .../src/main/java/org/apache/james/user/api/model/User.java        | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/server/data/data-api/src/main/java/org/apache/james/user/api/model/User.java b/server/data/data-api/src/main/java/org/apache/james/user/api/model/User.java
index c614ba0..191bfe8 100644
--- a/server/data/data-api/src/main/java/org/apache/james/user/api/model/User.java
+++ b/server/data/data-api/src/main/java/org/apache/james/user/api/model/User.java
@@ -51,11 +51,4 @@ public interface User {
      * @return true if newPass successfully added
      */
     boolean setPassword(String newPass);
-
-    default boolean hasUsername(Username username) {
-        Username thisUsername = getUserName();
-        Username thatUsername = username;
-
-        return thisUsername.equals(thatUsername);
-    }
 }


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


[james-project] 20/41: JAMES-2813 Split JsonGenericSerializer between conversion and serialization

Posted by bt...@apache.org.
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 27f2845344e1a97c63215d512aa3e17110f3083b
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Mon Oct 21 10:14:42 2019 +0200

    JAMES-2813 Split JsonGenericSerializer between conversion and serialization
---
 .../eventstore/cassandra/JsonEventSerializer.java  |   3 +-
 .../java/org/apache/james/json/DTOConverter.java   |  65 ++++++++++++
 .../apache/james/json/JsonGenericSerializer.java   |  60 +++--------
 .../src/test/java/org/apache/DTOConverterTest.java | 115 +++++++++++++++++++++
 .../JsonTaskAdditionalInformationSerializer.java   |   3 +-
 .../james/server/task/json/JsonTaskSerializer.java |   3 +-
 6 files changed, 202 insertions(+), 47 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 52b0d3a..0bc17a1 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
@@ -50,7 +50,8 @@ public class JsonEventSerializer {
 
     @Inject
     public JsonEventSerializer(Set<EventDTOModule<?, ?>> modules) {
-        jsonGenericSerializer = new JsonGenericSerializer(modules);
+        //FIXME
+        jsonGenericSerializer = new JsonGenericSerializer(modules, null);
     }
     
     public JsonEventSerializer(EventDTOModule<?, ?>... modules) {
diff --git a/json/src/main/java/org/apache/james/json/DTOConverter.java b/json/src/main/java/org/apache/james/json/DTOConverter.java
new file mode 100644
index 0000000..1fe27f3
--- /dev/null
+++ b/json/src/main/java/org/apache/james/json/DTOConverter.java
@@ -0,0 +1,65 @@
+/****************************************************************
+ * 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.json;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+
+import com.github.steveash.guavate.Guavate;
+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;
+
+    @SafeVarargs
+    public static <T, U extends DTO> DTOConverter<T, U> of(DTOModule<T, U>... modules) {
+        return new DTOConverter<>(ImmutableSet.copyOf(modules));
+    }
+
+    public DTOConverter(Set<DTOModule<T, U>> modules) {
+        typeToModule = modules.stream()
+            .collect(Guavate.toImmutableMap(
+                DTOModule::getDomainObjectType,
+                Function.identity()));
+
+        domainClassToModule = modules.stream()
+            .collect(Guavate.toImmutableMap(
+                DTOModule::getDomainObjectClass,
+                Function.identity()));
+    }
+
+    public Optional<U> convert(T domainObject) {
+        return Optional
+            .ofNullable(domainClassToModule.get(domainObject.getClass()))
+            .map(module -> module.toDTO(domainObject));
+    }
+
+    public Optional<T> convert(U dto) {
+        String type = dto.getType();
+        return Optional
+            .ofNullable(typeToModule.get(type))
+            .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 a1ed925..ceb3066 100644
--- a/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
+++ b/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
@@ -20,10 +20,7 @@
 package org.apache.james.json;
 
 import java.io.IOException;
-import java.util.Map;
-import java.util.Optional;
 import java.util.Set;
-import java.util.function.Function;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -37,40 +34,10 @@ import com.fasterxml.jackson.databind.jsontype.NamedType;
 import com.fasterxml.jackson.datatype.guava.GuavaModule;
 import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
-import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableSet;
 
 public class JsonGenericSerializer<T, U extends DTO> {
 
-    private static class DTOConverter<T, U extends DTO> {
-
-        private final Map<String, DTOModule<T, U>> typeToModule;
-        private final Map<Class<? extends T>, DTOModule<T, U>> domainClassToModule;
-
-        public DTOConverter(Set<DTOModule<T, U>> modules) {
-            typeToModule = modules.stream()
-                .collect(Guavate.toImmutableMap(
-                    DTOModule::getDomainObjectType,
-                    Function.identity()));
-
-            domainClassToModule = modules.stream()
-                .collect(Guavate.toImmutableMap(
-                    DTOModule::getDomainObjectClass,
-                    Function.identity()));
-        }
-
-        public Optional<U> convert(T domainObject) {
-            return Optional.ofNullable(domainClassToModule.get(domainObject.getClass()))
-                .map(module -> module.toDTO(domainObject));
-        }
-
-        public Optional<T> convert(U dto) {
-            String type = dto.getType();
-            return Optional.ofNullable(typeToModule.get(type))
-                .map(module -> module.getToDomainObjectConverter().convert(dto));
-        }
-    }
-
     public static class InvalidTypeException extends RuntimeException {
         public InvalidTypeException(String message) {
             super(message);
@@ -92,21 +59,26 @@ 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));
+        return new JsonGenericSerializer<>(ImmutableSet.copyOf(modules), DTOConverter.of(modules));
+    }
+
+    public JsonGenericSerializer(Set<DTOModule<T, U>> modules, DTOConverter<T, U> converter) {
+        this.dtoConverter = converter;
+        this.objectMapper = buildObjectMapper(modules);
     }
 
-    public JsonGenericSerializer(Set<DTOModule<T, U>> modules) {
-        objectMapper = new ObjectMapper();
-        objectMapper.registerModule(new Jdk8Module());
-        objectMapper.registerModule(new JavaTimeModule());
-        objectMapper.registerModule(new GuavaModule());
-        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
-        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
-        objectMapper.enable(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY);
+    private ObjectMapper buildObjectMapper(Set<DTOModule<T, U>> modules) {
+        ObjectMapper objectMapper = new ObjectMapper()
+            .registerModule(new Jdk8Module())
+            .registerModule(new JavaTimeModule())
+            .registerModule(new GuavaModule())
+            .setSerializationInclusion(JsonInclude.Include.NON_ABSENT)
+            .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
+            .enable(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY);
         modules.stream()
             .map(module -> new NamedType(module.getDTOClass(), module.getDomainObjectType()))
             .forEach(objectMapper::registerSubtypes);
-        dtoConverter = new DTOConverter<>(modules);
+        return objectMapper;
     }
 
     public String serialize(T domainObject) throws JsonProcessingException {
@@ -122,7 +94,7 @@ public class JsonGenericSerializer<T, U extends DTO> {
             .orElseThrow(() -> new UnknownTypeException("unknown type " + dto.getType()));
     }
 
-    public U jsonToDTO(String value) throws IOException {
+    private U jsonToDTO(String value) throws IOException {
         try {
             JsonNode jsonTree = detectDuplicateProperty(value);
             return parseAsPolymorphicDTO(jsonTree);
diff --git a/json/src/test/java/org/apache/DTOConverterTest.java b/json/src/test/java/org/apache/DTOConverterTest.java
new file mode 100644
index 0000000..3987dbd
--- /dev/null
+++ b/json/src/test/java/org/apache/DTOConverterTest.java
@@ -0,0 +1,115 @@
+/****************************************************************
+ * 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;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.time.ZonedDateTime;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.stream.Stream;
+
+import org.apache.dto.BaseType;
+import org.apache.dto.FirstDTO;
+import org.apache.dto.FirstDomainObject;
+import org.apache.dto.SecondDTO;
+import org.apache.dto.SecondDomainObject;
+import org.apache.dto.TestModules;
+import org.apache.james.json.DTO;
+import org.apache.james.json.DTOConverter;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+class DTOConverterTest {
+    private static final FirstDomainObject FIRST = new FirstDomainObject(Optional.of(1L), ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"), "first payload");
+    private static final FirstDTO FIRST_DTO = new FirstDTO("first", Optional.of(1L), "2016-04-03T02:01+07:00[Asia/Vientiane]", "first payload");
+    private static final SecondDomainObject SECOND = new SecondDomainObject(UUID.fromString("4a2c853f-7ffc-4ce3-9410-a47e85b3b741"), "second payload");
+    private static final SecondDTO SECOND_DTO = new SecondDTO("second", "4a2c853f-7ffc-4ce3-9410-a47e85b3b741", "second payload");
+
+    @SuppressWarnings("unchecked")
+    @Test
+    void shouldConvertFromKnownDTO() throws Exception {
+        assertThat(DTOConverter.of(TestModules.FIRST_TYPE)
+            .convert(FIRST_DTO))
+            .contains(FIRST);
+    }
+
+    @Test
+    void shouldReturnEmptyWhenConvertingFromUnknownDTO() {
+        assertThat(DTOConverter.of()
+            .convert(FIRST_DTO))
+            .isEmpty();
+    }
+
+    @ParameterizedTest
+    @MethodSource
+    void convertFromDomainObjectShouldHandleAllKnownTypes(BaseType domainObject, DTO dto) throws Exception {
+        @SuppressWarnings("unchecked")
+        DTOConverter<BaseType, DTO> serializer = DTOConverter.of(
+                TestModules.FIRST_TYPE,
+                TestModules.SECOND_TYPE);
+
+        assertThat(serializer.convert(domainObject))
+            .hasValueSatisfying(result -> assertThat(result).isInstanceOf(dto.getClass()).isEqualToComparingFieldByField(dto));
+    }
+
+    private static Stream<Arguments> convertFromDomainObjectShouldHandleAllKnownTypes() {
+        return allKnownTypes();
+    }
+
+    @ParameterizedTest
+    @MethodSource
+    void convertFromDTOShouldHandleAllKnownTypes(BaseType domainObject, DTO dto) throws Exception {
+        @SuppressWarnings("unchecked")
+        DTOConverter<BaseType, DTO> serializer = DTOConverter.of(
+                TestModules.FIRST_TYPE,
+                TestModules.SECOND_TYPE);
+
+        assertThat(serializer.convert(dto))
+            .hasValueSatisfying(result -> assertThat(result).isInstanceOf(domainObject.getClass()).isEqualToComparingFieldByField(domainObject));
+    }
+
+    private static Stream<Arguments> convertFromDTOShouldHandleAllKnownTypes() {
+        return allKnownTypes();
+    }
+
+    private static Stream<Arguments> allKnownTypes() {
+        return Stream.of(
+                Arguments.of(SECOND, SECOND_DTO),
+                Arguments.of(FIRST, FIRST_DTO)
+        );
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    void shouldConvertFromKnownDomainObject() throws Exception {
+        assertThat(DTOConverter.of(TestModules.FIRST_TYPE)
+            .convert(FIRST))
+            .hasValueSatisfying(result -> assertThat(result).isInstanceOf(FirstDTO.class).isEqualToComparingFieldByField(FIRST_DTO));
+    }
+
+    @Test
+    void shouldReturnEmptyWhenConvertUnknownDomainObject() {
+        assertThat(DTOConverter.of().convert(FIRST))
+            .isEmpty();
+    }
+}
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 751cc17..5d0cc48 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
@@ -49,7 +49,8 @@ public class JsonTaskAdditionalInformationSerializer {
 
     @Inject
     public JsonTaskAdditionalInformationSerializer(Set<AdditionalInformationDTOModule<?, ?>> modules) {
-        jsonGenericSerializer = new JsonGenericSerializer(modules);
+        //FIXME
+        jsonGenericSerializer = new JsonGenericSerializer(modules, null);
     }
 
     public JsonTaskAdditionalInformationSerializer(@SuppressWarnings("rawtypes") AdditionalInformationDTOModule... modules) {
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 9ecd7c4..90ebe54 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
@@ -50,7 +50,8 @@ public class JsonTaskSerializer {
 
     @Inject
     public JsonTaskSerializer(Set<TaskDTOModule<?, ?>> modules) {
-        jsonGenericSerializer = new JsonGenericSerializer(modules);
+        //FIXME
+        jsonGenericSerializer = new JsonGenericSerializer(modules, null);
     }
 
     public JsonTaskSerializer(@SuppressWarnings("rawtypes") TaskDTOModule... modules) {


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


[james-project] 28/41: JAMES-2813 extract EventNestedTypes string to a constant

Posted by bt...@apache.org.
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 22b3b482b6c6a4f3a7e4c9e02daea45e54f46e45
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Tue Nov 5 17:20:31 2019 +0100

    JAMES-2813 extract EventNestedTypes string to a constant
---
 .../james/eventsourcing/eventstore/cassandra/JsonEventSerializer.java | 4 +++-
 .../main/java/org/apache/james/modules/TaskSerializationModule.java   | 4 +++-
 2 files changed, 6 insertions(+), 2 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 9c3b447..b1bb6bc 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
@@ -39,6 +39,8 @@ import com.google.common.collect.ImmutableSet;
 
 public class JsonEventSerializer {
 
+    public static final String EVENT_NESTED_TYPES_INJECTION_NAME = "EventNestedTypes";
+
     public static RequireNestedConfiguration forModules(Set<? extends EventDTOModule<?, ?>> modules) {
         return nestedTypesModules -> {
             ImmutableSet<EventDTOModule<?, ?>> dtoModules = ImmutableSet.copyOf(modules);
@@ -82,7 +84,7 @@ public class JsonEventSerializer {
     private JsonGenericSerializer<Event, EventDTO> jsonGenericSerializer;
 
     @Inject
-    private JsonEventSerializer(Set<EventDTOModule<?, ?>> modules, @Named("EventNestedTypes") Set<DTOModule<?, ?>> nestedTypesModules) {
+    private JsonEventSerializer(Set<EventDTOModule<?, ?>> modules, @Named(EVENT_NESTED_TYPES_INJECTION_NAME) Set<DTOModule<?, ?>> nestedTypesModules) {
         jsonGenericSerializer = JsonGenericSerializer.forModules(modules).withNestedTypeModules(nestedTypesModules);
     }
     
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 f901b57..a30fe93 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
@@ -18,6 +18,8 @@
  ****************************************************************/
 package org.apache.james.modules;
 
+import static org.apache.james.eventsourcing.eventstore.cassandra.JsonEventSerializer.EVENT_NESTED_TYPES_INJECTION_NAME;
+
 import java.time.Clock;
 import java.util.Set;
 
@@ -345,7 +347,7 @@ public class TaskSerializationModule extends AbstractModule {
         return UserReindexingTaskAdditionalInformationDTO.serializationModule(mailboxIdFactory);
     }
 
-    @Named("EventNestedTypes")
+    @Named(EVENT_NESTED_TYPES_INJECTION_NAME)
     @Provides
     public Set<DTOModule<?, ?>> eventNestedTypes(Set<AdditionalInformationDTOModule<?, ?>> additionalInformationDTOModules,
                                             Set<TaskDTOModule<?, ?>> taskDTOModules) {


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


[james-project] 06/41: Changelog entry for Cassandra authentication + SSL

Posted by bt...@apache.org.
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 8e1e4e22b22993daeb89a5a28b5581d326701c33
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Nov 8 10:21:29 2019 +0700

    Changelog entry for Cassandra authentication + SSL
---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0a5ad25..94c2b87 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 - Distributed task management for Guice cassandra-rabbitmq product. This enables two James servers to share a consistent view
 of tasks being currently executed.
 - JAMES-2563 Health check for ElasticSearch
+- JAMES-2904 Authentication and SSL support for Cassandra backend
 
 ### Changed
 - Multiple changes have been made to enhance ElasticSearch performance:


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


[james-project] 12/41: JAMES-2981 update ugrade instructions

Posted by bt...@apache.org.
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 4debed29f3c0536e1e4b1e5ba4e06a7ee2b8c0de
Author: Rémi KOWALSKI <rk...@linagora.com>
AuthorDate: Fri Nov 15 15:52:37 2019 +0100

    JAMES-2981 update ugrade instructions
---
 upgrade-instructions.md | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/upgrade-instructions.md b/upgrade-instructions.md
index f4f9b5a..f1b0ab3 100644
--- a/upgrade-instructions.md
+++ b/upgrade-instructions.md
@@ -19,6 +19,19 @@ Change list:
  - [UsersFileRepository](#usersfilerepository)
  - [ElasticSearch performance enhancements](#elasticsearch-performance-enhancements)
  - [JAMES-2703 Post 3.4.0 release removals](#james-2703-post-340-release-removals)
+ - [Cassandra keyspace creation configuration](#cassandra-keyspace-creation-configuration)
+
+#### Cassandra keyspace creation configuration
+
+Date 15/11/2019
+
+SHA-1 bcf4d36500
+
+In order to allow the usage of cassandra credentials limited to a keyspace, the default behaviour of James is now to NOT
+create the keyspace during start-up.
+
+The automatic creation of the cassandra keyspace by James could be enabled by setting
+ `cassandra.keyspace.create=true` in the `cassandra.properties` configuration file.
  
 #### UsersFileRepository
 


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


[james-project] 26/41: JAMES-2813 forbid duplicate typeid for DTO

Posted by bt...@apache.org.
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 d8a83b0d0fd4da05cc1fed67a844a503c60020c3
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Wed Oct 23 18:05:25 2019 +0200

    JAMES-2813 forbid duplicate typeid for DTO
---
 .../main/java/org/apache/james/json/JsonGenericSerializer.java | 10 ++++++++++
 json/src/test/java/org/apache/JsonGenericSerializerTest.java   |  8 ++++++++
 2 files changed, 18 insertions(+)

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 bc2c156..0cf11dc 100644
--- a/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
+++ b/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
@@ -23,6 +23,7 @@ import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -37,6 +38,7 @@ import com.fasterxml.jackson.datatype.guava.GuavaModule;
 import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
 import com.github.steveash.guavate.Guavate;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 
@@ -90,10 +92,18 @@ public class JsonGenericSerializer<T, U extends DTO> {
     private final DTOConverter<T, U> dtoConverter;
 
     private JsonGenericSerializer(Set<? extends DTOModule<? extends T, ? extends U>> modules, Set<? extends DTOModule<?, ?>> nestedTypesModules, DTOConverter<T, U> converter) {
+        Preconditions.checkArgument(!hasDuplicateTypeIds(modules, nestedTypesModules));
         this.dtoConverter = converter;
         this.objectMapper = buildObjectMapper(Sets.union(modules, nestedTypesModules));
     }
 
+    private boolean hasDuplicateTypeIds(Set<? extends DTOModule<?, ?>> modules, Set<? extends DTOModule<?, ?>> nestedTypesModules) {
+        return Sets.intersection(
+                modules.stream().map(DTOModule::getDomainObjectType).collect(Collectors.toSet()),
+                nestedTypesModules.stream().map(DTOModule::getDomainObjectType).collect(Collectors.toSet()))
+            .size() > 0;
+    }
+
     private ObjectMapper buildObjectMapper(Set<? extends DTOModule<?, ?>> modules) {
         ObjectMapper objectMapper = new ObjectMapper()
             .registerModule(new Jdk8Module())
diff --git a/json/src/test/java/org/apache/JsonGenericSerializerTest.java b/json/src/test/java/org/apache/JsonGenericSerializerTest.java
index d9bcde1..235d19d 100644
--- a/json/src/test/java/org/apache/JsonGenericSerializerTest.java
+++ b/json/src/test/java/org/apache/JsonGenericSerializerTest.java
@@ -158,4 +158,12 @@ class JsonGenericSerializerTest {
             .isInstanceOf(JsonGenericSerializer.UnknownTypeException.class);
     }
 
+    @Test
+    void shouldThrowWhenRegisteringDuplicateTypeIds() {
+        assertThatThrownBy(() -> JsonGenericSerializer
+            .forModules(TestModules.FIRST_NESTED)
+            .withNestedTypeModules(TestModules.FIRST_NESTED))
+            .isInstanceOf(IllegalArgumentException.class);
+    }
+
 }


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


[james-project] 22/41: JAMES-2813 handle nested AdditionInformation

Posted by bt...@apache.org.
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 <ma...@apache.org>
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: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 23/41: JAMES-2813 use a staged builder to create serializers

Posted by bt...@apache.org.
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 805ebca371822761a93b8f28202b05d028fd5dfd
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Tue Oct 22 17:05:46 2019 +0200

    JAMES-2813 use a staged builder to create serializers
---
 .../migration/MigrationTaskSerializationTest.java  |  4 +-
 .../eventstore/cassandra/JsonEventSerializer.java  | 40 +++++++++++---
 .../CassandraEventSourcingSystemTest.java          |  2 +-
 .../cassandra/CassandraEventStoreExtension.java    | 20 +++----
 .../cassandra/CassandraEventStoreTest.java         |  2 +-
 .../cassandra/JsonEventSerializerTest.java         | 33 ++++++------
 .../apache/james/json/JsonGenericSerializer.java   | 43 ++++++++++++---
 .../src/test/java/org/apache/DTOConverterTest.java | 13 ++---
 .../java/org/apache/JsonGenericSerializerTest.java | 61 +++++++++++-----------
 json/src/test/java/org/apache/dto/TestModules.java | 16 +++---
 ...ailboxPathV2MigrationTaskSerializationTest.java | 19 +++----
 .../mail/task/MailboxMergingTaskTest.java          |  6 +--
 ...aultGarbageCollectionTaskSerializationTest.java | 10 ++--
 .../james/mailbox/quota/cassandra/dto/DTOTest.java | 16 +++---
 ...sandraQuotaMailingListenersIntegrationTest.java |  4 +-
 ...rorRecoveryIndexationTaskSerializationTest.java |  5 +-
 .../FullReindexingTaskSerializationTest.java       |  4 +-
 .../MessageIdReindexingTaskSerializationTest.java  |  4 +-
 ...ngleMailboxReindexingTaskSerializationTest.java |  4 +-
 ...ngleMessageReindexingTaskSerializationTest.java |  4 +-
 .../UserReindexingTaskSerializationTest.java       |  4 +-
 ...ventSourcingDLPConfigurationStoreExtension.java |  8 ++-
 ...pingsSourcesMigrationTaskSerializationTest.java |  6 +--
 ...sandraEventSourcingFilteringManagementTest.java |  4 +-
 ...sandraMappingsSolveInconsistenciesTaskTest.java |  6 +--
 ...edMessagesVaultDeleteTaskSerializationTest.java |  4 +-
 ...edMessagesVaultExportTaskSerializationTest.java |  4 +-
 ...dMessagesVaultRestoreTaskSerializationTest.java |  4 +-
 .../WebadminApiQuerySerializationContractTest.java |  2 +-
 .../service/EventDeadLettersRedeliverTaskTest.java |  4 +-
 .../webadmin/service/ClearMailQueueTaskTest.java   |  8 +--
 .../service/DeleteMailsFromMailQueueTaskTest.java  | 10 ++--
 .../service/ClearMailRepositoryTaskTest.java       |  8 +--
 .../service/ReprocessingAllMailsTaskTest.java      |  8 +--
 .../service/ReprocessingOneMailTaskTest.java       |  8 +--
 .../CassandraMailQueueViewTestFactory.java         |  4 +-
 .../EventsourcingConfigurationManagementTest.java  |  6 ++-
 ...andraTaskExecutionDetailsProjectionDAOTest.java |  2 +-
 ...assandraTaskExecutionDetailsProjectionTest.java |  5 +-
 .../distributed/DistributedTaskManagerTest.java    | 15 +++---
 .../RabbitMQTerminationSubscriberTest.java         |  5 +-
 .../distributed/RabbitMQWorkQueueTest.java         |  4 +-
 .../distributed/TaskEventsSerializationTest.java   |  9 ++--
 .../JsonTaskAdditionalInformationSerializer.java   | 13 +++--
 .../james/server/task/json/JsonTaskSerializer.java | 13 +++--
 .../server/task/json/TaskDeserializerTest.java     |  2 +-
 .../server/task/json/TaskSerializationTest.java    |  8 +--
 .../james/server/task/json/TaskSerializerTest.java |  2 +-
 48 files changed, 262 insertions(+), 224 deletions(-)

diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/migration/MigrationTaskSerializationTest.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/migration/MigrationTaskSerializationTest.java
index c56e378..7dd5686 100644
--- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/migration/MigrationTaskSerializationTest.java
+++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/migration/MigrationTaskSerializationTest.java
@@ -43,8 +43,8 @@ class MigrationTaskSerializationTest {
     private final CassandraSchemaVersionDAO cassandraSchemaVersionDAO = mock(CassandraSchemaVersionDAO.class);
     private final CassandraSchemaTransitions transitions = mock(CassandraSchemaTransitions.class);
     private final MigrationTask.Factory factory = target -> new MigrationTask(cassandraSchemaVersionDAO, transitions, target);
-    private final JsonTaskSerializer taskSerializer = new JsonTaskSerializer(MigrationTaskDTO.module(factory));
-    private JsonTaskAdditionalInformationSerializer jsonAdditionalInformationSerializer = new JsonTaskAdditionalInformationSerializer(MigrationTaskAdditionalInformationDTO.serializationModule());
+    private final JsonTaskSerializer taskSerializer = JsonTaskSerializer.of(MigrationTaskDTO.module(factory));
+    private JsonTaskAdditionalInformationSerializer jsonAdditionalInformationSerializer = JsonTaskAdditionalInformationSerializer.of(MigrationTaskAdditionalInformationDTO.serializationModule());
 
     @Test
     void taskShouldBeSerializable() throws JsonProcessingException {
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 15f8005..3acdd58 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
@@ -20,6 +20,8 @@
 package org.apache.james.eventsourcing.eventstore.cassandra;
 
 import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Set;
 
 import javax.inject.Inject;
@@ -27,15 +29,43 @@ 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;
+import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableSet;
 
 public class JsonEventSerializer {
 
+    public static RequireNestedConfiguration forModules(Set<? extends EventDTOModule<?, ?>> modules) {
+        return nestedTypesModules -> {
+            ImmutableSet<EventDTOModule<?, ?>> dtoModules = ImmutableSet.copyOf(modules);
+            return new JsonEventSerializer(dtoModules, ImmutableSet.copyOf(nestedTypesModules));
+        };
+    }
+
+    @SafeVarargs
+    public static RequireNestedConfiguration forModules(EventDTOModule<?, ?>... modules) {
+        return forModules(ImmutableSet.copyOf(modules));
+    }
+
+    public interface RequireNestedConfiguration {
+        JsonEventSerializer withNestedTypeModules(Set<DTOModule<?, ?>> modules);
+
+        default JsonEventSerializer withNestedTypeModules(DTOModule<?, ?>... modules) {
+            return withNestedTypeModules(ImmutableSet.copyOf(modules));
+        }
+
+        default JsonEventSerializer withNestedTypeModules(Set<DTOModule<?, ?>>... modules) {
+            return withNestedTypeModules(Arrays.stream(modules).flatMap(Collection::stream).collect(Guavate.toImmutableSet()));
+        }
+
+        default JsonEventSerializer withoutNestedType() {
+            return withNestedTypeModules(ImmutableSet.of());
+        }
+    }
+
     public static class InvalidEventException extends RuntimeException {
         public InvalidEventException(JsonGenericSerializer.InvalidTypeException original) {
             super(original);
@@ -51,14 +81,10 @@ public class JsonEventSerializer {
     private JsonGenericSerializer<Event, EventDTO> jsonGenericSerializer;
 
     @Inject
-    public JsonEventSerializer(DTOConverter<Event, EventDTO> converter, Set<EventDTOModule<?, ?>> modules, Set<DTOModule<?, ?>> nestedTypesModules) {
-        jsonGenericSerializer = new JsonGenericSerializer<>(modules, nestedTypesModules, converter);
+    private JsonEventSerializer(Set<EventDTOModule<?, ?>> modules, Set<DTOModule<?, ?>> nestedTypesModules) {
+        jsonGenericSerializer = JsonGenericSerializer.forModules(modules).withNestedTypeModules(nestedTypesModules);
     }
     
-    public JsonEventSerializer(EventDTOModule<?, ?>... modules) {
-        this(new DTOConverter<>(ImmutableSet.copyOf(modules)), ImmutableSet.copyOf(modules), ImmutableSet.of());
-    }
-
     public String serialize(Event event) throws JsonProcessingException {
         try {
             return jsonGenericSerializer.serialize(event);
diff --git a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventSourcingSystemTest.java b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventSourcingSystemTest.java
index 92c5401..6858b2d 100644
--- a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventSourcingSystemTest.java
+++ b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventSourcingSystemTest.java
@@ -25,5 +25,5 @@ import org.junit.jupiter.api.extension.RegisterExtension;
 
 public class CassandraEventSourcingSystemTest implements EventSourcingSystemTest {
     @RegisterExtension
-    static CassandraEventStoreExtension eventStoreExtension = new CassandraEventStoreExtension(TestEventDTOModules.TEST_TYPE);
+    static CassandraEventStoreExtension eventStoreExtension = new CassandraEventStoreExtension(JsonEventSerializer.forModules(TestEventDTOModules.TEST_TYPE).withoutNestedType());
 }
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 bed4553..d338495 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,8 @@
 
 package org.apache.james.eventsourcing.eventstore.cassandra;
 
-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;
@@ -34,21 +30,19 @@ import org.junit.jupiter.api.extension.ParameterContext;
 import org.junit.jupiter.api.extension.ParameterResolutionException;
 import org.junit.jupiter.api.extension.ParameterResolver;
 
-import com.google.common.collect.ImmutableSet;
-
 public class CassandraEventStoreExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback, ParameterResolver {
 
-    private final Set<EventDTOModule<?, ?>> modules;
     private CassandraClusterExtension cassandra;
+    private final JsonEventSerializer eventSerializer;
     private EventStoreDao eventStoreDao;
 
-    public CassandraEventStoreExtension(@SuppressWarnings("rawtypes") EventDTOModule... modules) {
-        this(new CassandraClusterExtension(CassandraEventStoreModule.MODULE), ImmutableSet.copyOf(modules));
+    public CassandraEventStoreExtension(JsonEventSerializer eventSerializer) {
+        this(new CassandraClusterExtension(CassandraEventStoreModule.MODULE), eventSerializer);
     }
 
-    public CassandraEventStoreExtension(CassandraClusterExtension cassandra, Set<EventDTOModule<?, ?>> module) {
+    public CassandraEventStoreExtension(CassandraClusterExtension cassandra, JsonEventSerializer eventSerializer) {
         this.cassandra = cassandra;
-        this.modules = module;
+        this.eventSerializer = eventSerializer;
     }
 
     @Override
@@ -63,9 +57,7 @@ public class CassandraEventStoreExtension implements BeforeAllCallback, AfterAll
 
     @Override
     public void beforeEach(ExtensionContext context) {
-        JsonEventSerializer jsonEventSerializer = new JsonEventSerializer(modules.toArray(new EventDTOModule[0]));
-
-        eventStoreDao = new EventStoreDao(cassandra.getCassandraCluster().getConf(), jsonEventSerializer);
+        eventStoreDao = new EventStoreDao(cassandra.getCassandraCluster().getConf(), eventSerializer);
     }
 
     @Override
diff --git a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreTest.java b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreTest.java
index f40eac1..562bd9b 100644
--- a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreTest.java
+++ b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreTest.java
@@ -25,5 +25,5 @@ import org.junit.jupiter.api.extension.RegisterExtension;
 
 class CassandraEventStoreTest implements EventStoreTest {
     @RegisterExtension
-    static CassandraEventStoreExtension eventStoreExtension = new CassandraEventStoreExtension(TestEventDTOModules.TEST_TYPE);
+    static CassandraEventStoreExtension eventStoreExtension = new CassandraEventStoreExtension(JsonEventSerializer.forModules(TestEventDTOModules.TEST_TYPE).withoutNestedType());
 }
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 043532a..d0d6c65 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,7 +28,6 @@ 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 {
@@ -45,23 +44,23 @@ class JsonEventSerializerTest {
 
     @Test
     void shouldDeserializeKnownEvent() throws Exception {
-        assertThat(new JsonEventSerializer(TestEventDTOModules.TEST_TYPE)
+        assertThat(JsonEventSerializer.forModules(TestEventDTOModules.TEST_TYPE).withoutNestedType()
             .deserialize(TEST_EVENT_JSON))
             .isEqualTo(TEST_EVENT);
     }
 
     @Test
     void shouldThrowWhenDeserializeUnknownEvent() {
-        assertThatThrownBy(() -> new JsonEventSerializer()
+        assertThatThrownBy(() -> JsonEventSerializer.forModules().withoutNestedType()
             .deserialize(TEST_EVENT_JSON))
             .isInstanceOf(JsonEventSerializer.UnknownEventException.class);
     }
 
     @Test
     void serializeShouldHandleAllKnownEvents() throws Exception {
-        JsonEventSerializer jsonEventSerializer = new JsonEventSerializer(
-            TestEventDTOModules.TEST_TYPE,
-            TestEventDTOModules.OTHER_TEST_TYPE);
+        JsonEventSerializer jsonEventSerializer = JsonEventSerializer
+            .forModules(TestEventDTOModules.TEST_TYPE, TestEventDTOModules.OTHER_TEST_TYPE)
+            .withoutNestedType();
 
         assertThatJson(
             jsonEventSerializer.serialize(OTHER_EVENT))
@@ -74,9 +73,9 @@ class JsonEventSerializerTest {
 
     @Test
     void deserializeShouldHandleAllKnownEvents() throws Exception {
-        JsonEventSerializer jsonEventSerializer = new JsonEventSerializer(
-            TestEventDTOModules.TEST_TYPE,
-            TestEventDTOModules.OTHER_TEST_TYPE);
+        JsonEventSerializer jsonEventSerializer = JsonEventSerializer
+            .forModules(TestEventDTOModules.TEST_TYPE, TestEventDTOModules.OTHER_TEST_TYPE)
+            .withoutNestedType();
 
         assertThatJson(
             jsonEventSerializer.deserialize(OTHER_EVENT_JSON))
@@ -90,32 +89,32 @@ class JsonEventSerializerTest {
 
     @Test
     void deserializeShouldThrowWhenEventWithDuplicatedTypes() {
-        assertThatThrownBy(() -> new JsonEventSerializer(
-                TestEventDTOModules.TEST_TYPE,
-                TestEventDTOModules.OTHER_TEST_TYPE)
+        assertThatThrownBy(() -> JsonEventSerializer
+            .forModules(TestEventDTOModules.TEST_TYPE, TestEventDTOModules.OTHER_TEST_TYPE)
+            .withoutNestedType()
             .deserialize(DUPLICATE_TYPE_EVENT_JSON))
             .isInstanceOf(JsonEventSerializer.InvalidEventException.class);
     }
 
     @Test
     void deserializeShouldThrowWhenEventWithMissingType() {
-        assertThatThrownBy(() -> new JsonEventSerializer(
-                TestEventDTOModules.TEST_TYPE,
-                TestEventDTOModules.OTHER_TEST_TYPE)
+        assertThatThrownBy(() -> JsonEventSerializer
+            .forModules(TestEventDTOModules.TEST_TYPE, TestEventDTOModules.OTHER_TEST_TYPE)
+            .withoutNestedType()
             .deserialize(MISSING_TYPE_EVENT_JSON))
             .isInstanceOf(JsonEventSerializer.InvalidEventException.class);
     }
 
     @Test
     void shouldSerializeKnownEvent() throws Exception {
-        assertThatJson(new JsonEventSerializer(TestEventDTOModules.TEST_TYPE)
+        assertThatJson(JsonEventSerializer.forModules(TestEventDTOModules.TEST_TYPE).withoutNestedType()
             .serialize(TEST_EVENT))
             .isEqualTo(TEST_EVENT_JSON);
     }
 
     @Test
     void shouldThrowWhenSerializeUnknownEvent() {
-        assertThatThrownBy(() -> new JsonEventSerializer()
+        assertThatThrownBy(() -> JsonEventSerializer.forModules().withoutNestedType()
             .serialize(TEST_EVENT))
             .isInstanceOf(JsonEventSerializer.UnknownEventException.class);
     }
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 a9cfdcc..bc2c156 100644
--- a/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
+++ b/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
@@ -20,6 +20,8 @@
 package org.apache.james.json;
 
 import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Set;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
@@ -34,11 +36,40 @@ import com.fasterxml.jackson.databind.jsontype.NamedType;
 import com.fasterxml.jackson.datatype.guava.GuavaModule;
 import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 
 public class JsonGenericSerializer<T, U extends DTO> {
 
+    public static <T, U extends DTO> RequireNestedConfiguration<T, U> forModules(Set<? extends DTOModule<? extends T, ? extends U>> modules) {
+        return nestedTypesModules -> {
+            ImmutableSet<DTOModule<? extends T, ? extends U>> dtoModules = ImmutableSet.copyOf(modules);
+            return new JsonGenericSerializer<>(dtoModules, ImmutableSet.copyOf(nestedTypesModules), new DTOConverter<>(dtoModules));
+        };
+    }
+
+    @SafeVarargs
+    public static <T, U extends DTO> RequireNestedConfiguration<T, U> forModules(DTOModule<? extends T, ? extends U>... modules) {
+        return forModules(ImmutableSet.copyOf(modules));
+    }
+
+    public interface RequireNestedConfiguration<T, U extends DTO> {
+        JsonGenericSerializer<T, U> withNestedTypeModules(Set<DTOModule<?, ?>> modules);
+
+        default JsonGenericSerializer<T, U> withNestedTypeModules(DTOModule<?, ?>... modules) {
+            return withNestedTypeModules(ImmutableSet.copyOf(modules));
+        }
+
+        default JsonGenericSerializer<T, U> withNestedTypeModules(Set<DTOModule<?, ?>>... modules) {
+            return withNestedTypeModules(Arrays.stream(modules).flatMap(Collection::stream).collect(Guavate.toImmutableSet()));
+        }
+
+        default JsonGenericSerializer<T, U> withoutNestedType() {
+            return withNestedTypeModules(ImmutableSet.of());
+        }
+    }
+
     public static class InvalidTypeException extends RuntimeException {
         public InvalidTypeException(String message) {
             super(message);
@@ -58,12 +89,7 @@ public class JsonGenericSerializer<T, U extends DTO> {
     private final ObjectMapper objectMapper;
     private final DTOConverter<T, U> dtoConverter;
 
-    @SafeVarargs
-    public static <T, U extends DTO> JsonGenericSerializer<T, U> of(DTOModule<T, U>... modules) {
-        return new JsonGenericSerializer<>(ImmutableSet.copyOf(modules), ImmutableSet.of(), DTOConverter.of(modules));
-    }
-
-    public JsonGenericSerializer(Set<? extends DTOModule<? extends T, ? extends U>> modules, Set<? extends DTOModule<?, ?>> nestedTypesModules, DTOConverter<T, U> converter) {
+    private JsonGenericSerializer(Set<? extends DTOModule<? extends T, ? extends U>> modules, Set<? extends DTOModule<?, ?>> nestedTypesModules, DTOConverter<T, U> converter) {
         this.dtoConverter = converter;
         this.objectMapper = buildObjectMapper(Sets.union(modules, nestedTypesModules));
     }
@@ -76,9 +102,10 @@ public class JsonGenericSerializer<T, U extends DTO> {
             .setSerializationInclusion(JsonInclude.Include.NON_ABSENT)
             .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
             .enable(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY);
-        modules.stream()
+        NamedType[] namedTypes = modules.stream()
             .map(module -> new NamedType(module.getDTOClass(), module.getDomainObjectType()))
-            .forEach(objectMapper::registerSubtypes);
+            .toArray(NamedType[]::new);
+        objectMapper.registerSubtypes(namedTypes);
         return objectMapper;
     }
 
diff --git a/json/src/test/java/org/apache/DTOConverterTest.java b/json/src/test/java/org/apache/DTOConverterTest.java
index d75fffe..6783b0e 100644
--- a/json/src/test/java/org/apache/DTOConverterTest.java
+++ b/json/src/test/java/org/apache/DTOConverterTest.java
@@ -43,15 +43,16 @@ import org.junit.jupiter.params.provider.MethodSource;
 class DTOConverterTest {
     private static final Optional<NestedType> NO_CHILD = Optional.empty();
     private static final Optional<DTO> NO_CHILD_DTO = Optional.empty();
-    private static final FirstDomainObject FIRST = new FirstDomainObject(Optional.of(1L), ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"), "first payload", NO_CHILD);
-    private static final FirstDTO FIRST_DTO = new FirstDTO("first", Optional.of(1L), "2016-04-03T02:01+07:00[Asia/Vientiane]", "first payload", NO_CHILD_DTO);
-    private static final SecondDomainObject SECOND = new SecondDomainObject(UUID.fromString("4a2c853f-7ffc-4ce3-9410-a47e85b3b741"), "second payload", NO_CHILD);
-    private static final SecondDTO SECOND_DTO = new SecondDTO("second", "4a2c853f-7ffc-4ce3-9410-a47e85b3b741", "second payload", NO_CHILD_DTO);
+    private static final BaseType FIRST = new FirstDomainObject(Optional.of(1L), ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"), "first payload", NO_CHILD);
+    private static final DTO FIRST_DTO = new FirstDTO("first", Optional.of(1L), "2016-04-03T02:01+07:00[Asia/Vientiane]", "first payload", NO_CHILD_DTO);
+    private static final BaseType SECOND = new SecondDomainObject(UUID.fromString("4a2c853f-7ffc-4ce3-9410-a47e85b3b741"), "second payload", NO_CHILD);
+    private static final DTO SECOND_DTO = new SecondDTO("second", "4a2c853f-7ffc-4ce3-9410-a47e85b3b741", "second payload", NO_CHILD_DTO);
 
     @SuppressWarnings("unchecked")
     @Test
     void shouldConvertFromKnownDTO() throws Exception {
-        assertThat(DTOConverter.of(TestModules.FIRST_TYPE)
+        assertThat(DTOConverter
+            .<BaseType, DTO>of(TestModules.FIRST_TYPE)
             .convert(FIRST_DTO))
             .contains(FIRST);
     }
@@ -105,7 +106,7 @@ class DTOConverterTest {
     @SuppressWarnings("unchecked")
     @Test
     void shouldConvertFromKnownDomainObject() throws Exception {
-        assertThat(DTOConverter.of(TestModules.FIRST_TYPE)
+        assertThat(DTOConverter.<BaseType, DTO>of(TestModules.FIRST_TYPE)
             .convert(FIRST))
             .hasValueSatisfying(result -> assertThat(result).isInstanceOf(FirstDTO.class).isEqualToComparingFieldByField(FIRST_DTO));
     }
diff --git a/json/src/test/java/org/apache/JsonGenericSerializerTest.java b/json/src/test/java/org/apache/JsonGenericSerializerTest.java
index 3fc6c45..d9bcde1 100644
--- a/json/src/test/java/org/apache/JsonGenericSerializerTest.java
+++ b/json/src/test/java/org/apache/JsonGenericSerializerTest.java
@@ -44,10 +44,10 @@ import org.junit.jupiter.params.provider.MethodSource;
 
 class JsonGenericSerializerTest {
     private static final Optional<NestedType> NO_CHILD = Optional.empty();
-    private static final FirstDomainObject FIRST = new FirstDomainObject(Optional.of(1L), ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"), "first payload", NO_CHILD);
-    private static final SecondDomainObject SECOND = new SecondDomainObject(UUID.fromString("4a2c853f-7ffc-4ce3-9410-a47e85b3b741"), "second payload", NO_CHILD);
-    private static final SecondDomainObject SECOND_WITH_NESTED = new SecondDomainObject(UUID.fromString("4a2c853f-7ffc-4ce3-9410-a47e85b3b741"), "second payload", Optional.of(new FirstNestedType(12)));
-    private static final FirstDomainObject FIRST_WITH_NESTED = new FirstDomainObject(Optional.of(1L), ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"), "payload", Optional.of(new SecondNestedType("bar")));
+    private static final BaseType FIRST = new FirstDomainObject(Optional.of(1L), ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"), "first payload", NO_CHILD);
+    private static final BaseType SECOND = new SecondDomainObject(UUID.fromString("4a2c853f-7ffc-4ce3-9410-a47e85b3b741"), "second payload", NO_CHILD);
+    private static final BaseType SECOND_WITH_NESTED = new SecondDomainObject(UUID.fromString("4a2c853f-7ffc-4ce3-9410-a47e85b3b741"), "second payload", Optional.of(new FirstNestedType(12)));
+    private static final BaseType FIRST_WITH_NESTED = new FirstDomainObject(Optional.of(1L), ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"), "payload", Optional.of(new SecondNestedType("bar")));
 
     private static final String MISSING_TYPE_JSON = "{\"id\":1,\"time\":\"2016-04-03T02:01+07:00[Asia/Vientiane]\",\"payload\":\"first payload\"}";
     private static final String DUPLICATE_TYPE_JSON = "{\"type\":\"first\", \"type\":\"second\", \"id\":1,\"time\":\"2016-04-03T02:01+07:00[Asia/Vientiane]\",\"payload\":\"first payload\"}";
@@ -56,51 +56,50 @@ class JsonGenericSerializerTest {
     private static final String SECOND_JSON = "{\"type\":\"second\",\"id\":\"4a2c853f-7ffc-4ce3-9410-a47e85b3b741\",\"payload\":\"second payload\"}";
     private static final String SECOND_WITH_NESTED_JSON = "{\"type\":\"second\",\"id\":\"4a2c853f-7ffc-4ce3-9410-a47e85b3b741\",\"payload\":\"second payload\", \"child\": {\"foo\": 12, \"type\": \"first-nested\"}}";
 
-    @SuppressWarnings("unchecked")
     @Test
     void shouldDeserializeKnownType() throws Exception {
-        assertThat(JsonGenericSerializer.of(TestModules.FIRST_TYPE)
+        assertThat(JsonGenericSerializer.forModules(TestModules.FIRST_TYPE).withoutNestedType()
             .deserialize(FIRST_JSON))
             .isEqualTo(FIRST);
     }
 
-    @SuppressWarnings("unchecked")
     @Test
     void shouldDeserializeNestedTypeWithSecond() throws Exception {
-        assertThat(JsonGenericSerializer.of(TestModules.FIRST_TYPE, TestModules.SECOND_TYPE, TestModules.FIRST_NESTED, TestModules.SECOND_NESTED)
+        assertThat(JsonGenericSerializer
+            .forModules(TestModules.FIRST_TYPE, TestModules.SECOND_TYPE)
+            .withNestedTypeModules(TestModules.FIRST_NESTED, TestModules.SECOND_NESTED)
             .deserialize(SECOND_WITH_NESTED_JSON))
             .isEqualTo(SECOND_WITH_NESTED);
     }
 
-    @SuppressWarnings("unchecked")
     @Test
     void shouldDeserializeNestedTypeWithFirst() throws Exception {
-        assertThat(JsonGenericSerializer.of(TestModules.FIRST_TYPE, TestModules.SECOND_TYPE, TestModules.FIRST_NESTED, TestModules.SECOND_NESTED)
+        assertThat(JsonGenericSerializer
+            .forModules(TestModules.FIRST_TYPE, TestModules.SECOND_TYPE)
+            .withNestedTypeModules(TestModules.FIRST_NESTED, TestModules.SECOND_NESTED)
             .deserialize(FIRST_JSON_WITH_NESTED))
             .isEqualTo(FIRST_WITH_NESTED);
     }
 
-    @SuppressWarnings("unchecked")
     @Test
     void shouldThrowWhenDeserializeEventWithMissingType() {
-        assertThatThrownBy(() -> JsonGenericSerializer.of(TestModules.FIRST_TYPE)
+        assertThatThrownBy(() -> JsonGenericSerializer.forModules(TestModules.FIRST_TYPE).withoutNestedType()
             .deserialize(MISSING_TYPE_JSON))
             .isInstanceOf(JsonGenericSerializer.InvalidTypeException.class);
     }
 
-    @SuppressWarnings("unchecked")
     @Test
     void shouldThrowWhenDeserializeEventWithDuplicatedTypes() {
-        assertThatThrownBy(() -> JsonGenericSerializer.of(
-                TestModules.FIRST_TYPE,
-                TestModules.SECOND_TYPE)
+        assertThatThrownBy(() -> JsonGenericSerializer
+            .forModules(TestModules.FIRST_TYPE, TestModules.SECOND_TYPE)
+            .withoutNestedType()
             .deserialize(DUPLICATE_TYPE_JSON))
             .isInstanceOf(JsonGenericSerializer.InvalidTypeException.class);
     }
 
     @Test
     void shouldThrowWhenDeserializeUnknownType() {
-        assertThatThrownBy(() -> JsonGenericSerializer.of()
+        assertThatThrownBy(() -> JsonGenericSerializer.forModules().withoutNestedType()
             .deserialize(FIRST_JSON))
             .isInstanceOf(JsonGenericSerializer.UnknownTypeException.class);
     }
@@ -108,12 +107,11 @@ class JsonGenericSerializerTest {
     @ParameterizedTest
     @MethodSource
     void serializeShouldHandleAllKnownTypes(BaseType domainObject, String serializedJson) throws Exception {
-        @SuppressWarnings("unchecked")
-        JsonGenericSerializer<BaseType, DTO> serializer = JsonGenericSerializer.of(
-                TestModules.FIRST_TYPE,
-                TestModules.SECOND_TYPE);
 
-        assertThatJson(serializer.serialize(domainObject))
+        assertThatJson(JsonGenericSerializer
+            .forModules(TestModules.FIRST_TYPE, TestModules.SECOND_TYPE)
+            .withoutNestedType()
+            .serialize(domainObject))
             .isEqualTo(serializedJson);
     }
 
@@ -124,12 +122,10 @@ class JsonGenericSerializerTest {
     @ParameterizedTest
     @MethodSource
     void deserializeShouldHandleAllKnownTypes(BaseType domainObject, String serializedJson) throws Exception {
-        @SuppressWarnings("unchecked")
-        JsonGenericSerializer<BaseType, DTO> serializer = JsonGenericSerializer.of(
-                TestModules.FIRST_TYPE,
-                TestModules.SECOND_TYPE);
-
-        assertThatJson(serializer.deserialize(serializedJson))
+        assertThatJson(JsonGenericSerializer
+            .forModules(TestModules.FIRST_TYPE, TestModules.SECOND_TYPE)
+            .withoutNestedType()
+            .deserialize(serializedJson))
             .isEqualTo(domainObject);
     }
 
@@ -144,17 +140,20 @@ class JsonGenericSerializerTest {
         );
     }
 
-    @SuppressWarnings("unchecked")
     @Test
     void shouldSerializeKnownType() throws Exception {
-        assertThatJson(JsonGenericSerializer.of(TestModules.FIRST_TYPE)
+        assertThatJson(JsonGenericSerializer
+            .<BaseType, DTO>forModules(TestModules.FIRST_TYPE)
+            .withoutNestedType()
             .serialize(FIRST))
             .isEqualTo(FIRST_JSON);
     }
 
     @Test
     void shouldThrowWhenSerializeUnknownType() {
-        assertThatThrownBy(() -> JsonGenericSerializer.of()
+        assertThatThrownBy(() -> JsonGenericSerializer
+            .forModules()
+            .withoutNestedType()
             .serialize(FIRST))
             .isInstanceOf(JsonGenericSerializer.UnknownTypeException.class);
     }
diff --git a/json/src/test/java/org/apache/dto/TestModules.java b/json/src/test/java/org/apache/dto/TestModules.java
index ad4d04b..d7cb781 100644
--- a/json/src/test/java/org/apache/dto/TestModules.java
+++ b/json/src/test/java/org/apache/dto/TestModules.java
@@ -24,7 +24,7 @@ import org.apache.james.json.DTOConverter;
 import org.apache.james.json.DTOModule;
 
 public interface TestModules {
-    TestNestedModule FIRST_NESTED = DTOModule
+    TestNestedModule<?, ?> FIRST_NESTED = DTOModule
         .forDomainObject(FirstNestedType.class)
         .convertToDTO(FirstNestedDTO.class)
         .toDomainObjectConverter(FirstNestedDTO::toDomainObject)
@@ -34,7 +34,7 @@ public interface TestModules {
             .typeName("first-nested")
         .withFactory(TestNestedModule::new);
 
-    TestNestedModule SECOND_NESTED = DTOModule
+    TestNestedModule<?, ?> SECOND_NESTED = DTOModule
         .forDomainObject(SecondNestedType.class)
         .convertToDTO(SecondNestedDTO.class)
         .toDomainObjectConverter(SecondNestedDTO::toDomainObject)
@@ -44,10 +44,9 @@ public interface TestModules {
         .typeName("second-nested")
         .withFactory(TestNestedModule::new);
 
-    DTOConverter NESTED_CONVERTERS = DTOConverter.of(FIRST_NESTED, SECOND_NESTED);
+    DTOConverter<NestedType, DTO> NESTED_CONVERTERS = DTOConverter.of(FIRST_NESTED, SECOND_NESTED);
 
-    @SuppressWarnings("rawtypes")
-    TestModule FIRST_TYPE = DTOModule
+    TestModule<?, ?> FIRST_TYPE = DTOModule
         .forDomainObject(FirstDomainObject.class)
         .convertToDTO(FirstDTO.class)
         .toDomainObjectConverter(dto -> dto.toDomainObject(NESTED_CONVERTERS))
@@ -56,12 +55,11 @@ public interface TestModules {
             domainObject.getId(),
             domainObject.getTime().toString(),
             domainObject.getPayload(),
-            NESTED_CONVERTERS.convert(domainObject.getChild())))
+            domainObject.getChild().flatMap(NESTED_CONVERTERS::convert)))
         .typeName("first")
         .withFactory(TestModule::new);
 
-    @SuppressWarnings("rawtypes")
-    TestModule SECOND_TYPE = DTOModule
+    TestModule<?, ?> SECOND_TYPE = DTOModule
         .forDomainObject(SecondDomainObject.class)
         .convertToDTO(SecondDTO.class)
         .toDomainObjectConverter(dto -> dto.toDomainObject(NESTED_CONVERTERS))
@@ -69,7 +67,7 @@ public interface TestModules {
             typeName,
             domainObject.getId().toString(),
             domainObject.getPayload(),
-            NESTED_CONVERTERS.convert(domainObject.getChild())))
+            domainObject.getChild().flatMap(NESTED_CONVERTERS::convert)))
         .typeName("second")
         .withFactory(TestModule::new);
 
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/MailboxPathV2MigrationTaskSerializationTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/MailboxPathV2MigrationTaskSerializationTest.java
index f0a0277..4012d94 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/MailboxPathV2MigrationTaskSerializationTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/MailboxPathV2MigrationTaskSerializationTest.java
@@ -30,9 +30,9 @@ import java.time.Instant;
 import org.apache.james.server.task.json.JsonTaskAdditionalInformationSerializer;
 import org.apache.james.server.task.json.JsonTaskSerializer;
 import org.apache.james.task.TaskExecutionDetails;
+import org.junit.jupiter.api.Test;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
-import org.junit.jupiter.api.Test;
 
 class MailboxPathV2MigrationTaskSerializationTest {
     private static final Instant TIMESTAMP = Instant.parse("2018-11-13T12:00:55Z");
@@ -42,8 +42,8 @@ class MailboxPathV2MigrationTaskSerializationTest {
     private static final MailboxPathV2Migration.AdditionalInformation DETAILS = new MailboxPathV2Migration.AdditionalInformation(42L, 10, TIMESTAMP);
     private static final String SERIALIZED_ADDITIONAL_INFORMATION = "{\"type\": \"cassandra-mailbox-path-v2-migration\", \"remainingCount\":42,\"initialCount\":10, \"timestamp\":\"2018-11-13T12:00:55Z\"}";
 
-    private static final JsonTaskSerializer TASK_SERIALIZER = new JsonTaskSerializer(MailboxPathV2MigrationTaskDTO.MODULE.apply(MIGRATION));
-    private static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = new JsonTaskAdditionalInformationSerializer(MailboxPathV2MigrationTaskAdditionalInformationDTO.MODULE);
+    private static final JsonTaskSerializer TASK_SERIALIZER = JsonTaskSerializer.of(MailboxPathV2MigrationTaskDTO.MODULE.apply(MIGRATION));
+    private static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = JsonTaskAdditionalInformationSerializer.of(MailboxPathV2MigrationTaskAdditionalInformationDTO.MODULE);
 
     @Test
     void taskShouldBeSerializable() throws JsonProcessingException {
@@ -63,12 +63,13 @@ class MailboxPathV2MigrationTaskSerializationTest {
     }
 
     @Test
-    void additonalInformationShouldBeDeserializable() throws IOException {
+    void additionalInformationShouldBeDeserializable() throws IOException {
         TaskExecutionDetails.AdditionalInformation deserialized = JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER.deserialize(SERIALIZED_ADDITIONAL_INFORMATION);
-        assertThat(deserialized).isInstanceOf(MailboxPathV2Migration.AdditionalInformation.class);
-
-        MailboxPathV2Migration.AdditionalInformation additionalInformation = (MailboxPathV2Migration.AdditionalInformation) deserialized;
-        assertThat(additionalInformation.getRemainingCount()).isEqualTo(DETAILS.getRemainingCount());
-        assertThat(additionalInformation.getInitialCount()).isEqualTo(DETAILS.getInitialCount());
+        assertThat(deserialized).isInstanceOfSatisfying(MailboxPathV2Migration.AdditionalInformation.class,
+            additionalInformation -> {
+                assertThat(additionalInformation.getRemainingCount()).isEqualTo(DETAILS.getRemainingCount());
+                assertThat(additionalInformation.getInitialCount()).isEqualTo(DETAILS.getInitialCount());
+            }
+        );
     }
 }
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/MailboxMergingTaskTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/MailboxMergingTaskTest.java
index 4e7b48e..dabac7c 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/MailboxMergingTaskTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/MailboxMergingTaskTest.java
@@ -29,10 +29,10 @@ import java.time.Instant;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.server.task.json.JsonTaskAdditionalInformationSerializer;
 import org.apache.james.server.task.json.JsonTaskSerializer;
+import org.junit.jupiter.api.Test;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import net.javacrumbs.jsonunit.assertj.JsonAssertions;
-import org.junit.jupiter.api.Test;
 
 class MailboxMergingTaskTest {
     private static final Instant TIMESTAMP = Instant.parse("2018-11-13T12:00:55Z");
@@ -42,8 +42,8 @@ class MailboxMergingTaskTest {
     private static final MailboxMergingTaskRunner TASK_RUNNER = mock(MailboxMergingTaskRunner.class);
     private static final MailboxMergingTask TASK = new MailboxMergingTask(TASK_RUNNER, 0L, CASSANDRA_ID_FACTORY.fromString("3b8e5f90-b94f-20f8-ce7b-3c4aad93b90c"), CASSANDRA_ID_FACTORY.fromString("2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd"));
     private static final MailboxMergingTask.Details DETAILS = new MailboxMergingTask.Details(CASSANDRA_ID_FACTORY.fromString("3b8e5f90-b94f-20f8-ce7b-3c4aad93b90c"), CASSANDRA_ID_FACTORY.fromString("2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd"), 10, 15, 20, TIMESTAMP);
-    private static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = new JsonTaskAdditionalInformationSerializer(MailboxMergingTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
-    private static final JsonTaskSerializer TESTEE = new JsonTaskSerializer(MailboxMergingTaskDTO.module(TASK_RUNNER));
+    private static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = JsonTaskAdditionalInformationSerializer.of(MailboxMergingTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
+    private static final JsonTaskSerializer TESTEE = JsonTaskSerializer.of(MailboxMergingTaskDTO.module(TASK_RUNNER));
 
     @Test
     void taskShouldBeSerializable() throws JsonProcessingException {
diff --git a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/blob/BlobStoreVaultGarbageCollectionTaskSerializationTest.java b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/blob/BlobStoreVaultGarbageCollectionTaskSerializationTest.java
index 6852dd7..ab2fff9 100644
--- a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/blob/BlobStoreVaultGarbageCollectionTaskSerializationTest.java
+++ b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/blob/BlobStoreVaultGarbageCollectionTaskSerializationTest.java
@@ -32,21 +32,19 @@ import org.apache.james.blob.api.BucketName;
 import org.apache.james.server.task.json.JsonTaskAdditionalInformationSerializer;
 import org.apache.james.server.task.json.JsonTaskSerializer;
 import org.apache.james.task.Task;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.google.common.collect.ImmutableList;
-
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.google.common.collect.ImmutableList;
 import reactor.core.publisher.Flux;
 
 class BlobStoreVaultGarbageCollectionTaskSerializationTest {
    private static final BlobStoreDeletedMessageVault DELETED_MESSAGE_VAULT = Mockito.mock(BlobStoreDeletedMessageVault.class);
    private static final BlobStoreVaultGarbageCollectionTask.Factory TASK_FACTORY = new BlobStoreVaultGarbageCollectionTask.Factory(DELETED_MESSAGE_VAULT);
 
-    private static final JsonTaskSerializer TASK_SERIALIZER = new JsonTaskSerializer(BlobStoreVaultGarbageCollectionTaskDTO.module(TASK_FACTORY));
+    private static final JsonTaskSerializer TASK_SERIALIZER = JsonTaskSerializer.of(BlobStoreVaultGarbageCollectionTaskDTO.module(TASK_FACTORY));
     private static final ZonedDateTime BEGINNING_OF_RETENTION_PERIOD = ZonedDateTime.parse("2019-09-03T15:26:13.356+02:00[Europe/Paris]");
     private static final ImmutableList<BucketName> BUCKET_IDS = ImmutableList.of(BucketName.of("1"), BucketName.of("2"), BucketName.of("3"));
     private static final Flux<BucketName> RETENTION_OPERATION = Flux.fromIterable(BUCKET_IDS);
@@ -57,7 +55,7 @@ class BlobStoreVaultGarbageCollectionTaskSerializationTest {
     private static final String SERIALIZED_TASK = "{\"type\":\"deleted-messages-blob-store-based-garbage-collection\"}";
     private static final String SERIALIZED_ADDITIONAL_INFORMATION_TASK = "{\"type\":\"deleted-messages-blob-store-based-garbage-collection\", \"beginningOfRetentionPeriod\":\"2019-09-03T15:26:13.356+02:00[Europe/Paris]\",\"deletedBuckets\":[\"1\", \"2\", \"3\"], \"timestamp\": \"2018-11-13T12:00:55Z\"}";
 
-    private static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = new JsonTaskAdditionalInformationSerializer(BlobStoreVaultGarbageCollectionTaskAdditionalInformationDTO.MODULE);
+    private static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = JsonTaskAdditionalInformationSerializer.of(BlobStoreVaultGarbageCollectionTaskAdditionalInformationDTO.MODULE);
 
     @BeforeAll
     static void setUp() {
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java
index 2311487..394bf6f 100644
--- a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java
@@ -148,56 +148,56 @@ class DTOTest {
 
     @Test
     void shouldSerializeQuotaThresholdChangedEvent() throws Exception {
-        assertThatJson(new JsonEventSerializer(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE)
+        assertThatJson(JsonEventSerializer.forModules(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE).withoutNestedType()
             .serialize(EVENT))
             .isEqualTo(EVENT_JSON);
     }
 
     @Test
     void shouldDeserializeQuotaThresholdChangedEvent() throws Exception {
-        assertThat(new JsonEventSerializer(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE)
+        assertThat(JsonEventSerializer.forModules(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE).withoutNestedType()
             .deserialize(EVENT_JSON))
             .isEqualTo(EVENT);
     }
 
     @Test
     void shouldSerializeEvent2() throws Exception {
-        assertThatJson(new JsonEventSerializer(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE)
+        assertThatJson(JsonEventSerializer.forModules(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE).withoutNestedType()
             .serialize(EVENT_2))
             .isEqualTo(EVENT_JSON_2);
     }
 
     @Test
     void shouldDeserializeEvent2() throws Exception {
-        assertThat(new JsonEventSerializer(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE)
+        assertThat(JsonEventSerializer.forModules(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE).withoutNestedType()
             .deserialize(EVENT_JSON_2))
             .isEqualTo(EVENT_2);
     }
 
     @Test
     void shouldSerializeEvent3() throws Exception {
-        assertThatJson(new JsonEventSerializer(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE)
+        assertThatJson(JsonEventSerializer.forModules(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE).withoutNestedType()
             .serialize(EVENT_3))
             .isEqualTo(EVENT_JSON_3);
     }
 
     @Test
     void shouldDeserializeEvent3() throws Exception {
-        assertThat(new JsonEventSerializer(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE)
+        assertThat(JsonEventSerializer.forModules(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE).withoutNestedType()
             .deserialize(EVENT_JSON_3))
             .isEqualTo(EVENT_3);
     }
 
     @Test
     void shouldSerializeEvent4() throws Exception {
-        assertThatJson(new JsonEventSerializer(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE)
+        assertThatJson(JsonEventSerializer.forModules(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE).withoutNestedType()
             .serialize(EVENT_4))
             .isEqualTo(EVENT_JSON_4);
     }
 
     @Test
     void shouldDeserializeEvent4() throws Exception {
-        assertThat(new JsonEventSerializer(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE)
+        assertThat(JsonEventSerializer.forModules(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE).withoutNestedType()
             .deserialize(EVENT_JSON_4))
             .isEqualTo(EVENT_4);
     }
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/listeners/CassandraQuotaMailingListenersIntegrationTest.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/listeners/CassandraQuotaMailingListenersIntegrationTest.java
index 8864507..55c3c44 100644
--- a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/listeners/CassandraQuotaMailingListenersIntegrationTest.java
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/listeners/CassandraQuotaMailingListenersIntegrationTest.java
@@ -20,11 +20,13 @@
 package org.apache.james.mailbox.quota.cassandra.listeners;
 
 import org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStoreExtension;
+import org.apache.james.eventsourcing.eventstore.cassandra.JsonEventSerializer;
 import org.apache.james.mailbox.quota.cassandra.dto.QuotaEventDTOModules;
 import org.apache.james.mailbox.quota.mailing.listeners.QuotaThresholdMailingIntegrationTest;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
 class CassandraQuotaMailingListenersIntegrationTest implements QuotaThresholdMailingIntegrationTest {
     @RegisterExtension
-    static CassandraEventStoreExtension eventStoreExtension = new CassandraEventStoreExtension(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE);
+    static CassandraEventStoreExtension eventStoreExtension =
+        new CassandraEventStoreExtension(JsonEventSerializer.forModules(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE).withoutNestedType());
 }
diff --git a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/ErrorRecoveryIndexationTaskSerializationTest.java b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/ErrorRecoveryIndexationTaskSerializationTest.java
index cbc823c..d71ad03 100644
--- a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/ErrorRecoveryIndexationTaskSerializationTest.java
+++ b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/ErrorRecoveryIndexationTaskSerializationTest.java
@@ -33,7 +33,6 @@ import org.apache.james.server.task.json.JsonTaskAdditionalInformationSerializer
 import org.apache.james.server.task.json.JsonTaskSerializer;
 import org.apache.james.task.Task;
 import org.apache.mailbox.tools.indexer.ReprocessingContextInformationDTO.ReprocessingContextInformationForErrorRecoveryIndexationTask;
-
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -71,9 +70,9 @@ class ErrorRecoveryIndexationTaskSerializationTest {
     void setUp() {
         reIndexerPerformer = mock(ReIndexerPerformer.class);
         ErrorRecoveryIndexationTask.Factory factory = new ErrorRecoveryIndexationTask.Factory(reIndexerPerformer, mailboxIdFactory);
-        taskSerializer = new JsonTaskSerializer(ErrorRecoveryIndexationTaskDTO.module(factory));
+        taskSerializer = JsonTaskSerializer.of(ErrorRecoveryIndexationTaskDTO.module(factory));
 
-        jsonAdditionalInformationSerializer = new JsonTaskAdditionalInformationSerializer(
+        jsonAdditionalInformationSerializer = JsonTaskAdditionalInformationSerializer.of(
             ReprocessingContextInformationForErrorRecoveryIndexationTask.serializationModule(mailboxIdFactory));
 
         reIndexingExecutionFailures = new ReIndexingExecutionFailures(ImmutableList.of(
diff --git a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/FullReindexingTaskSerializationTest.java b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/FullReindexingTaskSerializationTest.java
index 0c1a34b..3d0f9c5 100644
--- a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/FullReindexingTaskSerializationTest.java
+++ b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/FullReindexingTaskSerializationTest.java
@@ -61,9 +61,9 @@ class FullReindexingTaskSerializationTest {
     @BeforeEach
     void setUp() {
         reIndexerPerformer = mock(ReIndexerPerformer.class);
-        taskSerializer = new JsonTaskSerializer(FullReindexingTask.module(reIndexerPerformer));
+        taskSerializer = JsonTaskSerializer.of(FullReindexingTask.module(reIndexerPerformer));
 
-        jsonAdditionalInformationSerializer = new JsonTaskAdditionalInformationSerializer(
+        jsonAdditionalInformationSerializer = JsonTaskAdditionalInformationSerializer.of(
             ReprocessingContextInformationForFullReindexingTask.serializationModule(new TestId.Factory()));
 
         reIndexingExecutionFailures = new ReIndexingExecutionFailures(ImmutableList.of(
diff --git a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/MessageIdReindexingTaskSerializationTest.java b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/MessageIdReindexingTaskSerializationTest.java
index c1a873e..4c27cef 100644
--- a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/MessageIdReindexingTaskSerializationTest.java
+++ b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/MessageIdReindexingTaskSerializationTest.java
@@ -49,11 +49,11 @@ class MessageIdReindexingTaskSerializationTest {
     @BeforeEach
     void setUp() {
         messageIdFactory = new TestMessageId.Factory();
-        jsonAdditionalInformationSerializer = new JsonTaskAdditionalInformationSerializer(
+        jsonAdditionalInformationSerializer = JsonTaskAdditionalInformationSerializer.of(
             MessageIdReindexingTaskAdditionalInformationDTO.serializationModule(messageIdFactory));
         reIndexerPerformer = mock(ReIndexerPerformer.class);
         MessageIdReIndexingTask.Factory factory = new MessageIdReIndexingTask.Factory(reIndexerPerformer, messageIdFactory);
-        taskSerializer = new JsonTaskSerializer(MessageIdReindexingTaskDTO.module(factory));
+        taskSerializer = JsonTaskSerializer.of(MessageIdReindexingTaskDTO.module(factory));
     }
 
     @Test
diff --git a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/SingleMailboxReindexingTaskSerializationTest.java b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/SingleMailboxReindexingTaskSerializationTest.java
index 0ce4f36..b5c23c7 100644
--- a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/SingleMailboxReindexingTaskSerializationTest.java
+++ b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/SingleMailboxReindexingTaskSerializationTest.java
@@ -65,9 +65,9 @@ class SingleMailboxReindexingTaskSerializationTest {
     void setUp() {
         reIndexerPerformer = mock(ReIndexerPerformer.class);
         SingleMailboxReindexingTask.Factory factory = new SingleMailboxReindexingTask.Factory(reIndexerPerformer, new TestId.Factory());
-        taskSerializer = new JsonTaskSerializer(SingleMailboxReindexingTaskDTO.module(factory));
+        taskSerializer = JsonTaskSerializer.of(SingleMailboxReindexingTaskDTO.module(factory));
 
-        jsonAdditionalInformationSerializer = new JsonTaskAdditionalInformationSerializer(
+        jsonAdditionalInformationSerializer = JsonTaskAdditionalInformationSerializer.of(
             SingleMailboxReindexingTaskAdditionalInformationDTO.serializationModule(new TestId.Factory()));
 
         reIndexingExecutionFailures = new ReIndexingExecutionFailures(ImmutableList.of(
diff --git a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/SingleMessageReindexingTaskSerializationTest.java b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/SingleMessageReindexingTaskSerializationTest.java
index 9ba44ee..b97441b 100644
--- a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/SingleMessageReindexingTaskSerializationTest.java
+++ b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/SingleMessageReindexingTaskSerializationTest.java
@@ -45,14 +45,14 @@ class SingleMessageReindexingTaskSerializationTest {
     private final String SERIALIZED_ADDITIONAL_INFORMATION = "{\"type\": \"message-reindexing\", \"mailboxId\": \"1\", \"uid\": 10, \"timestamp\":\"2018-11-13T12:00:55Z\"}";
     private final TestId mailboxId = TestId.of(1L);
     private final MessageUid messageUid = MessageUid.of(10L);
-    private JsonTaskAdditionalInformationSerializer jsonAdditionalInformationSerializer = new JsonTaskAdditionalInformationSerializer(
+    private JsonTaskAdditionalInformationSerializer jsonAdditionalInformationSerializer = JsonTaskAdditionalInformationSerializer.of(
         SingleMessageReindexingTaskAdditionalInformationDTO.serializationModule(mailboxIdFactory));
 
     @BeforeEach
     void setUp() {
         reIndexerPerformer = mock(ReIndexerPerformer.class);
         SingleMessageReindexingTask.Factory factory = new SingleMessageReindexingTask.Factory(reIndexerPerformer, mailboxIdFactory);
-        taskSerializer = new JsonTaskSerializer(SingleMessageReindexingTaskDTO.module(factory));
+        taskSerializer = JsonTaskSerializer.of(SingleMessageReindexingTaskDTO.module(factory));
     }
 
     @Test
diff --git a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/UserReindexingTaskSerializationTest.java b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/UserReindexingTaskSerializationTest.java
index 701c131..ce2135a 100644
--- a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/UserReindexingTaskSerializationTest.java
+++ b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/UserReindexingTaskSerializationTest.java
@@ -68,8 +68,8 @@ class UserReindexingTaskSerializationTest {
     void setUp() {
         reIndexerPerformer = mock(ReIndexerPerformer.class);
         UserReindexingTask.Factory factory = new UserReindexingTask.Factory(reIndexerPerformer);
-        taskSerializer = new JsonTaskSerializer(UserReindexingTaskDTO.module(factory));
-        jsonAdditionalInformationSerializer = new JsonTaskAdditionalInformationSerializer(
+        taskSerializer = JsonTaskSerializer.of(UserReindexingTaskDTO.module(factory));
+        jsonAdditionalInformationSerializer = JsonTaskAdditionalInformationSerializer.of(
             UserReindexingTaskAdditionalInformationDTO.serializationModule(new TestId.Factory()));
 
         reIndexingExecutionFailures = new ReIndexingExecutionFailures(ImmutableList.of(
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 bc81db2..d438db7 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
@@ -35,8 +35,6 @@ import org.junit.jupiter.api.extension.ParameterContext;
 import org.junit.jupiter.api.extension.ParameterResolutionException;
 import org.junit.jupiter.api.extension.ParameterResolver;
 
-import com.google.common.collect.ImmutableSet;
-
 public class CassandraEventSourcingDLPConfigurationStoreExtension implements BeforeAllCallback, AfterAllCallback, AfterEachCallback, ParameterResolver {
 
     private final DockerCassandraExtension dockerCassandraExtension;
@@ -72,9 +70,9 @@ public class CassandraEventSourcingDLPConfigurationStoreExtension implements Bef
 
     @Override
     public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
-        JsonEventSerializer jsonEventSerializer = new JsonEventSerializer(
-                DLPConfigurationModules.DLP_CONFIGURATION_STORE,
-                DLPConfigurationModules.DLP_CONFIGURATION_CLEAR);
+        JsonEventSerializer jsonEventSerializer = JsonEventSerializer
+            .forModules(DLPConfigurationModules.DLP_CONFIGURATION_STORE, DLPConfigurationModules.DLP_CONFIGURATION_CLEAR)
+            .withoutNestedType();
 
         EventStoreDao eventStoreDao = new EventStoreDao(
             cassandra.getConf(),
diff --git a/server/data/data-cassandra/src/test/java/org/apache/james/rrt/cassandra/migration/MappingsSourcesMigrationTaskSerializationTest.java b/server/data/data-cassandra/src/test/java/org/apache/james/rrt/cassandra/migration/MappingsSourcesMigrationTaskSerializationTest.java
index e98fb43..edae144 100644
--- a/server/data/data-cassandra/src/test/java/org/apache/james/rrt/cassandra/migration/MappingsSourcesMigrationTaskSerializationTest.java
+++ b/server/data/data-cassandra/src/test/java/org/apache/james/rrt/cassandra/migration/MappingsSourcesMigrationTaskSerializationTest.java
@@ -29,9 +29,9 @@ import java.time.Instant;
 
 import org.apache.james.server.task.json.JsonTaskAdditionalInformationSerializer;
 import org.apache.james.server.task.json.JsonTaskSerializer;
+import org.junit.jupiter.api.Test;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
-import org.junit.jupiter.api.Test;
 
 class MappingsSourcesMigrationTaskSerializationTest {
     private static final Instant TIMESTAMP = Instant.parse("2018-11-13T12:00:55Z");
@@ -41,8 +41,8 @@ class MappingsSourcesMigrationTaskSerializationTest {
     private static final MappingsSourcesMigration.AdditionalInformation DETAILS = new MappingsSourcesMigration.AdditionalInformation(42L, 10, TIMESTAMP);
     private static final String SERIALIZED_ADDITIONAL_INFORMATION = "{\"type\": \"mappings-sources-migration\", \"successfulMappingsCount\":42,\"errorMappingsCount\":10,\"timestamp\":\"2018-11-13T12:00:55Z\"}";
 
-    private static final JsonTaskSerializer TASK_SERIALIZER = new JsonTaskSerializer(MappingsSourcesMigrationTaskDTO.MODULE.apply(MIGRATION));
-    private static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = new JsonTaskAdditionalInformationSerializer(MappingsSourcesMigrationTaskAdditionalInformationDTO.serializationModule(MappingsSourcesMigration.TYPE));
+    private static final JsonTaskSerializer TASK_SERIALIZER = JsonTaskSerializer.of(MappingsSourcesMigrationTaskDTO.MODULE.apply(MIGRATION));
+    private static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = JsonTaskAdditionalInformationSerializer.of(MappingsSourcesMigrationTaskAdditionalInformationDTO.serializationModule(MappingsSourcesMigration.TYPE));
 
     @Test
     void taskShouldBeSerializable() throws JsonProcessingException {
diff --git a/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/filtering/CassandraEventSourcingFilteringManagementTest.java b/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/filtering/CassandraEventSourcingFilteringManagementTest.java
index 68be998..555581e 100644
--- a/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/filtering/CassandraEventSourcingFilteringManagementTest.java
+++ b/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/filtering/CassandraEventSourcingFilteringManagementTest.java
@@ -20,10 +20,12 @@
 package org.apache.james.jmap.cassandra.filtering;
 
 import org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStoreExtension;
+import org.apache.james.eventsourcing.eventstore.cassandra.JsonEventSerializer;
 import org.apache.james.jmap.api.filtering.FilteringManagementContract;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
 class CassandraEventSourcingFilteringManagementTest implements FilteringManagementContract {
     @RegisterExtension
-    static CassandraEventStoreExtension eventStoreExtension = new CassandraEventStoreExtension(FilteringRuleSetDefineDTOModules.FILTERING_RULE_SET_DEFINED);
+    static CassandraEventStoreExtension eventStoreExtension =
+        new CassandraEventStoreExtension(JsonEventSerializer.forModules(FilteringRuleSetDefineDTOModules.FILTERING_RULE_SET_DEFINED).withoutNestedType());
 }
diff --git a/server/protocols/webadmin/webadmin-cassandra-data/src/test/java/org/apache/james/webadmin/service/CassandraMappingsSolveInconsistenciesTaskTest.java b/server/protocols/webadmin/webadmin-cassandra-data/src/test/java/org/apache/james/webadmin/service/CassandraMappingsSolveInconsistenciesTaskTest.java
index 9aa17cb..5faaa81 100644
--- a/server/protocols/webadmin/webadmin-cassandra-data/src/test/java/org/apache/james/webadmin/service/CassandraMappingsSolveInconsistenciesTaskTest.java
+++ b/server/protocols/webadmin/webadmin-cassandra-data/src/test/java/org/apache/james/webadmin/service/CassandraMappingsSolveInconsistenciesTaskTest.java
@@ -24,20 +24,20 @@ import static org.mockito.Mockito.mock;
 
 import java.io.IOException;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
 import org.apache.james.rrt.cassandra.CassandraMappingsSourcesDAO;
 import org.apache.james.rrt.cassandra.migration.MappingsSourcesMigration;
 import org.apache.james.server.task.json.JsonTaskSerializer;
+import org.junit.jupiter.api.Test;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
 import net.javacrumbs.jsonunit.assertj.JsonAssertions;
-import org.junit.jupiter.api.Test;
 
 class CassandraMappingsSolveInconsistenciesTaskTest {
     private static final String SERIALIZED = "{\"type\":\"cassandra-mappings-solve-inconsistencies\"}";
     private static final MappingsSourcesMigration MAPPINGS_SOURCES_MIGRATION = mock(MappingsSourcesMigration.class);
     private static final CassandraMappingsSourcesDAO CASSANDRA_MAPPINGS_SOURCES_DAO = mock(CassandraMappingsSourcesDAO.class);
     private static final CassandraMappingsSolveInconsistenciesTask TASK = new CassandraMappingsSolveInconsistenciesTask(MAPPINGS_SOURCES_MIGRATION, CASSANDRA_MAPPINGS_SOURCES_DAO);
-    private static final JsonTaskSerializer TESTEE = new JsonTaskSerializer(CassandraMappingsSolveInconsistenciesTask.module(MAPPINGS_SOURCES_MIGRATION, CASSANDRA_MAPPINGS_SOURCES_DAO));
+    private static final JsonTaskSerializer TESTEE = JsonTaskSerializer.of(CassandraMappingsSolveInconsistenciesTask.module(MAPPINGS_SOURCES_MIGRATION, CASSANDRA_MAPPINGS_SOURCES_DAO));
 
     @Test
     void taskShouldBeSerializable() throws JsonProcessingException {
diff --git a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultDeleteTaskSerializationTest.java b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultDeleteTaskSerializationTest.java
index 8706f96..38277cc 100644
--- a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultDeleteTaskSerializationTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultDeleteTaskSerializationTest.java
@@ -56,8 +56,8 @@ class DeletedMessagesVaultDeleteTaskSerializationTest {
     void setUp() {
         deletedMessageVault = mock(DeletedMessageVault.class);
         DeletedMessagesVaultDeleteTask.Factory factory = new DeletedMessagesVaultDeleteTask.Factory(deletedMessageVault, messageIdFactory);
-        taskSerializer = new JsonTaskSerializer(DeletedMessagesVaultDeleteTaskDTO.module(factory));
-        jsonAdditionalInformationSerializer = new JsonTaskAdditionalInformationSerializer(DeletedMessagesVaultDeleteTaskAdditionalInformationDTO.serializationModule(messageIdFactory));
+        taskSerializer = JsonTaskSerializer.of(DeletedMessagesVaultDeleteTaskDTO.module(factory));
+        jsonAdditionalInformationSerializer = JsonTaskAdditionalInformationSerializer.of(DeletedMessagesVaultDeleteTaskAdditionalInformationDTO.serializationModule(messageIdFactory));
     }
 
     @Test
diff --git a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultExportTaskSerializationTest.java b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultExportTaskSerializationTest.java
index 65f0b0f..bee616e 100644
--- a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultExportTaskSerializationTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultExportTaskSerializationTest.java
@@ -65,7 +65,7 @@ class DeletedMessagesVaultExportTaskSerializationTest {
         "\"exportTo\":\"james@apache.org\"}\n";
     private static final String SERIALIZED_ADDITIONAL_INFORMATION_TASK = "{\"type\":\"deleted-messages-export\", \"exportTo\":\"james@apache.org\",\"userExportFrom\":\"james\",\"totalExportedMessages\":42, \"timestamp\":\"2018-11-13T12:00:55Z\"}";
 
-    private static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = new JsonTaskAdditionalInformationSerializer(DeletedMessagesVaultExportTaskAdditionalInformationDTO.MODULE);
+    private static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = JsonTaskAdditionalInformationSerializer.of(DeletedMessagesVaultExportTaskAdditionalInformationDTO.MODULE);
 
     @BeforeAll
     static void init() throws AddressException {
@@ -77,7 +77,7 @@ class DeletedMessagesVaultExportTaskSerializationTest {
     void setUp() {
         exportService = mock(ExportService.class);
         DeletedMessagesVaultExportTaskDTO.Factory factory = new DeletedMessagesVaultExportTaskDTO.Factory(exportService, queryTranslator);
-        taskSerializer = new JsonTaskSerializer(DeletedMessagesVaultExportTaskDTO.module(factory));
+        taskSerializer = JsonTaskSerializer.of(DeletedMessagesVaultExportTaskDTO.module(factory));
     }
 
     @Test
diff --git a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultRestoreTaskSerializationTest.java b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultRestoreTaskSerializationTest.java
index 4bfa982..42e6f20 100644
--- a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultRestoreTaskSerializationTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultRestoreTaskSerializationTest.java
@@ -59,13 +59,13 @@ class DeletedMessagesVaultRestoreTaskSerializationTest {
         "}";
     private static final String SERIALIZED_ADDITIONAL_INFORMATION_TASK = "{\"type\":\"deleted-messages-restore\", \"user\":\"james\",\"successfulRestoreCount\":42,\"errorRestoreCount\":10, \"timestamp\":\"2018-11-13T12:00:55Z\"}";
 
-    private static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = new JsonTaskAdditionalInformationSerializer(DeletedMessagesVaultRestoreTaskAdditionalInformationDTO.MODULE);
+    private static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = JsonTaskAdditionalInformationSerializer.of(DeletedMessagesVaultRestoreTaskAdditionalInformationDTO.MODULE);
 
     @BeforeEach
     void setUp() {
         exportService = mock(RestoreService.class);
         DeletedMessagesVaultRestoreTaskDTO.Factory factory = new DeletedMessagesVaultRestoreTaskDTO.Factory(exportService, queryTranslator);
-        taskSerializer = new JsonTaskSerializer(DeletedMessagesVaultRestoreTaskDTO.module(factory));
+        taskSerializer = JsonTaskSerializer.of(DeletedMessagesVaultRestoreTaskDTO.module(factory));
     }
 
     @Test
diff --git a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/WebadminApiQuerySerializationContractTest.java b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/WebadminApiQuerySerializationContractTest.java
index 0dadb58..ef5b656 100644
--- a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/WebadminApiQuerySerializationContractTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/WebadminApiQuerySerializationContractTest.java
@@ -94,7 +94,7 @@ class WebadminApiQuerySerializationContractTest {
     private final static QueryTranslator queryTranslator = new QueryTranslator(mailboxIdFactory);
     private final static RestoreService restoreService = Mockito.mock(RestoreService.class);
     private final static DeletedMessagesVaultRestoreTaskDTO.Factory factory = new DeletedMessagesVaultRestoreTaskDTO.Factory(restoreService, queryTranslator);
-    private final static JsonTaskSerializer taskSerializer = new JsonTaskSerializer(DeletedMessagesVaultRestoreTaskDTO.module(factory));
+    private final static JsonTaskSerializer taskSerializer = JsonTaskSerializer.of(DeletedMessagesVaultRestoreTaskDTO.module(factory));
 
     /**
      * Enforce that the format of the query serialized in json in the body of the request to the webadmin is stable.
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/EventDeadLettersRedeliverTaskTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/EventDeadLettersRedeliverTaskTest.java
index 9764739..0c24d8a 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/EventDeadLettersRedeliverTaskTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/EventDeadLettersRedeliverTaskTest.java
@@ -58,12 +58,12 @@ class EventDeadLettersRedeliverTaskTest {
     private static final EventDeadLettersRedeliverAllTask TASK_ALL = new EventDeadLettersRedeliverAllTask(SERVICE);
     private static final EventDeadLettersRedeliverGroupTask TASK_GROUP = new EventDeadLettersRedeliverGroupTask(SERVICE, new GenericGroup("abc"));
     private static final EventDeadLettersRedeliverOneTask TASK_ONE = new EventDeadLettersRedeliverOneTask(SERVICE, new GenericGroup("abc"), EventDeadLetters.InsertionId.of("fcbc3c92-e9a0-4ece-94ed-6e6b45045258"));
-    private static final JsonTaskSerializer TESTEE = new JsonTaskSerializer(
+    private static final JsonTaskSerializer TESTEE = JsonTaskSerializer.of(
         EventDeadLettersRedeliverAllTaskDTO.module(SERVICE),
         EventDeadLettersRedeliverGroupTaskDTO.module(SERVICE),
         EventDeadLettersRedeliverOneTaskDTO.module(SERVICE));
 
-    private JsonTaskAdditionalInformationSerializer jsonAdditionalInformationSerializer = new JsonTaskAdditionalInformationSerializer(
+    private JsonTaskAdditionalInformationSerializer jsonAdditionalInformationSerializer = JsonTaskAdditionalInformationSerializer.of(
         EventDeadLettersRedeliveryTaskAdditionalInformationForAll.MODULE,
         EventDeadLettersRedeliveryTaskAdditionalInformationForGroup.MODULE,
         EventDeadLettersRedeliveryTaskAdditionalInformationForOne.MODULE);
diff --git a/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/service/ClearMailQueueTaskTest.java b/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/service/ClearMailQueueTaskTest.java
index cdde343..54d2c95 100644
--- a/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/service/ClearMailQueueTaskTest.java
+++ b/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/service/ClearMailQueueTaskTest.java
@@ -44,7 +44,7 @@ class ClearMailQueueTaskTest {
     private static final String QUEUE_NAME = "anyQueue";
     private static final long INITIAL_COUNT = 0L;
     private static final long REMAINING_COUNT = 10L;
-    private JsonTaskAdditionalInformationSerializer jsonAdditionalInformationSerializer = new JsonTaskAdditionalInformationSerializer(
+    private JsonTaskAdditionalInformationSerializer jsonAdditionalInformationSerializer = JsonTaskAdditionalInformationSerializer.of(
         ClearMailQueueTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
     private static final String SERIALIZED_TASK_ADDITIONAL_INFORMATION = "{\"type\": \"clear-mail-queue\", \"mailQueueName\":\"anyQueue\",\"initialCount\":0,\"remainingCount\":10, \"timestamp\":\"2018-11-13T12:00:55Z\"}";
 
@@ -54,7 +54,7 @@ class ClearMailQueueTaskTest {
         ManageableMailQueue mockedQueue = mock(ManageableMailQueue.class);
         when(mockedQueue.getName()).thenReturn(QUEUE_NAME);
         when(mailQueueFactory.getQueue(anyString())).thenAnswer(arg -> Optional.of(mockedQueue));
-        JsonTaskSerializer testee = new JsonTaskSerializer(ClearMailQueueTaskDTO.module(mailQueueFactory));
+        JsonTaskSerializer testee = JsonTaskSerializer.of(ClearMailQueueTaskDTO.module(mailQueueFactory));
 
         ManageableMailQueue queue = mailQueueFactory.getQueue(QUEUE_NAME).get();
         ClearMailQueueTask task = new ClearMailQueueTask(queue);
@@ -67,7 +67,7 @@ class ClearMailQueueTaskTest {
         ManageableMailQueue mockedQueue = mock(ManageableMailQueue.class);
         when(mockedQueue.getName()).thenReturn(QUEUE_NAME);
         when(mailQueueFactory.getQueue(anyString())).thenAnswer(arg -> Optional.of(mockedQueue));
-        JsonTaskSerializer testee = new JsonTaskSerializer(ClearMailQueueTaskDTO.module(mailQueueFactory));
+        JsonTaskSerializer testee = JsonTaskSerializer.of(ClearMailQueueTaskDTO.module(mailQueueFactory));
 
         ManageableMailQueue queue = mailQueueFactory.getQueue(QUEUE_NAME).get();
         ClearMailQueueTask task = new ClearMailQueueTask(queue);
@@ -78,7 +78,7 @@ class ClearMailQueueTaskTest {
     void taskShouldThrowWhenDeserializeAnUnknownQueue() throws Exception {
         MailQueueFactory<ManageableMailQueue> mailQueueFactory = mock(MailQueueFactory.class);
         when(mailQueueFactory.getQueue(anyString())).thenReturn(Optional.empty());
-        JsonTaskSerializer testee = new JsonTaskSerializer(ClearMailQueueTaskDTO.module(mailQueueFactory));
+        JsonTaskSerializer testee = JsonTaskSerializer.of(ClearMailQueueTaskDTO.module(mailQueueFactory));
 
         String serializedJson = "{\"type\": \"clear-mail-queue\", \"queue\": \"anyQueue\"}";
         assertThatThrownBy(() -> testee.deserialize(serializedJson))
diff --git a/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/service/DeleteMailsFromMailQueueTaskTest.java b/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/service/DeleteMailsFromMailQueueTaskTest.java
index 098a1f6..edd4c54 100644
--- a/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/service/DeleteMailsFromMailQueueTaskTest.java
+++ b/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/service/DeleteMailsFromMailQueueTaskTest.java
@@ -50,7 +50,7 @@ class DeleteMailsFromMailQueueTaskTest {
     private MailQueueFactory<ManageableMailQueue> mailQueueFactory;
     private ManageableMailQueue mockedQueue;
     private final static String queueName = "anyQueue";
-    private JsonTaskAdditionalInformationSerializer jsonAdditionalInformationSerializer = new JsonTaskAdditionalInformationSerializer(DeleteMailsFromMailQueueTaskAdditionalInformationDTO.MODULE);
+    private JsonTaskAdditionalInformationSerializer jsonAdditionalInformationSerializer = JsonTaskAdditionalInformationSerializer.of(DeleteMailsFromMailQueueTaskAdditionalInformationDTO.MODULE);
 
     @BeforeEach
     private void setUp() {
@@ -64,7 +64,7 @@ class DeleteMailsFromMailQueueTaskTest {
     @MethodSource
     void taskShouldBeSerializable(Optional<MailAddress> sender, Optional<String> name, Optional<MailAddress> recipient, String serializedJson) throws Exception {
 
-        JsonTaskSerializer testee = new JsonTaskSerializer(DeleteMailsFromMailQueueTaskDTO.module(mailQueueFactory));
+        JsonTaskSerializer testee = JsonTaskSerializer.of(DeleteMailsFromMailQueueTaskDTO.module(mailQueueFactory));
 
         ManageableMailQueue queue = mailQueueFactory.getQueue(queueName).get();
         DeleteMailsFromMailQueueTask task = new DeleteMailsFromMailQueueTask(queue, sender, name, recipient);
@@ -78,7 +78,7 @@ class DeleteMailsFromMailQueueTaskTest {
     @ParameterizedTest
     @MethodSource
     void taskShouldBeDeserializable(Optional<MailAddress> sender, Optional<String> name, Optional<MailAddress> recipient, String serializedJson) throws Exception {
-        JsonTaskSerializer testee = new JsonTaskSerializer(DeleteMailsFromMailQueueTaskDTO.module(mailQueueFactory));
+        JsonTaskSerializer testee = JsonTaskSerializer.of(DeleteMailsFromMailQueueTaskDTO.module(mailQueueFactory));
 
         ManageableMailQueue queue = mailQueueFactory.getQueue(queueName).get();
         DeleteMailsFromMailQueueTask task = new DeleteMailsFromMailQueueTask(queue, sender, name, recipient);
@@ -101,7 +101,7 @@ class DeleteMailsFromMailQueueTaskTest {
     void taskShouldThrowWhenDeserializeAnUnknownQueue() throws Exception {
         MailQueueFactory<ManageableMailQueue> mailQueueFactory = mock(MailQueueFactory.class);
         when(mailQueueFactory.getQueue(anyString())).thenReturn(Optional.empty());
-        JsonTaskSerializer testee = new JsonTaskSerializer(DeleteMailsFromMailQueueTaskDTO.module(mailQueueFactory));
+        JsonTaskSerializer testee = JsonTaskSerializer.of(DeleteMailsFromMailQueueTaskDTO.module(mailQueueFactory));
 
         String serializedJson = "{\"type\": \"delete-mails-from-mail-queue\", \"queue\": \"anyQueue\", \"sender\": \"a@b.c\"}";
         assertThatThrownBy(() -> testee.deserialize(serializedJson))
@@ -110,7 +110,7 @@ class DeleteMailsFromMailQueueTaskTest {
 
     @Test
     void taskShouldThrowWhenDeserializeAMalformedMailAddress() throws Exception {
-        JsonTaskSerializer testee = new JsonTaskSerializer(DeleteMailsFromMailQueueTaskDTO.module(mailQueueFactory));
+        JsonTaskSerializer testee = JsonTaskSerializer.of(DeleteMailsFromMailQueueTaskDTO.module(mailQueueFactory));
 
         String serializedJson = "{\"type\": \"delete-mails-from-mail-queue\", \"queue\": \"" + queueName + "\", \"sender\": \"a.b.c\"}";
         assertThatThrownBy(() -> testee.deserialize(serializedJson))
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/ClearMailRepositoryTaskTest.java b/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/ClearMailRepositoryTaskTest.java
index 33b47f4..fdaf67f 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/ClearMailRepositoryTaskTest.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/ClearMailRepositoryTaskTest.java
@@ -50,19 +50,19 @@ class ClearMailRepositoryTaskTest {
     private static final ClearMailRepositoryTask TASK = new ClearMailRepositoryTask(MAIL_REPOSITORIES, MAIL_REPOSITORY_PATH);
     private static final long INITIAL_COUNT = 0L;
     private static final long REMAINING_COUNT = 10L;
-    private JsonTaskAdditionalInformationSerializer jsonAdditionalInformationSerializer = new JsonTaskAdditionalInformationSerializer(
+    private JsonTaskAdditionalInformationSerializer jsonAdditionalInformationSerializer = JsonTaskAdditionalInformationSerializer.of(
         ClearMailRepositoryTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
 
     @Test
     void taskShouldBeSerializable() throws JsonProcessingException {
-        JsonTaskSerializer testee = new JsonTaskSerializer(ClearMailRepositoryTaskDTO.module(FACTORY));
+        JsonTaskSerializer testee = JsonTaskSerializer.of(ClearMailRepositoryTaskDTO.module(FACTORY));
         JsonAssertions.assertThatJson(testee.serialize(TASK))
             .isEqualTo(SERIALIZED);
     }
 
     @Test
     void taskShouldBeDeserializable() throws IOException {
-        JsonTaskSerializer testee = new JsonTaskSerializer(ClearMailRepositoryTaskDTO.module(FACTORY));
+        JsonTaskSerializer testee = JsonTaskSerializer.of(ClearMailRepositoryTaskDTO.module(FACTORY));
 
         assertThat(testee.deserialize(SERIALIZED))
             .isEqualToComparingFieldByFieldRecursively(TASK);
@@ -70,7 +70,7 @@ class ClearMailRepositoryTaskTest {
 
     @Test
     void taskShouldThrowOnDeserializationUrlDecodingError() {
-        JsonTaskSerializer testee = new JsonTaskSerializer(ClearMailRepositoryTaskDTO.module(FACTORY));
+        JsonTaskSerializer testee = JsonTaskSerializer.of(ClearMailRepositoryTaskDTO.module(FACTORY));
 
         assertThatThrownBy(() -> testee.deserialize("{\"type\":\"clear-mail-repository\",\"mailRepositoryPath\":\"%\"}"))
             .isInstanceOf(ClearMailRepositoryTask.InvalidMailRepositoryPathDeserializationException.class);
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/ReprocessingAllMailsTaskTest.java b/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/ReprocessingAllMailsTaskTest.java
index f05c984..c419a1c 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/ReprocessingAllMailsTaskTest.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/ReprocessingAllMailsTaskTest.java
@@ -44,7 +44,7 @@ class ReprocessingAllMailsTaskTest {
 
     private static final Instant TIMESTAMP = Instant.parse("2018-11-13T12:00:55Z");
     private static final ReprocessingService REPROCESSING_SERVICE = mock(ReprocessingService.class);
-    private JsonTaskAdditionalInformationSerializer jsonAdditionalInformationSerializer = new JsonTaskAdditionalInformationSerializer(ReprocessingAllMailsTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
+    private JsonTaskAdditionalInformationSerializer jsonAdditionalInformationSerializer = JsonTaskAdditionalInformationSerializer.of(ReprocessingAllMailsTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
     private static final long REPOSITORY_SIZE = 5L;
     private static final MailRepositoryPath REPOSITORY_PATH = MailRepositoryPath.from("a");
     private static final String TARGET_QUEUE = "queue";
@@ -63,7 +63,7 @@ class ReprocessingAllMailsTaskTest {
                                   String targetQueue,
                                   Optional<String> targetProcessor,
                                   String serialized) throws JsonProcessingException {
-        JsonTaskSerializer testee = new JsonTaskSerializer(ReprocessingAllMailsTaskDTO.module(REPROCESSING_SERVICE));
+        JsonTaskSerializer testee = JsonTaskSerializer.of(ReprocessingAllMailsTaskDTO.module(REPROCESSING_SERVICE));
         ReprocessingAllMailsTask task = new ReprocessingAllMailsTask(REPROCESSING_SERVICE, repositorySize, repositoryPath, targetQueue, targetProcessor);
         assertThatJson(testee.serialize(task))
             .isEqualTo(serialized);
@@ -80,7 +80,7 @@ class ReprocessingAllMailsTaskTest {
                                     String targetQueue,
                                     Optional<String> targetProcessor,
                                     String serialized) throws IOException {
-        JsonTaskSerializer testee = new JsonTaskSerializer(ReprocessingAllMailsTaskDTO.module(REPROCESSING_SERVICE));
+        JsonTaskSerializer testee = JsonTaskSerializer.of(ReprocessingAllMailsTaskDTO.module(REPROCESSING_SERVICE));
         ReprocessingAllMailsTask task = new ReprocessingAllMailsTask(REPROCESSING_SERVICE, repositorySize, repositoryPath, targetQueue, targetProcessor);
 
         assertThat(testee.deserialize(serialized))
@@ -101,7 +101,7 @@ class ReprocessingAllMailsTaskTest {
     @ParameterizedTest
     @ValueSource(strings = {"{\"type\":\"reprocessing-all\",\"repositorySize\":5,\"repositoryPath\":\"%\",\"targetQueue\":\"queue\",\"targetProcessor\":\"targetProcessor\"}", "{\"type\":\"reprocessing-all\",\"repositorySize\":5,\"repositoryPath\":\"%\",\"targetQueue\":\"queue\"}"})
     void taskShouldThrowOnDeserializationUrlDecodingError(String serialized) {
-        JsonTaskSerializer testee = new JsonTaskSerializer(ReprocessingAllMailsTaskDTO.module(REPROCESSING_SERVICE));
+        JsonTaskSerializer testee = JsonTaskSerializer.of(ReprocessingAllMailsTaskDTO.module(REPROCESSING_SERVICE));
 
         assertThatThrownBy(() -> testee.deserialize(serialized))
             .isInstanceOf(ReprocessingAllMailsTask.InvalidMailRepositoryPathDeserializationException.class);
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/ReprocessingOneMailTaskTest.java b/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/ReprocessingOneMailTaskTest.java
index b23c4cf..434a16b 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/ReprocessingOneMailTaskTest.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/ReprocessingOneMailTaskTest.java
@@ -55,7 +55,7 @@ class ReprocessingOneMailTaskTest {
     private static final String TARGET_QUEUE = "queue";
     private static final MailKey MAIL_KEY = new MailKey("myMail");
     private static final Optional<String> TARGET_PROCESSOR = Optional.of("targetProcessor");
-    private JsonTaskAdditionalInformationSerializer jsonAdditionalInformationSerializer = new JsonTaskAdditionalInformationSerializer(ReprocessingOneMailTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
+    private JsonTaskAdditionalInformationSerializer jsonAdditionalInformationSerializer = JsonTaskAdditionalInformationSerializer.of(ReprocessingOneMailTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
 
     @ParameterizedTest
     @MethodSource
@@ -64,7 +64,7 @@ class ReprocessingOneMailTaskTest {
                                   MailKey mailKey,
                                   Optional<String> targetProcessor,
                                   String serialized) throws JsonProcessingException {
-        JsonTaskSerializer testee = new JsonTaskSerializer(ReprocessingOneMailTaskDTO.module(CLOCK, REPROCESSING_SERVICE));
+        JsonTaskSerializer testee = JsonTaskSerializer.of(ReprocessingOneMailTaskDTO.module(CLOCK, REPROCESSING_SERVICE));
         ReprocessingOneMailTask task = new ReprocessingOneMailTask(REPROCESSING_SERVICE, repositoryPath, targetQueue, mailKey, targetProcessor, CLOCK);
         JsonAssertions.assertThatJson(testee.serialize(task))
             .isEqualTo(serialized);
@@ -81,7 +81,7 @@ class ReprocessingOneMailTaskTest {
                                     MailKey mailKey,
                                     Optional<String> targetProcessor,
                                     String serialized) throws IOException {
-        JsonTaskSerializer testee = new JsonTaskSerializer(ReprocessingOneMailTaskDTO.module(CLOCK, REPROCESSING_SERVICE));
+        JsonTaskSerializer testee = JsonTaskSerializer.of(ReprocessingOneMailTaskDTO.module(CLOCK, REPROCESSING_SERVICE));
         ReprocessingOneMailTask task = new ReprocessingOneMailTask(REPROCESSING_SERVICE, repositoryPath, targetQueue, mailKey, targetProcessor, CLOCK);
 
         assertThat(testee.deserialize(serialized))
@@ -102,7 +102,7 @@ class ReprocessingOneMailTaskTest {
     @ParameterizedTest
     @ValueSource(strings = {"{\"type\":\"reprocessing-one\",\"repositoryPath\":\"%\",\"targetQueue\":\"queue\",\"mailKey\": \"myMail\",\"targetProcessor\":\"targetProcessor\"}", "{\"type\":\"reprocessing-one\",\"repositoryPath\":\"%\",\"targetQueue\":\"queue\",\"mailKey\": \"myMail\"}"})
     void taskShouldThrowOnDeserializationUrlDecodingError(String serialized) {
-        JsonTaskSerializer testee = new JsonTaskSerializer(ReprocessingOneMailTaskDTO.module(CLOCK, REPROCESSING_SERVICE));
+        JsonTaskSerializer testee = JsonTaskSerializer.of(ReprocessingOneMailTaskDTO.module(CLOCK, REPROCESSING_SERVICE));
 
         assertThatThrownBy(() -> testee.deserialize(serialized))
             .isInstanceOf(ReprocessingOneMailTask.InvalidMailRepositoryPathDeserializationException.class);
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 5ce44f7..a43c6c6 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
@@ -33,8 +33,6 @@ import org.apache.james.queue.rabbitmq.view.cassandra.configuration.CassandraMai
 import org.apache.james.queue.rabbitmq.view.cassandra.configuration.EventsourcingConfigurationManagement;
 
 import com.datastax.driver.core.Session;
-import com.google.common.collect.ImmutableSet;
-
 import reactor.core.publisher.Mono;
 
 public class CassandraMailQueueViewTestFactory {
@@ -54,7 +52,7 @@ public class CassandraMailQueueViewTestFactory {
 
 
         EventsourcingConfigurationManagement eventsourcingConfigurationManagement = new EventsourcingConfigurationManagement(new CassandraEventStore(new EventStoreDao(session,
-            new JsonEventSerializer(CassandraMailQueueViewConfigurationModule.MAIL_QUEUE_VIEW_CONFIGURATION))));
+            JsonEventSerializer.forModules(CassandraMailQueueViewConfigurationModule.MAIL_QUEUE_VIEW_CONFIGURATION).withoutNestedType())));
 
         return new CassandraMailQueueView.Factory(
             cassandraMailQueueMailStore,
diff --git a/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/EventsourcingConfigurationManagementTest.java b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/EventsourcingConfigurationManagementTest.java
index 5f96ef3..960c421 100644
--- a/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/EventsourcingConfigurationManagementTest.java
+++ b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/EventsourcingConfigurationManagementTest.java
@@ -29,14 +29,16 @@ import java.util.List;
 import org.apache.james.eventsourcing.Event;
 import org.apache.james.eventsourcing.eventstore.EventStore;
 import org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStoreExtension;
+import org.apache.james.eventsourcing.eventstore.cassandra.JsonEventSerializer;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
 class EventsourcingConfigurationManagementTest {
 
     @RegisterExtension
-    static CassandraEventStoreExtension eventStoreExtension = new CassandraEventStoreExtension(
-        CassandraMailQueueViewConfigurationModule.MAIL_QUEUE_VIEW_CONFIGURATION);
+    static CassandraEventStoreExtension eventStoreExtension =
+        new CassandraEventStoreExtension(
+            JsonEventSerializer.forModules(CassandraMailQueueViewConfigurationModule.MAIL_QUEUE_VIEW_CONFIGURATION).withoutNestedType());
 
     private static final int DEFAULT_BUCKET_COUNT = 10;
     private static final int DEFAULT_UPDATE_PACE = 100;
diff --git a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/cassandra/CassandraTaskExecutionDetailsProjectionDAOTest.java b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/cassandra/CassandraTaskExecutionDetailsProjectionDAOTest.java
index 2247d4c..991c2d0 100644
--- a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/cassandra/CassandraTaskExecutionDetailsProjectionDAOTest.java
+++ b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/cassandra/CassandraTaskExecutionDetailsProjectionDAOTest.java
@@ -47,7 +47,7 @@ class CassandraTaskExecutionDetailsProjectionDAOTest {
     @RegisterExtension
     static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(
         CassandraModule.aggregateModules(CassandraSchemaVersionModule.MODULE, CassandraZonedDateTimeModule.MODULE, CassandraTaskExecutionDetailsProjectionModule.MODULE()));
-    private static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = new JsonTaskAdditionalInformationSerializer(MemoryReferenceWithCounterTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
+    private static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = JsonTaskAdditionalInformationSerializer.of(MemoryReferenceWithCounterTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
 
     private CassandraTaskExecutionDetailsProjectionDAO testee;
 
diff --git a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/cassandra/CassandraTaskExecutionDetailsProjectionTest.java b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/cassandra/CassandraTaskExecutionDetailsProjectionTest.java
index a2dcf15..0492207 100644
--- a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/cassandra/CassandraTaskExecutionDetailsProjectionTest.java
+++ b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/cassandra/CassandraTaskExecutionDetailsProjectionTest.java
@@ -30,9 +30,6 @@ import org.apache.james.server.task.json.JsonTaskAdditionalInformationSerializer
 import org.apache.james.server.task.json.dto.MemoryReferenceWithCounterTaskAdditionalInformationDTO;
 import org.apache.james.task.eventsourcing.TaskExecutionDetailsProjection;
 import org.apache.james.task.eventsourcing.TaskExecutionDetailsProjectionContract;
-
-import org.apache.james.task.eventsourcing.cassandra.CassandraTaskExecutionDetailsProjection;
-import org.apache.james.task.eventsourcing.cassandra.CassandraTaskExecutionDetailsProjectionDAO;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
@@ -41,7 +38,7 @@ class CassandraTaskExecutionDetailsProjectionTest implements TaskExecutionDetail
     @RegisterExtension
     static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(
             CassandraModule.aggregateModules(CassandraSchemaVersionModule.MODULE, CassandraZonedDateTimeModule.MODULE, CassandraTaskExecutionDetailsProjectionModule.MODULE()));
-    private static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = new JsonTaskAdditionalInformationSerializer(MemoryReferenceWithCounterTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
+    private static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = JsonTaskAdditionalInformationSerializer.of(MemoryReferenceWithCounterTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
 
     private Supplier<CassandraTaskExecutionDetailsProjection> testeeSupplier;
 
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 ff98f90..02c6024 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
@@ -45,6 +45,7 @@ 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.AdditionalInformationDTOModule;
 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;
@@ -72,8 +73,6 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-import com.google.common.collect.ImmutableSet;
-
 class DistributedTaskManagerTest implements TaskManagerContract {
 
     static class TrackedRabbitMQWorkQueueSupplier implements WorkQueueSupplier {
@@ -99,8 +98,9 @@ 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);
+    public static final AdditionalInformationDTOModule<?, ?> ADDITIONAL_INFORMATION_MODULE = MemoryReferenceWithCounterTaskAdditionalInformationDTO.SERIALIZATION_MODULE;
+    static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = JsonTaskAdditionalInformationSerializer.of(ADDITIONAL_INFORMATION_MODULE);
+    static final DTOConverter<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> DTO_CONVERTER = DTOConverter.of(ADDITIONAL_INFORMATION_MODULE);
     static final Hostname HOSTNAME = new Hostname("foo");
     static final Hostname HOSTNAME_2 = new Hostname("bar");
 
@@ -116,7 +116,7 @@ class DistributedTaskManagerTest implements TaskManagerContract {
             CassandraZonedDateTimeModule.MODULE,
             CassandraTaskExecutionDetailsProjectionModule.MODULE()));
 
-    JsonTaskSerializer taskSerializer = new JsonTaskSerializer(
+    JsonTaskSerializer taskSerializer = JsonTaskSerializer.of(
         TestTaskDTOModules.COMPLETED_TASK_MODULE,
         TestTaskDTOModules.FAILED_TASK_MODULE,
         TestTaskDTOModules.THROWING_TASK_MODULE,
@@ -126,7 +126,8 @@ class DistributedTaskManagerTest implements TaskManagerContract {
     Set<EventDTOModule<?, ?>> eventDtoModule = TasksSerializationModule.list(taskSerializer, DTO_CONVERTER);
 
     @RegisterExtension
-    CassandraEventStoreExtension eventStoreExtension = new CassandraEventStoreExtension(CASSANDRA_CLUSTER, eventDtoModule);
+    CassandraEventStoreExtension eventStoreExtension = new CassandraEventStoreExtension(CASSANDRA_CLUSTER,
+        JsonEventSerializer.forModules(eventDtoModule).withNestedTypeModules(ADDITIONAL_INFORMATION_MODULE));
 
     @RegisterExtension
     CountDownLatchExtension countDownLatchExtension = new CountDownLatchExtension();
@@ -145,7 +146,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(new DTOConverter<>(eventDtoModule), eventDtoModule, ImmutableSet.of());
+        this.eventSerializer = JsonEventSerializer.forModules(eventDtoModule).withoutNestedType();
     }
 
     @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 db2c02b..7e358cd 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
@@ -39,13 +39,12 @@ import org.awaitility.Awaitility;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-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 JsonTaskSerializer TASK_SERIALIZER = JsonTaskSerializer.of();
     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());
+    private static final JsonEventSerializer SERIALIZER = JsonEventSerializer.forModules(MODULES).withoutNestedType();
 
     @RegisterExtension
     static RabbitMQExtension rabbitMQExtension = RabbitMQExtension.singletonRabbitMQ();
diff --git a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/RabbitMQWorkQueueTest.java b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/RabbitMQWorkQueueTest.java
index fefb6f1..3d8b17e 100644
--- a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/RabbitMQWorkQueueTest.java
+++ b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/RabbitMQWorkQueueTest.java
@@ -100,7 +100,7 @@ class RabbitMQWorkQueueTest {
     @BeforeEach
     void setUp() {
         worker = spy(new ImmediateWorker());
-        serializer = new JsonTaskSerializer(TestTaskDTOModules.COMPLETED_TASK_MODULE);
+        serializer = JsonTaskSerializer.of(TestTaskDTOModules.COMPLETED_TASK_MODULE);
         testee = new RabbitMQWorkQueue(worker, rabbitMQExtension.getRabbitChannelPool(), serializer);
         testee.start();
     }
@@ -150,7 +150,7 @@ class RabbitMQWorkQueueTest {
         TaskWithId taskWithId = new TaskWithId(taskId, task);
 
         ImmediateWorker otherTaskManagerWorker = new ImmediateWorker();
-        JsonTaskSerializer otherTaskSerializer = new JsonTaskSerializer(TestTaskDTOModules.TEST_TYPE);
+        JsonTaskSerializer otherTaskSerializer = JsonTaskSerializer.of(TestTaskDTOModules.TEST_TYPE);
         try (RabbitMQWorkQueue otherWorkQueue = new RabbitMQWorkQueue(otherTaskManagerWorker, rabbitMQExtension.getRabbitChannelPool(), otherTaskSerializer)) {
             //wait to be sur that the first workqueue has subscribed as an exclusive consumer of the RabbitMQ queue.
             Thread.sleep(200);
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 4edfa51..0b5d1e0 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
@@ -53,14 +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 JsonTaskAdditionalInformationSerializer TASK_ADDITIONNAL_INFORMATION_SERIALIZER = JsonTaskAdditionalInformationSerializer.of(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);
     static final Task TASK = new CompletedTask();
@@ -68,12 +67,14 @@ class TaskEventsSerializationTest {
     static final MemoryReferenceWithCounterTask.AdditionalInformation COUNTER_ADDITIONAL_INFORMATION = new MemoryReferenceWithCounterTask.AdditionalInformation(3, TIMESTAMP);
 
     private final Set<EventDTOModule<?, ?>> list = TasksSerializationModule.list(
-        new JsonTaskSerializer(
+        JsonTaskSerializer.of(
             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));
+    JsonEventSerializer serializer = JsonEventSerializer
+        .forModules(list)
+        .withNestedTypeModules(MemoryReferenceWithCounterTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
 
     @ParameterizedTest
     @MethodSource
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 eb68ef9..52c0608 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,7 +23,6 @@ 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;
@@ -34,6 +33,10 @@ import com.google.common.collect.ImmutableSet;
 
 public class JsonTaskAdditionalInformationSerializer {
 
+    public static JsonTaskAdditionalInformationSerializer of(AdditionalInformationDTOModule<?, ?>... modules) {
+        return new JsonTaskAdditionalInformationSerializer(ImmutableSet.copyOf(modules));
+    }
+
     public static class InvalidAdditionalInformationException extends RuntimeException {
         public InvalidAdditionalInformationException(JsonGenericSerializer.InvalidTypeException original) {
             super(original);
@@ -49,12 +52,8 @@ public class JsonTaskAdditionalInformationSerializer {
     private JsonGenericSerializer<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> jsonGenericSerializer;
 
     @Inject
-    public JsonTaskAdditionalInformationSerializer(Set<AdditionalInformationDTOModule<?, ?>> modules) {
-        jsonGenericSerializer = new JsonGenericSerializer(modules, ImmutableSet.of(), new DTOConverter<>(modules));
-    }
-
-    public JsonTaskAdditionalInformationSerializer(@SuppressWarnings("rawtypes") AdditionalInformationDTOModule... modules) {
-        this(ImmutableSet.copyOf(modules));
+    private JsonTaskAdditionalInformationSerializer(Set<AdditionalInformationDTOModule<?, ?>> modules) {
+        jsonGenericSerializer = JsonGenericSerializer.forModules(modules).withoutNestedType();
     }
 
     public String serialize(TaskExecutionDetails.AdditionalInformation additionalInformation) throws JsonProcessingException {
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 313aa50..31f4a77 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,7 +24,6 @@ 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;
@@ -35,6 +34,10 @@ import com.google.common.collect.ImmutableSet;
 
 public class JsonTaskSerializer {
 
+    public static JsonTaskSerializer of(TaskDTOModule<?, ?>... modules) {
+        return new JsonTaskSerializer(ImmutableSet.copyOf(modules));
+    }
+
     public static class InvalidTaskException  extends RuntimeException {
         public InvalidTaskException(JsonGenericSerializer.InvalidTypeException original) {
             super(original);
@@ -50,12 +53,8 @@ public class JsonTaskSerializer {
     private JsonGenericSerializer<Task, TaskDTO> jsonGenericSerializer;
 
     @Inject
-    public JsonTaskSerializer(DTOConverter<Task, TaskDTO> converter, Set<TaskDTOModule<?, ?>> modules) {
-        jsonGenericSerializer = new JsonGenericSerializer(modules, ImmutableSet.of(), converter);
-    }
-
-    public JsonTaskSerializer(@SuppressWarnings("rawtypes") TaskDTOModule... modules) {
-        this(DTOConverter.of(modules), ImmutableSet.copyOf(modules));
+    private JsonTaskSerializer(Set<TaskDTOModule<?, ?>> modules) {
+        jsonGenericSerializer = JsonGenericSerializer.forModules(modules).withoutNestedType();
     }
 
     public String serialize(Task task) throws JsonProcessingException {
diff --git a/server/task/task-json/src/test/java/org/apache/james/server/task/json/TaskDeserializerTest.java b/server/task/task-json/src/test/java/org/apache/james/server/task/json/TaskDeserializerTest.java
index 4d2a947..305593f 100644
--- a/server/task/task-json/src/test/java/org/apache/james/server/task/json/TaskDeserializerTest.java
+++ b/server/task/task-json/src/test/java/org/apache/james/server/task/json/TaskDeserializerTest.java
@@ -52,7 +52,7 @@ class TaskDeserializerTest {
 
     @BeforeEach
     void setUp() {
-        testee = new JsonTaskSerializer(TestTaskDTOModules.TEST_TYPE);
+        testee = JsonTaskSerializer.of(TestTaskDTOModules.TEST_TYPE);
     }
 
     @Test
diff --git a/server/task/task-json/src/test/java/org/apache/james/server/task/json/TaskSerializationTest.java b/server/task/task-json/src/test/java/org/apache/james/server/task/json/TaskSerializationTest.java
index 85205ad..09e11ce 100644
--- a/server/task/task-json/src/test/java/org/apache/james/server/task/json/TaskSerializationTest.java
+++ b/server/task/task-json/src/test/java/org/apache/james/server/task/json/TaskSerializationTest.java
@@ -51,7 +51,7 @@ class TaskSerializationTest {
     @ParameterizedTest
     @MethodSource
     void taskShouldBeSerializable(Task task, TaskDTOModule<?, ?> module, String expectedJson) throws Exception {
-        String actual = new JsonTaskSerializer(module).serialize(task);
+        String actual = JsonTaskSerializer.of(module).serialize(task);
         assertThatJson(actual).isEqualTo(expectedJson);
     }
 
@@ -62,7 +62,7 @@ class TaskSerializationTest {
     @ParameterizedTest
     @MethodSource
     void taskShouldBeDeserializable(Task task, TaskDTOModule<?, ?> module, String serializedJson) throws Exception {
-        assertThat(new JsonTaskSerializer(module).deserialize(serializedJson))
+        assertThat(JsonTaskSerializer.of(module).deserialize(serializedJson))
             .isInstanceOf(task.getClass());
     }
 
@@ -82,7 +82,7 @@ class TaskSerializationTest {
     void memoryReferenceTaskShouldSerialize() throws JsonProcessingException {
         MemoryReferenceTask memoryReferenceTask = new MemoryReferenceTask(() -> Task.Result.COMPLETED);
 
-        String actual = new JsonTaskSerializer(MEMORY_REFERENCE_TASK_MODULE.apply(new MemoryReferenceTaskStore())).serialize(memoryReferenceTask);
+        String actual = JsonTaskSerializer.of(MEMORY_REFERENCE_TASK_MODULE.apply(new MemoryReferenceTaskStore())).serialize(memoryReferenceTask);
         assertThatJson(actual).isEqualTo(SERIALIZED_MEMORY_REFERENCE_TASK);
     }
 
@@ -92,7 +92,7 @@ class TaskSerializationTest {
         MemoryReferenceTask memoryReferenceTask = new MemoryReferenceTask(() -> Task.Result.COMPLETED);
         memoryReferenceTaskStore.add(memoryReferenceTask);
 
-        Task task = new JsonTaskSerializer(MEMORY_REFERENCE_TASK_MODULE.apply(memoryReferenceTaskStore)).deserialize(SERIALIZED_MEMORY_REFERENCE_TASK);
+        Task task = JsonTaskSerializer.of(MEMORY_REFERENCE_TASK_MODULE.apply(memoryReferenceTaskStore)).deserialize(SERIALIZED_MEMORY_REFERENCE_TASK);
         assertThat(task).isInstanceOf(MemoryReferenceTask.class);
     }
 }
diff --git a/server/task/task-json/src/test/java/org/apache/james/server/task/json/TaskSerializerTest.java b/server/task/task-json/src/test/java/org/apache/james/server/task/json/TaskSerializerTest.java
index 38983bc..d018068 100644
--- a/server/task/task-json/src/test/java/org/apache/james/server/task/json/TaskSerializerTest.java
+++ b/server/task/task-json/src/test/java/org/apache/james/server/task/json/TaskSerializerTest.java
@@ -30,7 +30,7 @@ class TaskSerializerTest {
 
     @Test
     void shouldSerializeTaskWithItsType() throws Exception {
-        JsonTaskSerializer testee = new JsonTaskSerializer(TestTaskDTOModules.TEST_TYPE);
+        JsonTaskSerializer testee = JsonTaskSerializer.of(TestTaskDTOModules.TEST_TYPE);
         long parameter = 1L;
         TestTask task = new TestTask(parameter);
         JsonAssertions.assertThatJson(testee.serialize(task)).isEqualTo(TASK_AS_STRING);


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


[james-project] 13/41: JAMES-2964 Changelog for negative quota creation

Posted by bt...@apache.org.
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 4e7df2c52226c72a6dc5bdb33e6394763dcff022
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue Nov 19 09:52:06 2019 +0700

    JAMES-2964 Changelog for negative quota creation
---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0c96758..5baf925 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -39,6 +39,7 @@ of tasks being currently executed.
 - MAILBOX-392 Mailbox name validation upon mailbox creation is stricter: forbid `#&*%` and empty sub-mailboxes names.
 - JAMES-2972 Incorrect attribute name in the mailet configuration thanks to jtconsol
 - JAMES-2632 JMAP Draft GetMailboxes performance enhancements when retrieving all mailboxes of a user
+- JAMES-2964 Forbid to create User quota/ Domain quota/ Global quota using negative number
 
 ### Removed
 - Classes marked as deprecated whose removal was planned after 3.4.0 release (See JAMES-2703). This includes:


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


[james-project] 05/41: Changelog entry for library upgrade

Posted by bt...@apache.org.
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 366f867dc336a1956d6dc94e7641192d99bd5523
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue Nov 5 11:10:42 2019 +0700

    Changelog entry for library upgrade
---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index a116a55..0a5ad25 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,7 @@ of tasks being currently executed.
   - Removed unnecessary fields from mailbox mapping
   - Disable dynamic mapping thanks to a change of the header structure 
   - Read related [upgrade instructions](upgrade-instructions.md)
+- JAMES-2855 Multiple library/plugin/docker images/build tool upgrades
   
 ### Fixed
 - JAMES-2828 & JAMES-2929 bugs affecting JDBCMailRepository usage with PostgresSQL thanks to Jörg Thomas & Sergey B


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


[james-project] 17/41: JAMES-2813 make sure only constants are static and follow usual naming convention

Posted by bt...@apache.org.
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 f6e753fb3f64bddbc505693c842bf04215aa145b
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Thu Oct 17 16:06:48 2019 +0200

    JAMES-2813 make sure only constants are static and follow usual naming convention
---
 .../distributed/DistributedTaskManagerTest.java    | 65 +++++++++++-----------
 .../distributed/TaskEventsSerializationTest.java   | 47 ++++++++--------
 2 files changed, 57 insertions(+), 55 deletions(-)

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 2b60b6e..73170a5 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
@@ -73,7 +73,8 @@ import org.junit.jupiter.api.extension.RegisterExtension;
 import com.github.steveash.guavate.Guavate;
 
 class DistributedTaskManagerTest implements TaskManagerContract {
-    private static class TrackedRabbitMQWorkQueueSupplier implements WorkQueueSupplier {
+
+    static class TrackedRabbitMQWorkQueueSupplier implements WorkQueueSupplier {
         private final List<RabbitMQWorkQueue> workQueues;
         private final RabbitMQWorkQueueSupplier supplier;
 
@@ -96,51 +97,51 @@ class DistributedTaskManagerTest implements TaskManagerContract {
         }
     }
 
-    private static final JsonTaskSerializer TASK_SERIALIZER = new JsonTaskSerializer(
-        TestTaskDTOModules.COMPLETED_TASK_MODULE,
-        TestTaskDTOModules.FAILED_TASK_MODULE,
-        TestTaskDTOModules.THROWING_TASK_MODULE,
-        TestTaskDTOModules.MEMORY_REFERENCE_TASK_MODULE.apply(new MemoryReferenceTaskStore()),
-        TestTaskDTOModules.MEMORY_REFERENCE_WITH_COUNTER_TASK_MODULE.apply(new MemoryReferenceWithCounterTaskStore())
-        );
-
-    private static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = new JsonTaskAdditionalInformationSerializer(MemoryReferenceWithCounterTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
-
-    private static final Hostname HOSTNAME = new Hostname("foo");
-    private static final Hostname HOSTNAME_2 = new Hostname("bar");
-    private static final Set<EventDTOModule<?, ?>> MODULES = TasksSerializationModule.list(TASK_SERIALIZER, JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER).stream().collect(Guavate.toImmutableSet());
-    private static final JsonEventSerializer EVENT_SERIALIZER = new JsonEventSerializer(MODULES);
+    static final JsonTaskAdditionalInformationSerializer JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER = new JsonTaskAdditionalInformationSerializer(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();
 
-    static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(
+    @RegisterExtension
+    static final CassandraClusterExtension CASSANDRA_CLUSTER = new CassandraClusterExtension(
         CassandraModule.aggregateModules(
             CassandraSchemaVersionModule.MODULE,
             CassandraEventStoreModule.MODULE,
             CassandraZonedDateTimeModule.MODULE,
             CassandraTaskExecutionDetailsProjectionModule.MODULE()));
 
-    @RegisterExtension
-    static RabbitMQExtension rabbitMQExtension = RabbitMQExtension.singletonRabbitMQ();
+    JsonTaskSerializer taskSerializer = new JsonTaskSerializer(
+        TestTaskDTOModules.COMPLETED_TASK_MODULE,
+        TestTaskDTOModules.FAILED_TASK_MODULE,
+        TestTaskDTOModules.THROWING_TASK_MODULE,
+        TestTaskDTOModules.MEMORY_REFERENCE_TASK_MODULE.apply(new MemoryReferenceTaskStore()),
+        TestTaskDTOModules.MEMORY_REFERENCE_WITH_COUNTER_TASK_MODULE.apply(new MemoryReferenceWithCounterTaskStore()));
 
-    @RegisterExtension
-    static CassandraEventStoreExtension eventStoreExtension = new CassandraEventStoreExtension(cassandraCluster, MODULES);
+    Set<EventDTOModule<?, ?>> eventDtoModule = TasksSerializationModule.list(taskSerializer, JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER).stream().collect(Guavate.toImmutableSet());
 
     @RegisterExtension
-    static CountDownLatchExtension countDownLatchExtension = new CountDownLatchExtension();
+    CassandraEventStoreExtension eventStoreExtension = new CassandraEventStoreExtension(CASSANDRA_CLUSTER, eventDtoModule);
 
-    private final CassandraCluster cassandra = cassandraCluster.getCassandraCluster();
-    private final CassandraTaskExecutionDetailsProjectionDAO cassandraTaskExecutionDetailsProjectionDAO = new CassandraTaskExecutionDetailsProjectionDAO(cassandra.getConf(), cassandra.getTypesProvider(), JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER);
-    private final TaskExecutionDetailsProjection executionDetailsProjection = new CassandraTaskExecutionDetailsProjection(cassandraTaskExecutionDetailsProjectionDAO);
+    @RegisterExtension
+    CountDownLatchExtension countDownLatchExtension = new CountDownLatchExtension();
 
-    private TrackedRabbitMQWorkQueueSupplier workQueueSupplier;
-    private EventStore eventStore;
-    private List<RabbitMQTerminationSubscriber> terminationSubscribers;
+    TrackedRabbitMQWorkQueueSupplier workQueueSupplier;
+    EventStore eventStore;
+    List<RabbitMQTerminationSubscriber> terminationSubscribers;
+    TaskExecutionDetailsProjection executionDetailsProjection;
+    JsonEventSerializer eventSerializer;
 
     @BeforeEach
     void setUp(EventStore eventStore) {
-        workQueueSupplier = new TrackedRabbitMQWorkQueueSupplier(rabbitMQExtension.getRabbitChannelPool(), TASK_SERIALIZER);
+        CassandraCluster cassandra = CASSANDRA_CLUSTER.getCassandraCluster();
+        CassandraTaskExecutionDetailsProjectionDAO projectionDAO = new CassandraTaskExecutionDetailsProjectionDAO(cassandra.getConf(), cassandra.getTypesProvider(), JSON_TASK_ADDITIONAL_INFORMATION_SERIALIZER);
+        this.executionDetailsProjection = new CassandraTaskExecutionDetailsProjection(projectionDAO);
+        this.workQueueSupplier = new TrackedRabbitMQWorkQueueSupplier(RABBIT_MQ_EXTENSION.getRabbitChannelPool(), taskSerializer);
         this.eventStore = eventStore;
-        terminationSubscribers = new ArrayList<>();
+        this.terminationSubscribers = new ArrayList<>();
+        this.eventSerializer = new JsonEventSerializer(eventDtoModule);
     }
 
     @AfterEach
@@ -153,8 +154,8 @@ class DistributedTaskManagerTest implements TaskManagerContract {
         return taskManager(HOSTNAME);
     }
 
-    private EventSourcingTaskManager taskManager(Hostname hostname) {
-        RabbitMQTerminationSubscriber terminationSubscriber = new RabbitMQTerminationSubscriber(rabbitMQExtension.getRabbitChannelPool(), EVENT_SERIALIZER);
+    EventSourcingTaskManager taskManager(Hostname hostname) {
+        RabbitMQTerminationSubscriber terminationSubscriber = new RabbitMQTerminationSubscriber(RABBIT_MQ_EXTENSION.getRabbitChannelPool(), eventSerializer);
         terminationSubscribers.add(terminationSubscriber);
         terminationSubscriber.start();
         return new EventSourcingTaskManager(workQueueSupplier, eventStore, executionDetailsProjection, hostname, terminationSubscriber);
@@ -177,7 +178,7 @@ class DistributedTaskManagerTest implements TaskManagerContract {
     }
 
     @Test
-    void givenTwoTaskManagersAndTwoTaskOnlyOneTaskShouldRunAtTheSameTime() throws InterruptedException {
+    void givenTwoTaskManagersAndTwoTaskOnlyOneTaskShouldRunAtTheSameTime() {
         CountDownLatch waitingForFirstTaskLatch = new CountDownLatch(1);
 
         try (EventSourcingTaskManager taskManager1 = taskManager();
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 bcb2a6d..1ad3921 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,10 @@ 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.server.task.json.JsonTaskAdditionalInformationSerializer;
 import org.apache.james.server.task.json.JsonTaskSerializer;
 import org.apache.james.server.task.json.dto.MemoryReferenceWithCounterTaskAdditionalInformationDTO;
@@ -50,44 +48,47 @@ import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 
-import com.github.steveash.guavate.Guavate;
 import net.javacrumbs.jsonunit.assertj.JsonAssertions;
 import scala.Option;
 
 class TaskEventsSerializationTest {
-    private static final Instant TIMESTAMP = Instant.parse("2018-11-13T12:00:55Z");
-    private static final JsonTaskSerializer TASK_SERIALIZER = new JsonTaskSerializer(TestTaskDTOModules.COMPLETED_TASK_MODULE,
-        TestTaskDTOModules.MEMORY_REFERENCE_WITH_COUNTER_TASK_MODULE.apply(new MemoryReferenceWithCounterTaskStore()));
-    private static final JsonTaskAdditionalInformationSerializer TASK_ADDITIONNAL_INFORMATION_SERIALIZER = new JsonTaskAdditionalInformationSerializer(MemoryReferenceWithCounterTaskAdditionalInformationDTO.SERIALIZATION_MODULE);
-    private static final Set<EventDTOModule<?, ?>> MODULES = TasksSerializationModule.list(TASK_SERIALIZER, TASK_ADDITIONNAL_INFORMATION_SERIALIZER);
-    private static final JsonEventSerializer SERIALIZER = new JsonEventSerializer(MODULES.stream().collect(Guavate.toImmutableSet()));
-    private static final TaskAggregateId AGGREGATE_ID = new TaskAggregateId(TaskId.fromString("2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd"));
-    private static final EventId EVENT_ID = EventId.fromSerialized(42);
-    private static final Task TASK = new CompletedTask();
-    private static final Hostname HOSTNAME = new Hostname("foo");
-    private static final MemoryReferenceWithCounterTask.AdditionalInformation counterAdditionalInformation = new MemoryReferenceWithCounterTask.AdditionalInformation(3, TIMESTAMP);
+    static final Instant TIMESTAMP = Instant.parse("2018-11-13T12:00:55Z");
+    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);
+    static final Task TASK = new CompletedTask();
+    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));
 
     @ParameterizedTest
     @MethodSource
     void taskShouldBeSerializable(TaskEvent event, String serializedJson) throws Exception {
-        JsonAssertions.assertThatJson(SERIALIZER.serialize(event)).isEqualTo(serializedJson);
+        JsonAssertions.assertThatJson(serializer.serialize(event)).isEqualTo(serializedJson);
     }
 
-    private static Stream<Arguments> taskShouldBeSerializable() throws Exception {
+    static Stream<Arguments> taskShouldBeSerializable() throws Exception {
         return validTasks();
     }
 
     @ParameterizedTest
     @MethodSource
     void taskShouldBeDeserializable(TaskEvent event, String serializedJson) throws Exception {
-        assertThat(SERIALIZER.deserialize(serializedJson)).isEqualToComparingFieldByFieldRecursively(event);
+        assertThat(serializer.deserialize(serializedJson)).isEqualToComparingFieldByFieldRecursively(event);
     }
 
-    private static Stream<Arguments> taskShouldBeDeserializable() throws Exception {
+    static Stream<Arguments> taskShouldBeDeserializable() throws Exception {
         return validTasks();
     }
 
-    private static Stream<Arguments> validTasks() throws Exception {
+    static Stream<Arguments> validTasks() throws Exception {
         return Stream.of(
             Arguments.of(new Created(AGGREGATE_ID, EVENT_ID, TASK, HOSTNAME), "{\"task\":\"{\\\"type\\\":\\\"completed-task\\\"}\",\"type\":\"task-manager-created\",\"aggregate\":\"2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd\",\"event\":42,\"hostname\":\"foo\"}\n"),
             Arguments.of(new Started(AGGREGATE_ID, EVENT_ID, HOSTNAME), "{\"aggregate\":\"2c7f4081-aa30-11e9-bf6c-2d3b9e84aafd\",\"event\":42,\"type\":\"task-manager-started\",\"hostname\":\"foo\"}"),
@@ -97,10 +98,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(counterAdditionalInformation)), "{\"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(counterAdditionalInformation)), "{\"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(counterAdditionalInformation), 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(counterAdditionalInformation)), "{\"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\\\"}\"}")
         );
     }
 


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


[james-project] 24/41: JAMES-2813 DTO <-> domain object must be a bijection for jackson to work

Posted by bt...@apache.org.
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 ec1edc03651d53772f4966a437699155578b49b0
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Wed Oct 23 14:31:39 2019 +0200

    JAMES-2813 DTO <-> domain object must be a bijection for jackson to work
    
    	Reference: https://github.com/FasterXML/jackson-databind/issues/2515
---
 .../indexer/ReprocessingContextInformationDTO.java | 46 ++++++++++---
 ...tersRedeliveryTaskAdditionalInformationDTO.java | 78 ++++++++++++++++------
 2 files changed, 94 insertions(+), 30 deletions(-)

diff --git a/mailbox/tools/indexer/src/main/java/org/apache/mailbox/tools/indexer/ReprocessingContextInformationDTO.java b/mailbox/tools/indexer/src/main/java/org/apache/mailbox/tools/indexer/ReprocessingContextInformationDTO.java
index 3ee9c7f..9172e98 100644
--- a/mailbox/tools/indexer/src/main/java/org/apache/mailbox/tools/indexer/ReprocessingContextInformationDTO.java
+++ b/mailbox/tools/indexer/src/main/java/org/apache/mailbox/tools/indexer/ReprocessingContextInformationDTO.java
@@ -58,15 +58,27 @@ public class ReprocessingContextInformationDTO implements AdditionalInformationD
     }
 
     public static class ReprocessingContextInformationForErrorRecoveryIndexationTask extends ReprocessingContextInformation {
-        public static final AdditionalInformationDTOModule<ReprocessingContextInformationForErrorRecoveryIndexationTask, ReprocessingContextInformationDTO> serializationModule(MailboxId.Factory mailboxIdFactory) {
+
+        public static class DTO extends ReprocessingContextInformationDTO {
+
+            DTO(@JsonProperty("type") String type,
+                @JsonProperty("successfullyReprocessedMailCount") int successfullyReprocessedMailCount,
+                @JsonProperty("failedReprocessedMailCount") int failedReprocessedMailCount,
+                @JsonProperty("failures") List<ReindexingFailureDTO> failures,
+                @JsonProperty("timestamp") Instant timestamp) {
+                super(type, successfullyReprocessedMailCount, failedReprocessedMailCount, failures, timestamp);
+            }
+        }
+
+        public static final AdditionalInformationDTOModule<ReprocessingContextInformationForErrorRecoveryIndexationTask, DTO> serializationModule(MailboxId.Factory mailboxIdFactory) {
             return DTOModule.forDomainObject(ReprocessingContextInformationForErrorRecoveryIndexationTask.class)
-                .convertToDTO(ReprocessingContextInformationDTO.class)
+                .convertToDTO(DTO.class)
                 .toDomainObjectConverter(dto -> new ReprocessingContextInformationForErrorRecoveryIndexationTask(
                     dto.successfullyReprocessedMailCount,
                     dto.failedReprocessedMailCount,
                     deserializeFailures(mailboxIdFactory, dto.failures),
                     dto.getTimestamp()))
-                .toDTOConverter((details, type) -> new ReprocessingContextInformationDTO(
+                .toDTOConverter((details, type) -> new DTO(
                     type,
                     details.getSuccessfullyReprocessedMailCount(),
                     details.getFailedReprocessedMailCount(),
@@ -82,11 +94,23 @@ public class ReprocessingContextInformationDTO implements AdditionalInformationD
     }
 
     public static class ReprocessingContextInformationForFullReindexingTask extends ReprocessingContextInformation {
-        public static final AdditionalInformationDTOModule<ReprocessingContextInformationForFullReindexingTask, ReprocessingContextInformationDTO> serializationModule(MailboxId.Factory mailboxIdFactory) {
+
+        public static class DTO extends ReprocessingContextInformationDTO {
+
+            DTO(@JsonProperty("type") String type,
+                @JsonProperty("successfullyReprocessedMailCount") int successfullyReprocessedMailCount,
+                @JsonProperty("failedReprocessedMailCount") int failedReprocessedMailCount,
+                @JsonProperty("failures") List<ReindexingFailureDTO> failures,
+                @JsonProperty("timestamp") Instant timestamp) {
+                super(type, successfullyReprocessedMailCount, failedReprocessedMailCount, failures, timestamp);
+            }
+        }
+
+        public static final AdditionalInformationDTOModule<ReprocessingContextInformationForFullReindexingTask, DTO> serializationModule(MailboxId.Factory mailboxIdFactory) {
             return DTOModule.forDomainObject(ReprocessingContextInformationForFullReindexingTask.class)
-                .convertToDTO(ReprocessingContextInformationDTO.class)
+                .convertToDTO(DTO.class)
                 .toDomainObjectConverter(dto -> new ReprocessingContextInformationForFullReindexingTask(dto.successfullyReprocessedMailCount, dto.failedReprocessedMailCount, deserializeFailures(mailboxIdFactory, dto.failures), dto.getTimestamp()))
-                .toDTOConverter((details, type) -> new ReprocessingContextInformationDTO(
+                .toDTOConverter((details, type) -> new DTO(
                     type,
                     details.getSuccessfullyReprocessedMailCount(),
                     details.getFailedReprocessedMailCount(),
@@ -144,11 +168,11 @@ public class ReprocessingContextInformationDTO implements AdditionalInformationD
             .collect(Guavate.toImmutableList());
     }
 
-    private final String type;
-    private final int successfullyReprocessedMailCount;
-    private final int failedReprocessedMailCount;
-    private final List<ReindexingFailureDTO> failures;
-    private final Instant timestamp;
+    protected final String type;
+    protected final int successfullyReprocessedMailCount;
+    protected final int failedReprocessedMailCount;
+    protected final List<ReindexingFailureDTO> failures;
+    protected final Instant timestamp;
 
 
     ReprocessingContextInformationDTO(@JsonProperty("type") String type,
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/EventDeadLettersRedeliveryTaskAdditionalInformationDTO.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/EventDeadLettersRedeliveryTaskAdditionalInformationDTO.java
index 46dce06..552aa8b 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/EventDeadLettersRedeliveryTaskAdditionalInformationDTO.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/EventDeadLettersRedeliveryTaskAdditionalInformationDTO.java
@@ -14,12 +14,29 @@ import com.github.fge.lambdas.Throwing;
 
 public class EventDeadLettersRedeliveryTaskAdditionalInformationDTO implements AdditionalInformationDTO {
     public static class EventDeadLettersRedeliveryTaskAdditionalInformationForAll extends EventDeadLettersRedeliveryTaskAdditionalInformation {
-        public static final AdditionalInformationDTOModule<EventDeadLettersRedeliveryTaskAdditionalInformationForAll, EventDeadLettersRedeliveryTaskAdditionalInformationDTO> MODULE =
+
+        public static class DTO extends EventDeadLettersRedeliveryTaskAdditionalInformationDTO {
+            public DTO(@JsonProperty("type") String type,
+                       @JsonProperty("successfulRedeliveriesCount") long successfulRedeliveriesCount,
+                       @JsonProperty("failedRedeliveriesCount") long failedRedeliveriesCount,
+                       @JsonProperty("group") Optional<String> group,
+                       @JsonProperty("insertionId") Optional<String> insertionId,
+                       @JsonProperty("timestamp") Instant timestamp) {
+                super(type, successfulRedeliveriesCount, failedRedeliveriesCount, group,insertionId, timestamp);
+            }
+        }
+
+        public static final AdditionalInformationDTOModule<EventDeadLettersRedeliveryTaskAdditionalInformationForAll, DTO> MODULE =
             DTOModule
                 .forDomainObject(EventDeadLettersRedeliveryTaskAdditionalInformationForAll.class)
-                .convertToDTO(EventDeadLettersRedeliveryTaskAdditionalInformationDTO.class)
+                .convertToDTO(DTO.class)
                 .toDomainObjectConverter(EventDeadLettersRedeliveryTaskAdditionalInformationDTO::fromAll)
-                .toDTOConverter(EventDeadLettersRedeliveryTaskAdditionalInformationDTO::toDTO)
+                .toDTOConverter((domainObject, typeName) -> new DTO(typeName,
+                    domainObject.getSuccessfulRedeliveriesCount(),
+                    domainObject.getFailedRedeliveriesCount(),
+                    domainObject.getGroup(),
+                    domainObject.getInsertionId(),
+                    domainObject.timestamp()))
                 .typeName(EventDeadLettersRedeliverAllTask.TYPE.asString())
                 .withFactory(AdditionalInformationDTOModule::new);
 
@@ -30,12 +47,29 @@ public class EventDeadLettersRedeliveryTaskAdditionalInformationDTO implements A
     }
 
     public static class EventDeadLettersRedeliveryTaskAdditionalInformationForGroup extends EventDeadLettersRedeliveryTaskAdditionalInformation {
-        public static final AdditionalInformationDTOModule<EventDeadLettersRedeliveryTaskAdditionalInformationForGroup, EventDeadLettersRedeliveryTaskAdditionalInformationDTO> MODULE =
+
+        public static class DTO extends EventDeadLettersRedeliveryTaskAdditionalInformationDTO {
+            public DTO(@JsonProperty("type") String type,
+                       @JsonProperty("successfulRedeliveriesCount") long successfulRedeliveriesCount,
+                       @JsonProperty("failedRedeliveriesCount") long failedRedeliveriesCount,
+                       @JsonProperty("group") Optional<String> group,
+                       @JsonProperty("insertionId") Optional<String> insertionId,
+                       @JsonProperty("timestamp") Instant timestamp) {
+                super(type, successfulRedeliveriesCount, failedRedeliveriesCount, group,insertionId, timestamp);
+            }
+        }
+
+        public static final AdditionalInformationDTOModule<EventDeadLettersRedeliveryTaskAdditionalInformationForGroup, DTO> MODULE =
             DTOModule
                 .forDomainObject(EventDeadLettersRedeliveryTaskAdditionalInformationForGroup.class)
-                .convertToDTO(EventDeadLettersRedeliveryTaskAdditionalInformationDTO.class)
+                .convertToDTO(DTO.class)
                 .toDomainObjectConverter(EventDeadLettersRedeliveryTaskAdditionalInformationDTO::fromGroup)
-                .toDTOConverter(EventDeadLettersRedeliveryTaskAdditionalInformationDTO::toDTO)
+                .toDTOConverter((domainObject, typeName) -> new DTO(typeName,
+                    domainObject.getSuccessfulRedeliveriesCount(),
+                    domainObject.getFailedRedeliveriesCount(),
+                    domainObject.getGroup(),
+                    domainObject.getInsertionId(),
+                    domainObject.timestamp()))
                 .typeName(EventDeadLettersRedeliverGroupTask.TYPE.asString())
                 .withFactory(AdditionalInformationDTOModule::new);
 
@@ -46,12 +80,28 @@ public class EventDeadLettersRedeliveryTaskAdditionalInformationDTO implements A
     }
 
     public static class EventDeadLettersRedeliveryTaskAdditionalInformationForOne extends EventDeadLettersRedeliveryTaskAdditionalInformation {
-        public static final AdditionalInformationDTOModule<EventDeadLettersRedeliveryTaskAdditionalInformationForOne, EventDeadLettersRedeliveryTaskAdditionalInformationDTO> MODULE =
+        public static class DTO extends EventDeadLettersRedeliveryTaskAdditionalInformationDTO {
+            public DTO(@JsonProperty("type") String type,
+                       @JsonProperty("successfulRedeliveriesCount") long successfulRedeliveriesCount,
+                       @JsonProperty("failedRedeliveriesCount") long failedRedeliveriesCount,
+                       @JsonProperty("group") Optional<String> group,
+                       @JsonProperty("insertionId") Optional<String> insertionId,
+                       @JsonProperty("timestamp") Instant timestamp) {
+                super(type, successfulRedeliveriesCount, failedRedeliveriesCount, group,insertionId, timestamp);
+            }
+        }
+
+        public static final AdditionalInformationDTOModule<EventDeadLettersRedeliveryTaskAdditionalInformationForOne, DTO> MODULE =
             DTOModule
                 .forDomainObject(EventDeadLettersRedeliveryTaskAdditionalInformationForOne.class)
-                .convertToDTO(EventDeadLettersRedeliveryTaskAdditionalInformationDTO.class)
+                .convertToDTO(DTO.class)
                 .toDomainObjectConverter(EventDeadLettersRedeliveryTaskAdditionalInformationDTO::fromOne)
-                .toDTOConverter(EventDeadLettersRedeliveryTaskAdditionalInformationDTO::toDTO)
+                .toDTOConverter((domainObject, typeName) -> new DTO(typeName,
+                    domainObject.getSuccessfulRedeliveriesCount(),
+                    domainObject.getFailedRedeliveriesCount(),
+                    domainObject.getGroup(),
+                    domainObject.getInsertionId(),
+                    domainObject.timestamp()))
                 .typeName(EventDeadLettersRedeliverOneTask.TYPE.asString())
                 .withFactory(AdditionalInformationDTOModule::new);
 
@@ -66,16 +116,6 @@ public class EventDeadLettersRedeliveryTaskAdditionalInformationDTO implements A
         }
     }
 
-    private static EventDeadLettersRedeliveryTaskAdditionalInformationDTO toDTO(EventDeadLettersRedeliveryTaskAdditionalInformation domainObject, String typeName) {
-        return new EventDeadLettersRedeliveryTaskAdditionalInformationDTO(
-            typeName,
-            domainObject.getSuccessfulRedeliveriesCount(),
-            domainObject.getFailedRedeliveriesCount(),
-            domainObject.getGroup(),
-            domainObject.getInsertionId(),
-            domainObject.timestamp());
-    }
-
     private static EventDeadLettersRedeliveryTaskAdditionalInformationForAll fromAll(EventDeadLettersRedeliveryTaskAdditionalInformationDTO dto) {
         return new EventDeadLettersRedeliveryTaskAdditionalInformationForAll(
             dto.successfulRedeliveriesCount,


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


[james-project] 40/41: JAMES-2949 Remove FIXME-USERNAME annotations by using lower case comparison

Posted by bt...@apache.org.
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 3b1fc18f230982122d6cff68f62dd2f3c3f4e655
Author: Raphael Ouazana <ra...@linagora.com>
AuthorDate: Tue Nov 19 17:09:45 2019 +0100

    JAMES-2949 Remove FIXME-USERNAME annotations by using lower case comparison
---
 .../main/java/org/apache/james/core/Username.java  | 11 +++++
 .../java/org/apache/james/core/UsernameTest.java   | 48 ++++++++++++++++++++++
 .../apache/james/mailbox/model/MailboxPath.java    |  2 +-
 .../james/transport/mailets/AbstractSign.java      |  2 +-
 .../mailets/delivery/SimpleMailStore.java          |  2 +-
 .../SenderAuthIdentifyVerificationRcptHook.java    |  7 +---
 6 files changed, 63 insertions(+), 9 deletions(-)

diff --git a/core/src/main/java/org/apache/james/core/Username.java b/core/src/main/java/org/apache/james/core/Username.java
index 308bc69..73e6aaf 100644
--- a/core/src/main/java/org/apache/james/core/Username.java
+++ b/core/src/main/java/org/apache/james/core/Username.java
@@ -125,6 +125,17 @@ public class Username {
         return asString().toLowerCase(Locale.US);
     }
 
+    public boolean equalsAsId(String otherId) {
+        if (otherId == null) {
+            return false;
+        }
+        return asId().equals(otherId.toLowerCase(Locale.US));
+    }
+
+    public boolean equalsAsId(Username otherId) {
+        return asId().equals(otherId.asId());
+    }
+
     public MailAddress asMailAddress() throws AddressException {
         Preconditions.checkState(hasDomainPart());
         return new MailAddress(localPart, domainPart.get());
diff --git a/core/src/test/java/org/apache/james/core/UsernameTest.java b/core/src/test/java/org/apache/james/core/UsernameTest.java
index 8fe63d1..8d49880 100644
--- a/core/src/test/java/org/apache/james/core/UsernameTest.java
+++ b/core/src/test/java/org/apache/james/core/UsernameTest.java
@@ -242,4 +242,52 @@ class UsernameTest {
             .withDefaultDomainFromUser(Username.of("bob")))
             .isEqualTo(Username.of("user"));
     }
+
+    @Test
+    void equalsAsIdShouldReturnFalseWhenNull() {
+        assertThat(Username.of("user").equalsAsId((String)null))
+            .isFalse();
+    }
+
+    @Test
+    void equalsAsIdShouldReturnFalseWhenDifferentId() {
+        assertThat(Username.of("user").equalsAsId("user2"))
+            .isFalse();
+    }
+
+    @Test
+    void equalsAsIdShouldReturnTrueWhenSameId() {
+        assertThat(Username.of("user").equalsAsId("user"))
+            .isTrue();
+    }
+
+    @Test
+    void equalsAsIdShouldReturnTrueWhenSameIdWithDifferentCase() {
+        assertThat(Username.of("user").equalsAsId("uSEr"))
+            .isTrue();
+    }
+
+    @Test
+    void equalsAsIdForUsernameShouldThrowWhenNull() {
+        assertThatThrownBy(() -> Username.of("user").equalsAsId((Username)null))
+            .isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    void equalsAsIdForUsernameShouldReturnFalseWhenDifferentId() {
+        assertThat(Username.of("user").equalsAsId(Username.of("user2")))
+            .isFalse();
+    }
+
+    @Test
+    void equalsAsIdForUsernameShouldReturnTrueWhenSameId() {
+        assertThat(Username.of("user").equalsAsId(Username.of("user")))
+            .isTrue();
+    }
+
+    @Test
+    void equalsAsIdForUsernameShouldReturnTrueWhenSameIdWithDifferentCase() {
+        assertThat(Username.of("user").equalsAsId(Username.of("uSEr")))
+            .isTrue();
+    }
 }
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxPath.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxPath.java
index 5edc9b1..458000e 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxPath.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxPath.java
@@ -101,7 +101,7 @@ public class MailboxPath {
     }
 
     public boolean belongsTo(MailboxSession mailboxSession) {
-        return user.asString().equalsIgnoreCase(mailboxSession.getUser().asString());//FIXME-USERNAME
+        return user.equalsAsId(mailboxSession.getUser());
     }
 
     /**
diff --git a/mailet/crypto/src/main/java/org/apache/james/transport/mailets/AbstractSign.java b/mailet/crypto/src/main/java/org/apache/james/transport/mailets/AbstractSign.java
index d8f0dc6..5a643e1 100644
--- a/mailet/crypto/src/main/java/org/apache/james/transport/mailets/AbstractSign.java
+++ b/mailet/crypto/src/main/java/org/apache/james/transport/mailets/AbstractSign.java
@@ -586,7 +586,7 @@ public abstract class AbstractSign extends GenericMailet {
         } else {
             // is the reverse-path user different from the SMTP authorized user?
             Username username = getUsername(reversePath);
-            if (!username.asString().equals(authUser)) { //FIXME-USERNAME
+            if (!username.equalsAsId(authUser)) {
                 LOGGER.info("SMTP logged in as <{}> but pretend to be sender <{}>", authUser, username);
                 return false;
             }
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SimpleMailStore.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SimpleMailStore.java
index 82f671e..45f9f08 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SimpleMailStore.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SimpleMailStore.java
@@ -104,7 +104,7 @@ public class SimpleMailStore implements MailStore {
 
     private String locateFolder(Username username, Mail mail) {
         return AttributeUtils
-            .getValueAndCastFromMail(mail, AttributeName.of(DELIVERY_PATH_PREFIX + username.asString()), String.class) //FIXME-USERNAME
+            .getValueAndCastFromMail(mail, AttributeName.of(DELIVERY_PATH_PREFIX + username.asId()), String.class)
             .orElse(folder);
     }
 
diff --git a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/SenderAuthIdentifyVerificationRcptHook.java b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/SenderAuthIdentifyVerificationRcptHook.java
index 5ed3567..74e1953 100644
--- a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/SenderAuthIdentifyVerificationRcptHook.java
+++ b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/SenderAuthIdentifyVerificationRcptHook.java
@@ -18,9 +18,6 @@
  ****************************************************************/
 package org.apache.james.smtpserver;
 
-import java.text.Collator;
-import java.util.Locale;
-
 import javax.inject.Inject;
 
 import org.apache.james.core.Domain;
@@ -78,8 +75,6 @@ public class SenderAuthIdentifyVerificationRcptHook extends AbstractSenderAuthId
 
     @Override
     protected boolean isSenderAllowed(Username user, Username sender) {
-        Collator collator = Collator.getInstance(Locale.US);
-        collator.setStrength(Collator.PRIMARY);
-        return collator.compare(user.asString(), sender.asString()) == 0; //FIXME-USERNAME
+        return user.equalsAsId(sender);
     }
 }


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


[james-project] 01/41: Changelog for recent ElasticSearch changes

Posted by bt...@apache.org.
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 016ef250d083960354d3137640a3692285dc2863
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Nov 1 17:59:07 2019 +0700

    Changelog for recent ElasticSearch changes
---
 CHANGELOG.md            | 3 +++
 upgrade-instructions.md | 7 +++++++
 2 files changed, 10 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index e10d720..97d3e99 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 ### Changed
 - Multiple changes have been made to enhance ElasticSearch performance:
   - Use of routing keys to collocate documents per mailbox
+  - Under some configuration, html was not extracted before document indexing
+  - Removed unnecessary fields from mailbox mapping
+  - Disable dynamic mapping thanks to a change of the header structure 
   - Read related [upgrade instructions](upgrade-instructions.md)
 
 ### Removed
diff --git a/upgrade-instructions.md b/upgrade-instructions.md
index 53e745c..0566952 100644
--- a/upgrade-instructions.md
+++ b/upgrade-instructions.md
@@ -40,6 +40,9 @@ SHA-1 0d72783ff4
 
 JIRAS:
  - https://issues.apache.org/jira/browse/JAMES-2917
+ - https://issues.apache.org/jira/browse/JAMES-2078
+ - https://issues.apache.org/jira/browse/JAMES-2079
+ - https://issues.apache.org/jira/browse/JAMES-2910
 
 Concerned product: Guice product relying on ElasticSearch
 
@@ -47,6 +50,10 @@ We significantly improved our usage of ElasticSearch. Underlying changes include
 
  - The use of routing to collocate emails of a same mailbox within a same shard. This enables search queries to avoid cluster
  level synchronisation, and thus enhance throughput, latencies and scalability.
+ - Disabling dynamic mapping. We now represent headers as nested objects.
+ - Removing some not needed fields from the mapping
+ - No longer index raw HTML. This was possible under some configuration combinaison, and caused the data stored in elasticSearch
+ to be significantly larger than required.
 
 The downside of these changes is that a reindex is needed, implying a downtime on search:
  - Delete the indexes used by James


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


[james-project] 04/41: Add some items contributed since last release

Posted by bt...@apache.org.
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 772275cd3ca561ea242c0785c874cb79a151386a
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue Nov 5 11:07:44 2019 +0700

    Add some items contributed since last release
---
 CHANGELOG.md | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1f9241c..a116a55 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 ### Added
 - Distributed task management for Guice cassandra-rabbitmq product. This enables two James servers to share a consistent view
 of tasks being currently executed.
+- JAMES-2563 Health check for ElasticSearch
 
 ### Changed
 - Multiple changes have been made to enhance ElasticSearch performance:
@@ -27,6 +28,10 @@ of tasks being currently executed.
 - JAMES-2957 dlp.Dlp matcher should parse emails containing attachments
 - JAMES-2958 Limit domain name size to not longer than 255 characters
 - JAMES-2939 Prevent mixed case INBOX creation
+- JAMES-2903 Rework default LOG4J log file for Spring
+- JAMES-2739 fixed browse mails from queue over JMX
+- JAMES-2375 DSNBounce mailet should provide a subject
+- JAMES-2097 RemoteDelivery: Avoid retrying already succeeded recipients when sendPartial
 
 ### Removed
 - Classes marked as deprecated whose removal was planned after 3.4.0 release (See JAMES-2703). This includes:


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


[james-project] 33/41: JAMES-2979 fix delivery runnable mail dequeue

Posted by bt...@apache.org.
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 bce3f3839f788517f25580618f8c0e9980641773
Author: Rémi KOWALSKI <rk...@linagora.com>
AuthorDate: Thu Nov 14 14:02:03 2019 +0100

    JAMES-2979 fix delivery runnable mail dequeue
---
 .../james/transport/mailets/remote/delivery/DeliveryRunnable.java      | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/DeliveryRunnable.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/DeliveryRunnable.java
index 1699174..a6d92d0 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/DeliveryRunnable.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/DeliveryRunnable.java
@@ -84,8 +84,7 @@ public class DeliveryRunnable implements Disposable {
     public void start() {
         remoteDeliveryScheduler = Schedulers.newBoundedElastic(Schedulers.DEFAULT_BOUNDED_ELASTIC_SIZE, Schedulers.DEFAULT_BOUNDED_ELASTIC_QUEUESIZE, "RemoteDelivery");
         disposable = Flux.from(queue.deQueue())
-            .publishOn(remoteDeliveryScheduler)
-            .flatMap(this::runStep)
+            .flatMap(queueItem -> runStep(queueItem).subscribeOn(remoteDeliveryScheduler))
             .onErrorContinue(((throwable, nothing) -> LOGGER.error("Exception caught in RemoteDelivery", throwable)))
             .subscribeOn(remoteDeliveryScheduler)
             .subscribe();


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


[james-project] 39/41: [Refactoring] Refactor james-server-util test classes with correct access modifiers

Posted by bt...@apache.org.
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 40a00cbd695643a15636e48924fd38996c46dc60
Author: Rene Cordier <rc...@linagora.com>
AuthorDate: Tue Nov 19 17:04:55 2019 +0700

    [Refactoring] Refactor james-server-util test classes with correct access modifiers
---
 .../org/apache/james/util/BodyOffsetInputStreamTest.java     |  2 +-
 .../java/org/apache/james/util/CommutativityCheckerTest.java |  2 +-
 .../src/test/java/org/apache/james/util/GuavaUtilsTest.java  |  2 +-
 .../util/src/test/java/org/apache/james/util/HostTest.java   |  2 +-
 .../test/java/org/apache/james/util/IteratorWrapperTest.java |  2 +-
 .../test/java/org/apache/james/util/LoggingLevelTest.java    | 12 ++++++------
 .../src/test/java/org/apache/james/util/MDCBuilderTest.java  |  2 +-
 .../test/java/org/apache/james/util/OptionalUtilsTest.java   |  4 ++--
 .../util/src/test/java/org/apache/james/util/PortTest.java   |  2 +-
 .../src/test/java/org/apache/james/util/SizeFormatTest.java  |  2 +-
 .../util/src/test/java/org/apache/james/util/SizeTest.java   |  2 +-
 .../src/test/java/org/apache/james/util/StreamUtilsTest.java |  2 +-
 .../src/test/java/org/apache/james/util/ValuePatchTest.java  | 10 +++++-----
 .../james/util/concurrency/ConcurrentTestRunnerTest.java     |  6 +++---
 .../apache/james/util/date/ImapDateTimeFormatterTest.java    |  2 +-
 .../apache/james/util/mime/MessageContentExtractorTest.java  |  2 +-
 .../apache/james/util/retry/DoublingRetryScheduleTest.java   |  2 +-
 .../apache/james/util/retry/ExceptionRetryHandlerTest.java   |  2 +-
 .../util/retry/naming/NamingExceptionRetryHandlerTest.java   |  2 +-
 .../apache/james/util/streams/ImmutableCollectorsTest.java   |  2 +-
 .../java/org/apache/james/util/streams/IteratorsTest.java    |  2 +-
 .../test/java/org/apache/james/util/streams/LimitTest.java   |  2 +-
 .../test/java/org/apache/james/util/streams/OffsetTest.java  |  2 +-
 23 files changed, 35 insertions(+), 35 deletions(-)

diff --git a/server/container/util/src/test/java/org/apache/james/util/BodyOffsetInputStreamTest.java b/server/container/util/src/test/java/org/apache/james/util/BodyOffsetInputStreamTest.java
index cf3a09e..de5ca13 100644
--- a/server/container/util/src/test/java/org/apache/james/util/BodyOffsetInputStreamTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/BodyOffsetInputStreamTest.java
@@ -25,7 +25,7 @@ import java.io.IOException;
 
 import org.junit.jupiter.api.Test;
 
-public class BodyOffsetInputStreamTest {
+class BodyOffsetInputStreamTest {
     private String mail = "Subject: test\r\n\r\nbody";
     private long expectedOffset = 17;
     private long bytes = mail.length();
diff --git a/server/container/util/src/test/java/org/apache/james/util/CommutativityCheckerTest.java b/server/container/util/src/test/java/org/apache/james/util/CommutativityCheckerTest.java
index 3561c0a..7b999bb 100644
--- a/server/container/util/src/test/java/org/apache/james/util/CommutativityCheckerTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/CommutativityCheckerTest.java
@@ -30,7 +30,7 @@ import org.junit.jupiter.api.Test;
 
 import com.google.common.collect.ImmutableSet;
 
-public class CommutativityCheckerTest {
+class CommutativityCheckerTest {
     @Test
     void constructorShouldThrowWhenNullValuesToTest() {
         BinaryOperator<Integer> binaryOperator = (a, b) -> a * a + b;
diff --git a/server/container/util/src/test/java/org/apache/james/util/GuavaUtilsTest.java b/server/container/util/src/test/java/org/apache/james/util/GuavaUtilsTest.java
index 5b2ec4d..6943b63 100644
--- a/server/container/util/src/test/java/org/apache/james/util/GuavaUtilsTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/GuavaUtilsTest.java
@@ -29,7 +29,7 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableListMultimap;
 import com.google.common.collect.ImmutableMap;
 
-public class GuavaUtilsTest {
+class GuavaUtilsTest {
 
     @Test
     void toMultimapShouldAcceptEmptyMaps() {
diff --git a/server/container/util/src/test/java/org/apache/james/util/HostTest.java b/server/container/util/src/test/java/org/apache/james/util/HostTest.java
index 2052b5e..290b3e4 100644
--- a/server/container/util/src/test/java/org/apache/james/util/HostTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/HostTest.java
@@ -28,7 +28,7 @@ import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
 
-public class HostTest {
+class HostTest {
 
     private static final int DEFAULT_PORT = 154;
 
diff --git a/server/container/util/src/test/java/org/apache/james/util/IteratorWrapperTest.java b/server/container/util/src/test/java/org/apache/james/util/IteratorWrapperTest.java
index 687f7b7..44a9714 100644
--- a/server/container/util/src/test/java/org/apache/james/util/IteratorWrapperTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/IteratorWrapperTest.java
@@ -26,7 +26,7 @@ import org.junit.jupiter.api.Test;
 
 import com.google.common.collect.ImmutableList;
 
-public class IteratorWrapperTest {
+class IteratorWrapperTest {
 
     @Test
     void getEntriesSeenShouldReturnEmptyWhenNotConsumed() {
diff --git a/server/container/util/src/test/java/org/apache/james/util/LoggingLevelTest.java b/server/container/util/src/test/java/org/apache/james/util/LoggingLevelTest.java
index dfb5fc0..e6f3060 100644
--- a/server/container/util/src/test/java/org/apache/james/util/LoggingLevelTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/LoggingLevelTest.java
@@ -25,37 +25,37 @@ import static org.mockito.Mockito.verify;
 import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 
-public class LoggingLevelTest {
+class LoggingLevelTest {
     @Test
-    public void formatShouldCallDebugWhenDebugLevelIsGiven() {
+    void formatShouldCallDebugWhenDebugLevelIsGiven() {
         Logger logger = mock(Logger.class);
         LoggingLevel.DEBUG.format(logger, "easy as {} {} {}", 1, 2.0, "3");
         verify(logger).debug("easy as {} {} {}", 1, 2.0, "3");
     }
 
     @Test
-    public void formatShouldCallErrorWhenErrorLevelIsGiven() {
+    void formatShouldCallErrorWhenErrorLevelIsGiven() {
         Logger logger = mock(Logger.class);
         LoggingLevel.ERROR.format(logger, "easy as {} {} {}", 1, 2.0, "3");
         verify(logger).error("easy as {} {} {}", 1, 2.0, "3");
     }
 
     @Test
-    public void formatShouldCallInfoWhenInfoLevelIsGiven() {
+    void formatShouldCallInfoWhenInfoLevelIsGiven() {
         Logger logger = mock(Logger.class);
         LoggingLevel.INFO.format(logger, "easy as {} {} {}", 1, 2.0, "3");
         verify(logger).info("easy as {} {} {}", 1, 2.0, "3");
     }
 
     @Test
-    public void formatShouldCallTraceWhenTraceLevelIsGiven() {
+    void formatShouldCallTraceWhenTraceLevelIsGiven() {
         Logger logger = mock(Logger.class);
         LoggingLevel.TRACE.format(logger, "easy as {} {} {}", 1, 2.0, "3");
         verify(logger).trace("easy as {} {} {}", 1, 2.0, "3");
     }
 
     @Test
-    public void formatShouldCallWarningWhenWarningLevelIsGiven() {
+    void formatShouldCallWarningWhenWarningLevelIsGiven() {
         Logger logger = mock(Logger.class);
         LoggingLevel.WARNING.format(logger, "easy as {} {} {}", 1, 2.0, "3");
         verify(logger).warn("easy as {} {} {}", 1, 2.0, "3");
diff --git a/server/container/util/src/test/java/org/apache/james/util/MDCBuilderTest.java b/server/container/util/src/test/java/org/apache/james/util/MDCBuilderTest.java
index 02494a8..af47acb 100644
--- a/server/container/util/src/test/java/org/apache/james/util/MDCBuilderTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/MDCBuilderTest.java
@@ -29,7 +29,7 @@ import org.junit.jupiter.api.Test;
 
 import com.google.common.collect.ImmutableList;
 
-public class MDCBuilderTest {
+class MDCBuilderTest {
 
     private static final String KEY_1 = "key1";
     private static final String KEY_2 = "key2";
diff --git a/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java b/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java
index 8d750b9..c80bafe 100644
--- a/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java
@@ -25,7 +25,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import org.junit.jupiter.api.Test;
 
-public class OptionalUtilsTest {
+class OptionalUtilsTest {
 
     @Test
     void ifEmptyShouldPreserveValueOfEmptyOptionals() {
@@ -215,7 +215,7 @@ public class OptionalUtilsTest {
     }
 
     @Test
-    void containsDifferentShouldReturnFalseWhenEmpty() throws Exception {
+    void containsDifferentShouldReturnFalseWhenEmpty() {
         assertThat(OptionalUtils.containsDifferent(Optional.empty(), "any")).isFalse();
     }
 
diff --git a/server/container/util/src/test/java/org/apache/james/util/PortTest.java b/server/container/util/src/test/java/org/apache/james/util/PortTest.java
index 7e2c129..793c162 100644
--- a/server/container/util/src/test/java/org/apache/james/util/PortTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/PortTest.java
@@ -24,7 +24,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import org.junit.jupiter.api.Test;
 
-public class PortTest {
+class PortTest {
     @Test
     void assertValidShouldThrowOnNegativePort() {
         assertThatThrownBy(() -> Port.assertValid(-1))
diff --git a/server/container/util/src/test/java/org/apache/james/util/SizeFormatTest.java b/server/container/util/src/test/java/org/apache/james/util/SizeFormatTest.java
index ef492a4..03c5a24 100644
--- a/server/container/util/src/test/java/org/apache/james/util/SizeFormatTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/SizeFormatTest.java
@@ -24,7 +24,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import org.junit.jupiter.api.Test;
 
-public class SizeFormatTest {
+class SizeFormatTest {
 
     @Test
     void formatShouldThrowWhenNegative() {
diff --git a/server/container/util/src/test/java/org/apache/james/util/SizeTest.java b/server/container/util/src/test/java/org/apache/james/util/SizeTest.java
index 7afdf56..0392a63 100644
--- a/server/container/util/src/test/java/org/apache/james/util/SizeTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/SizeTest.java
@@ -24,7 +24,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import org.junit.jupiter.api.Test;
 
-public class SizeTest {
+class SizeTest {
 
     @Test
     void testNoUnit() throws Exception {
diff --git a/server/container/util/src/test/java/org/apache/james/util/StreamUtilsTest.java b/server/container/util/src/test/java/org/apache/james/util/StreamUtilsTest.java
index 75f2526..e08ebea 100644
--- a/server/container/util/src/test/java/org/apache/james/util/StreamUtilsTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/StreamUtilsTest.java
@@ -29,7 +29,7 @@ import org.junit.jupiter.api.Test;
 import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableList;
 
-public class StreamUtilsTest {
+class StreamUtilsTest {
 
     @Test
     void flattenShouldReturnEmptyWhenEmptyStreams() {
diff --git a/server/container/util/src/test/java/org/apache/james/util/ValuePatchTest.java b/server/container/util/src/test/java/org/apache/james/util/ValuePatchTest.java
index 07144f0..115da14 100644
--- a/server/container/util/src/test/java/org/apache/james/util/ValuePatchTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/ValuePatchTest.java
@@ -27,12 +27,12 @@ import java.util.Optional;
 
 import org.junit.jupiter.api.Test;
 
-public class ValuePatchTest {
+class ValuePatchTest {
 
-    public static final int REPLACEMENT_VALUE = 24;
-    public static final Optional<Integer> REPLACEMENT = Optional.of(REPLACEMENT_VALUE);
-    public static final int VALUE = 12;
-    public static final Optional<Integer> OPTIONAL_OF_VALUE = Optional.of(VALUE);
+    private static final int REPLACEMENT_VALUE = 24;
+    private static final Optional<Integer> REPLACEMENT = Optional.of(REPLACEMENT_VALUE);
+    private static final int VALUE = 12;
+    private static final Optional<Integer> OPTIONAL_OF_VALUE = Optional.of(VALUE);
 
     @Test
     void keepShouldProduceKeptValues() {
diff --git a/server/container/util/src/test/java/org/apache/james/util/concurrency/ConcurrentTestRunnerTest.java b/server/container/util/src/test/java/org/apache/james/util/concurrency/ConcurrentTestRunnerTest.java
index 7a4afc0..b40077e 100644
--- a/server/container/util/src/test/java/org/apache/james/util/concurrency/ConcurrentTestRunnerTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/concurrency/ConcurrentTestRunnerTest.java
@@ -32,9 +32,9 @@ import java.util.concurrent.TimeUnit;
 
 import org.junit.jupiter.api.Test;
 
-public class ConcurrentTestRunnerTest {
-    public static final ConcurrentTestRunner.ConcurrentOperation NOOP = (threadNumber, step) -> { };
-    public static final Duration DEFAULT_AWAIT_TIME = Duration.ofMillis(100);
+class ConcurrentTestRunnerTest {
+    private static final ConcurrentTestRunner.ConcurrentOperation NOOP = (threadNumber, step) -> { };
+    private static final Duration DEFAULT_AWAIT_TIME = Duration.ofMillis(100);
 
     @Test
     void constructorShouldThrowOnNegativeThreadCount() {
diff --git a/server/container/util/src/test/java/org/apache/james/util/date/ImapDateTimeFormatterTest.java b/server/container/util/src/test/java/org/apache/james/util/date/ImapDateTimeFormatterTest.java
index 41c1046..4eb9fbc 100644
--- a/server/container/util/src/test/java/org/apache/james/util/date/ImapDateTimeFormatterTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/date/ImapDateTimeFormatterTest.java
@@ -29,7 +29,7 @@ import java.time.format.DateTimeParseException;
 
 import org.junit.jupiter.api.Test;
 
-public class ImapDateTimeFormatterTest {
+class ImapDateTimeFormatterTest {
 
     @Test
     void dayOfWeekShouldBeParsed() {
diff --git a/server/container/util/src/test/java/org/apache/james/util/mime/MessageContentExtractorTest.java b/server/container/util/src/test/java/org/apache/james/util/mime/MessageContentExtractorTest.java
index ecf0e5a..e622d80 100644
--- a/server/container/util/src/test/java/org/apache/james/util/mime/MessageContentExtractorTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/mime/MessageContentExtractorTest.java
@@ -41,7 +41,7 @@ import org.apache.james.util.mime.MessageContentExtractor.MessageContent;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
-public class MessageContentExtractorTest {
+class MessageContentExtractorTest {
     private static final String BINARY_CONTENT = "binary";
     private static final String TEXT_CONTENT = "text content";
     private static final String HTML_CONTENT = "<b>html</b> content";
diff --git a/server/container/util/src/test/java/org/apache/james/util/retry/DoublingRetryScheduleTest.java b/server/container/util/src/test/java/org/apache/james/util/retry/DoublingRetryScheduleTest.java
index ba0faf9..60f348f 100644
--- a/server/container/util/src/test/java/org/apache/james/util/retry/DoublingRetryScheduleTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/retry/DoublingRetryScheduleTest.java
@@ -24,7 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import org.apache.james.util.retry.api.RetrySchedule;
 import org.junit.jupiter.api.Test;
 
-public class DoublingRetryScheduleTest {
+class DoublingRetryScheduleTest {
 
     @Test
     void testDoublingRetrySchedule() {
diff --git a/server/container/util/src/test/java/org/apache/james/util/retry/ExceptionRetryHandlerTest.java b/server/container/util/src/test/java/org/apache/james/util/retry/ExceptionRetryHandlerTest.java
index 07ba09d..6e96018 100644
--- a/server/container/util/src/test/java/org/apache/james/util/retry/ExceptionRetryHandlerTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/retry/ExceptionRetryHandlerTest.java
@@ -32,7 +32,7 @@ import org.apache.james.util.retry.api.RetrySchedule;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
-public class ExceptionRetryHandlerTest {
+class ExceptionRetryHandlerTest {
     private static class TestRetryingProxy implements ExceptionRetryingProxy {
 
         @Override
diff --git a/server/container/util/src/test/java/org/apache/james/util/retry/naming/NamingExceptionRetryHandlerTest.java b/server/container/util/src/test/java/org/apache/james/util/retry/naming/NamingExceptionRetryHandlerTest.java
index 2bb357a..60ef0ad 100644
--- a/server/container/util/src/test/java/org/apache/james/util/retry/naming/NamingExceptionRetryHandlerTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/retry/naming/NamingExceptionRetryHandlerTest.java
@@ -29,7 +29,7 @@ import org.apache.james.util.retry.api.RetryHandler;
 import org.apache.james.util.retry.api.RetrySchedule;
 import org.junit.jupiter.api.Test;
 
-public class NamingExceptionRetryHandlerTest {
+class NamingExceptionRetryHandlerTest {
 
     private static class TestRetryingProxy implements ExceptionRetryingProxy {
         @Override
diff --git a/server/container/util/src/test/java/org/apache/james/util/streams/ImmutableCollectorsTest.java b/server/container/util/src/test/java/org/apache/james/util/streams/ImmutableCollectorsTest.java
index d6f1bf2..c43ad2a 100644
--- a/server/container/util/src/test/java/org/apache/james/util/streams/ImmutableCollectorsTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/streams/ImmutableCollectorsTest.java
@@ -35,7 +35,7 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 
-public class ImmutableCollectorsTest {
+class ImmutableCollectorsTest {
 
     @Test
     void immutableListCollectorShouldReturnEmptyImmutableListWhenEmptyStream() {
diff --git a/server/container/util/src/test/java/org/apache/james/util/streams/IteratorsTest.java b/server/container/util/src/test/java/org/apache/james/util/streams/IteratorsTest.java
index bb01f00..06f8186 100644
--- a/server/container/util/src/test/java/org/apache/james/util/streams/IteratorsTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/streams/IteratorsTest.java
@@ -31,7 +31,7 @@ import com.google.common.collect.UnmodifiableIterator;
 
 import reactor.core.publisher.Flux;
 
-public class IteratorsTest {
+class IteratorsTest {
 
     @Test
     void toStreamShouldReturnEmptyStreamWhenEmptyIterator() {
diff --git a/server/container/util/src/test/java/org/apache/james/util/streams/LimitTest.java b/server/container/util/src/test/java/org/apache/james/util/streams/LimitTest.java
index 2a1d35b..6a17cbd 100644
--- a/server/container/util/src/test/java/org/apache/james/util/streams/LimitTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/streams/LimitTest.java
@@ -32,7 +32,7 @@ import com.google.common.collect.ImmutableList;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
 
-public class LimitTest {
+class LimitTest {
 
     private final List<Integer> aList = ImmutableList.of(1, 2, 3, 4, 5, 6);
 
diff --git a/server/container/util/src/test/java/org/apache/james/util/streams/OffsetTest.java b/server/container/util/src/test/java/org/apache/james/util/streams/OffsetTest.java
index f62762e..780c566 100644
--- a/server/container/util/src/test/java/org/apache/james/util/streams/OffsetTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/streams/OffsetTest.java
@@ -27,7 +27,7 @@ import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
 
-public class OffsetTest {
+class OffsetTest {
 
     public static final int VALUE = 18;
 


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


[james-project] 38/41: [Refactoring] Remove exceptions not thrown by methods in test classes in james-server-util module

Posted by bt...@apache.org.
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 128fe638becebb51af7265ce81d181c5a59e8cd0
Author: Rene Cordier <rc...@linagora.com>
AuthorDate: Tue Nov 19 17:04:08 2019 +0700

    [Refactoring] Remove exceptions not thrown by methods in test classes in james-server-util module
---
 .../org/apache/james/util/CommutativityCheckerTest.java  | 16 ++++++++--------
 .../java/org/apache/james/util/OptionalUtilsTest.java    |  6 +++---
 .../src/test/java/org/apache/james/util/SizeTest.java    |  2 +-
 .../james/util/concurrency/ConcurrentTestRunnerTest.java |  2 +-
 .../james/util/retry/ExceptionRetryHandlerTest.java      |  2 +-
 5 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/server/container/util/src/test/java/org/apache/james/util/CommutativityCheckerTest.java b/server/container/util/src/test/java/org/apache/james/util/CommutativityCheckerTest.java
index d0b9dac..3561c0a 100644
--- a/server/container/util/src/test/java/org/apache/james/util/CommutativityCheckerTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/CommutativityCheckerTest.java
@@ -32,7 +32,7 @@ import com.google.common.collect.ImmutableSet;
 
 public class CommutativityCheckerTest {
     @Test
-    void constructorShouldThrowWhenNullValuesToTest() throws Exception {
+    void constructorShouldThrowWhenNullValuesToTest() {
         BinaryOperator<Integer> binaryOperator = (a, b) -> a * a + b;
 
         assertThatThrownBy(() -> new CommutativityChecker<>(null, binaryOperator))
@@ -40,7 +40,7 @@ public class CommutativityCheckerTest {
     }
 
     @Test
-    void constructorShouldThrowWhenEmptyValuesToTest() throws Exception {
+    void constructorShouldThrowWhenEmptyValuesToTest() {
         BinaryOperator<Integer> binaryOperator = (a, b) -> a * a + b;
 
         assertThatThrownBy(() -> new CommutativityChecker<>(ImmutableSet.of(), binaryOperator))
@@ -48,7 +48,7 @@ public class CommutativityCheckerTest {
     }
 
     @Test
-    void constructorShouldThrowWhenSingleValueToTest() throws Exception {
+    void constructorShouldThrowWhenSingleValueToTest() {
         BinaryOperator<Integer> binaryOperator = (a, b) -> a * a + b;
 
         assertThatThrownBy(() -> new CommutativityChecker<>(ImmutableSet.of(0), binaryOperator))
@@ -56,13 +56,13 @@ public class CommutativityCheckerTest {
     }
 
     @Test
-    void constructorShouldThrowWhenNullOperation() throws Exception {
+    void constructorShouldThrowWhenNullOperation() {
         assertThatThrownBy(() -> new CommutativityChecker<>(ImmutableSet.of(0, 1), null))
             .isInstanceOf(NullPointerException.class);
     }
 
     @Test
-    void findNonCommutativeInputShouldReturnEmptyWhenCommutativeOperation() throws Exception {
+    void findNonCommutativeInputShouldReturnEmptyWhenCommutativeOperation() {
         Set<Integer> integers = ImmutableSet.of(5, 4, 3, 2, 1);
         BinaryOperator<Integer> commutativeOperator = (a, b) -> a + b;
         CommutativityChecker<Integer> commutativityChecker = new CommutativityChecker<>(integers, commutativeOperator);
@@ -71,7 +71,7 @@ public class CommutativityCheckerTest {
     }
 
     @Test
-    void findNonCommutativeInputShouldReturnDataWhenNonCommutativeOperation() throws Exception {
+    void findNonCommutativeInputShouldReturnDataWhenNonCommutativeOperation() {
         Set<Integer> integers = ImmutableSet.of(2, 1);
         BinaryOperator<Integer> nonCommutativeOperator = (a, b) -> 2 * a + b;
         CommutativityChecker<Integer> commutativityChecker = new CommutativityChecker<>(integers, nonCommutativeOperator);
@@ -81,7 +81,7 @@ public class CommutativityCheckerTest {
     }
 
     @Test
-    void findNonCommutativeInputShouldNotReturnStableValues() throws Exception {
+    void findNonCommutativeInputShouldNotReturnStableValues() {
         Set<Integer> integers = ImmutableSet.of(0, 1, 2);
         BinaryOperator<Integer> nonCommutativeOperatorWithStableValues = (a, b) -> a * a + b;
         CommutativityChecker<Integer> commutativityChecker = new CommutativityChecker<>(integers, nonCommutativeOperatorWithStableValues);
@@ -92,7 +92,7 @@ public class CommutativityCheckerTest {
     }
 
     @Test
-    void findNonCommutativeInputShouldReturnEmptyWhenNonCommutativeOperationButOnlyStableValues() throws Exception {
+    void findNonCommutativeInputShouldReturnEmptyWhenNonCommutativeOperationButOnlyStableValues() {
         Set<Integer> stableValues = ImmutableSet.of(0, 1);
         BinaryOperator<Integer> nonCommutativeOperatorWithStableValues = (a, b) -> a * a + b;
         CommutativityChecker<Integer> commutativityChecker = new CommutativityChecker<>(stableValues, nonCommutativeOperatorWithStableValues);
diff --git a/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java b/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java
index 98812ab..8d750b9 100644
--- a/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java
@@ -210,7 +210,7 @@ public class OptionalUtilsTest {
     }
 
     @Test
-    void containsDifferentShouldReturnTrueWhenNullStoreValue() throws Exception {
+    void containsDifferentShouldReturnTrueWhenNullStoreValue() {
         assertThat(OptionalUtils.containsDifferent(Optional.of("any"), null)).isTrue();
     }
 
@@ -220,12 +220,12 @@ public class OptionalUtilsTest {
     }
 
     @Test
-    void containsDifferentShouldReturnFalseWhenSameValue() throws Exception {
+    void containsDifferentShouldReturnFalseWhenSameValue() {
         assertThat(OptionalUtils.containsDifferent(Optional.of("any"), "any")).isFalse();
     }
 
     @Test
-    void containsDifferentShouldReturnTrueWhenDifferentValue() throws Exception {
+    void containsDifferentShouldReturnTrueWhenDifferentValue() {
         assertThat(OptionalUtils.containsDifferent(Optional.of("any"), "other")).isTrue();
     }
 
diff --git a/server/container/util/src/test/java/org/apache/james/util/SizeTest.java b/server/container/util/src/test/java/org/apache/james/util/SizeTest.java
index bc73a77..7afdf56 100644
--- a/server/container/util/src/test/java/org/apache/james/util/SizeTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/SizeTest.java
@@ -68,7 +68,7 @@ public class SizeTest {
     }
 
     @Test
-    void testWrongNumber() throws Exception {
+    void testWrongNumber() {
         assertThatThrownBy(() -> Size.parse("42RG"))
             .isInstanceOf(NumberFormatException.class);
     }
diff --git a/server/container/util/src/test/java/org/apache/james/util/concurrency/ConcurrentTestRunnerTest.java b/server/container/util/src/test/java/org/apache/james/util/concurrency/ConcurrentTestRunnerTest.java
index 1381694..7a4afc0 100644
--- a/server/container/util/src/test/java/org/apache/james/util/concurrency/ConcurrentTestRunnerTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/concurrency/ConcurrentTestRunnerTest.java
@@ -185,7 +185,7 @@ public class ConcurrentTestRunnerTest {
     }
 
     @Test
-    void assertNoExceptionShouldThrowOnExceptions() throws Exception {
+    void assertNoExceptionShouldThrowOnExceptions() {
         assertThatThrownBy(() ->
                 ConcurrentTestRunner.builder()
                     .operation((threadNumber, step) -> {
diff --git a/server/container/util/src/test/java/org/apache/james/util/retry/ExceptionRetryHandlerTest.java b/server/container/util/src/test/java/org/apache/james/util/retry/ExceptionRetryHandlerTest.java
index a61f05f..07ba09d 100644
--- a/server/container/util/src/test/java/org/apache/james/util/retry/ExceptionRetryHandlerTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/retry/ExceptionRetryHandlerTest.java
@@ -55,7 +55,7 @@ public class ExceptionRetryHandlerTest {
     private RetrySchedule schedule = null;
 
     @BeforeEach
-    void setUp() throws Exception {
+    void setUp() {
         exceptionClasses = new Class<?>[]{Exception.class};
         proxy = new TestRetryingProxy();
         schedule = i -> i;


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


[james-project] 34/41: JAMES-2979 fix concurent dequeue for MemoryMailQueue

Posted by bt...@apache.org.
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 c4b9d184dad70899baa7eee3ab3474d8c4f7eb6c
Author: Rémi KOWALSKI <rk...@linagora.com>
AuthorDate: Thu Nov 14 13:53:17 2019 +0100

    JAMES-2979 fix concurent dequeue for MemoryMailQueue
---
 .../java/org/apache/james/queue/memory/MemoryMailQueueFactory.java   | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/server/queue/queue-memory/src/main/java/org/apache/james/queue/memory/MemoryMailQueueFactory.java b/server/queue/queue-memory/src/main/java/org/apache/james/queue/memory/MemoryMailQueueFactory.java
index b012f7f..2066a7c 100644
--- a/server/queue/queue-memory/src/main/java/org/apache/james/queue/memory/MemoryMailQueueFactory.java
+++ b/server/queue/queue-memory/src/main/java/org/apache/james/queue/memory/MemoryMailQueueFactory.java
@@ -55,6 +55,7 @@ import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
+import reactor.core.scheduler.Schedulers;
 
 public class MemoryMailQueueFactory implements MailQueueFactory<ManageableMailQueue> {
 
@@ -96,7 +97,9 @@ public class MemoryMailQueueFactory implements MailQueueFactory<ManageableMailQu
             this.name = name;
             this.flux = Mono.fromCallable(mailItems::take)
                 .repeat()
-                .flatMap(item -> Mono.just(inProcessingMailItems.add(item)).thenReturn(item))
+                .subscribeOn(Schedulers.boundedElastic())
+                .flatMap(item ->
+                    Mono.fromRunnable(() -> inProcessingMailItems.add(item)).thenReturn(item))
                 .map(mailQueueItemDecoratorFactory::decorate);
         }
 


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


[james-project] 14/41: JAMES-2813 fix bad copy/paste on DTO type

Posted by bt...@apache.org.
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 28f01f2b5555fb6b23fe9352b9afd2269e61f911
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Tue Oct 22 17:08:58 2019 +0200

    JAMES-2813 fix bad copy/paste on DTO type
---
 .../org/apache/james/server/task/json/dto/TestTaskDTOModules.java   | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/server/task/task-json/src/test/java/org/apache/james/server/task/json/dto/TestTaskDTOModules.java b/server/task/task-json/src/test/java/org/apache/james/server/task/json/dto/TestTaskDTOModules.java
index 0236c76..61b3acc 100644
--- a/server/task/task-json/src/test/java/org/apache/james/server/task/json/dto/TestTaskDTOModules.java
+++ b/server/task/task-json/src/test/java/org/apache/james/server/task/json/dto/TestTaskDTOModules.java
@@ -74,11 +74,11 @@ public interface TestTaskDTOModules {
         .typeName(MemoryReferenceTask.TYPE.asString())
         .withFactory(TaskDTOModule::new);
 
-    Function<MemoryReferenceWithCounterTaskStore, TaskDTOModule<MemoryReferenceWithCounterTask, MemoryReferenceTaskDTO>> MEMORY_REFERENCE_WITH_COUNTER_TASK_MODULE = store -> DTOModule
+    Function<MemoryReferenceWithCounterTaskStore, TaskDTOModule<MemoryReferenceWithCounterTask, MemoryReferenceWithCounterTaskDTO>> MEMORY_REFERENCE_WITH_COUNTER_TASK_MODULE = store -> DTOModule
         .forDomainObject(MemoryReferenceWithCounterTask.class)
-        .convertToDTO(MemoryReferenceTaskDTO.class)
+        .convertToDTO(MemoryReferenceWithCounterTaskDTO.class)
         .toDomainObjectConverter(dto -> store.get(dto.getReference()))
-        .toDTOConverter((task, typeName) -> new MemoryReferenceTaskDTO(typeName, store.add(task)))
+        .toDTOConverter((task, typeName) -> new MemoryReferenceWithCounterTaskDTO(typeName, store.add(task)))
         .typeName(MemoryReferenceWithCounterTask.TYPE.asString())
         .withFactory(TaskDTOModule::new);
 


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


[james-project] 21/41: JAMES-2813 demonstrate how to handle nested DTOs with some tests

Posted by bt...@apache.org.
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 475c53908d5ed456eefa21a1e4b4f81a91969e5c
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Mon Oct 21 12:04:52 2019 +0200

    JAMES-2813 demonstrate how to handle nested DTOs with some tests
---
 .../src/test/java/org/apache/DTOConverterTest.java | 11 ++++---
 .../java/org/apache/JsonGenericSerializerTest.java | 28 +++++++++++++++--
 json/src/test/java/org/apache/dto/FirstDTO.java    | 14 +++++++--
 .../java/org/apache/dto/FirstDomainObject.java     | 11 +++++--
 .../dto/{SecondDTO.java => FirstNestedDTO.java}    | 34 ++++++++-------------
 ...econdDomainObject.java => FirstNestedType.java} | 26 ++++++----------
 .../{SecondDomainObject.java => NestedType.java}   | 34 +--------------------
 json/src/test/java/org/apache/dto/SecondDTO.java   | 15 ++++++++--
 .../java/org/apache/dto/SecondDomainObject.java    | 12 ++++++--
 .../dto/{SecondDTO.java => SecondNestedDTO.java}   | 33 ++++++++------------
 ...condDomainObject.java => SecondNestedType.java} | 26 ++++++----------
 json/src/test/java/org/apache/dto/TestModules.java | 33 +++++++++++++++++---
 ...condDomainObject.java => TestNestedModule.java} | 35 ++++------------------
 13 files changed, 153 insertions(+), 159 deletions(-)

diff --git a/json/src/test/java/org/apache/DTOConverterTest.java b/json/src/test/java/org/apache/DTOConverterTest.java
index 3987dbd..d75fffe 100644
--- a/json/src/test/java/org/apache/DTOConverterTest.java
+++ b/json/src/test/java/org/apache/DTOConverterTest.java
@@ -29,6 +29,7 @@ import java.util.stream.Stream;
 import org.apache.dto.BaseType;
 import org.apache.dto.FirstDTO;
 import org.apache.dto.FirstDomainObject;
+import org.apache.dto.NestedType;
 import org.apache.dto.SecondDTO;
 import org.apache.dto.SecondDomainObject;
 import org.apache.dto.TestModules;
@@ -40,10 +41,12 @@ import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 
 class DTOConverterTest {
-    private static final FirstDomainObject FIRST = new FirstDomainObject(Optional.of(1L), ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"), "first payload");
-    private static final FirstDTO FIRST_DTO = new FirstDTO("first", Optional.of(1L), "2016-04-03T02:01+07:00[Asia/Vientiane]", "first payload");
-    private static final SecondDomainObject SECOND = new SecondDomainObject(UUID.fromString("4a2c853f-7ffc-4ce3-9410-a47e85b3b741"), "second payload");
-    private static final SecondDTO SECOND_DTO = new SecondDTO("second", "4a2c853f-7ffc-4ce3-9410-a47e85b3b741", "second payload");
+    private static final Optional<NestedType> NO_CHILD = Optional.empty();
+    private static final Optional<DTO> NO_CHILD_DTO = Optional.empty();
+    private static final FirstDomainObject FIRST = new FirstDomainObject(Optional.of(1L), ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"), "first payload", NO_CHILD);
+    private static final FirstDTO FIRST_DTO = new FirstDTO("first", Optional.of(1L), "2016-04-03T02:01+07:00[Asia/Vientiane]", "first payload", NO_CHILD_DTO);
+    private static final SecondDomainObject SECOND = new SecondDomainObject(UUID.fromString("4a2c853f-7ffc-4ce3-9410-a47e85b3b741"), "second payload", NO_CHILD);
+    private static final SecondDTO SECOND_DTO = new SecondDTO("second", "4a2c853f-7ffc-4ce3-9410-a47e85b3b741", "second payload", NO_CHILD_DTO);
 
     @SuppressWarnings("unchecked")
     @Test
diff --git a/json/src/test/java/org/apache/JsonGenericSerializerTest.java b/json/src/test/java/org/apache/JsonGenericSerializerTest.java
index 8205553..3fc6c45 100644
--- a/json/src/test/java/org/apache/JsonGenericSerializerTest.java
+++ b/json/src/test/java/org/apache/JsonGenericSerializerTest.java
@@ -30,7 +30,10 @@ import java.util.stream.Stream;
 
 import org.apache.dto.BaseType;
 import org.apache.dto.FirstDomainObject;
+import org.apache.dto.FirstNestedType;
+import org.apache.dto.NestedType;
 import org.apache.dto.SecondDomainObject;
+import org.apache.dto.SecondNestedType;
 import org.apache.dto.TestModules;
 import org.apache.james.json.DTO;
 import org.apache.james.json.JsonGenericSerializer;
@@ -40,13 +43,18 @@ import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 
 class JsonGenericSerializerTest {
-    private static final FirstDomainObject FIRST = new FirstDomainObject(Optional.of(1L), ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"), "first payload");
-    private static final SecondDomainObject SECOND = new SecondDomainObject(UUID.fromString("4a2c853f-7ffc-4ce3-9410-a47e85b3b741"), "second payload");
+    private static final Optional<NestedType> NO_CHILD = Optional.empty();
+    private static final FirstDomainObject FIRST = new FirstDomainObject(Optional.of(1L), ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"), "first payload", NO_CHILD);
+    private static final SecondDomainObject SECOND = new SecondDomainObject(UUID.fromString("4a2c853f-7ffc-4ce3-9410-a47e85b3b741"), "second payload", NO_CHILD);
+    private static final SecondDomainObject SECOND_WITH_NESTED = new SecondDomainObject(UUID.fromString("4a2c853f-7ffc-4ce3-9410-a47e85b3b741"), "second payload", Optional.of(new FirstNestedType(12)));
+    private static final FirstDomainObject FIRST_WITH_NESTED = new FirstDomainObject(Optional.of(1L), ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"), "payload", Optional.of(new SecondNestedType("bar")));
 
     private static final String MISSING_TYPE_JSON = "{\"id\":1,\"time\":\"2016-04-03T02:01+07:00[Asia/Vientiane]\",\"payload\":\"first payload\"}";
     private static final String DUPLICATE_TYPE_JSON = "{\"type\":\"first\", \"type\":\"second\", \"id\":1,\"time\":\"2016-04-03T02:01+07:00[Asia/Vientiane]\",\"payload\":\"first payload\"}";
     private static final String FIRST_JSON = "{\"type\":\"first\",\"id\":1,\"time\":\"2016-04-03T02:01+07:00[Asia/Vientiane]\",\"payload\":\"first payload\"}";
+    private static final String FIRST_JSON_WITH_NESTED = "{\"type\":\"first\",\"id\":1,\"time\":\"2016-04-03T02:01+07:00[Asia/Vientiane]\",\"payload\":\"payload\", \"child\": {\"bar\": \"bar\", \"type\": \"second-nested\"}}";
     private static final String SECOND_JSON = "{\"type\":\"second\",\"id\":\"4a2c853f-7ffc-4ce3-9410-a47e85b3b741\",\"payload\":\"second payload\"}";
+    private static final String SECOND_WITH_NESTED_JSON = "{\"type\":\"second\",\"id\":\"4a2c853f-7ffc-4ce3-9410-a47e85b3b741\",\"payload\":\"second payload\", \"child\": {\"foo\": 12, \"type\": \"first-nested\"}}";
 
     @SuppressWarnings("unchecked")
     @Test
@@ -58,6 +66,22 @@ class JsonGenericSerializerTest {
 
     @SuppressWarnings("unchecked")
     @Test
+    void shouldDeserializeNestedTypeWithSecond() throws Exception {
+        assertThat(JsonGenericSerializer.of(TestModules.FIRST_TYPE, TestModules.SECOND_TYPE, TestModules.FIRST_NESTED, TestModules.SECOND_NESTED)
+            .deserialize(SECOND_WITH_NESTED_JSON))
+            .isEqualTo(SECOND_WITH_NESTED);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    void shouldDeserializeNestedTypeWithFirst() throws Exception {
+        assertThat(JsonGenericSerializer.of(TestModules.FIRST_TYPE, TestModules.SECOND_TYPE, TestModules.FIRST_NESTED, TestModules.SECOND_NESTED)
+            .deserialize(FIRST_JSON_WITH_NESTED))
+            .isEqualTo(FIRST_WITH_NESTED);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
     void shouldThrowWhenDeserializeEventWithMissingType() {
         assertThatThrownBy(() -> JsonGenericSerializer.of(TestModules.FIRST_TYPE)
             .deserialize(MISSING_TYPE_JSON))
diff --git a/json/src/test/java/org/apache/dto/FirstDTO.java b/json/src/test/java/org/apache/dto/FirstDTO.java
index 9e4f46b..b1bdf23 100644
--- a/json/src/test/java/org/apache/dto/FirstDTO.java
+++ b/json/src/test/java/org/apache/dto/FirstDTO.java
@@ -23,6 +23,7 @@ import java.time.ZonedDateTime;
 import java.util.Optional;
 
 import org.apache.james.json.DTO;
+import org.apache.james.json.DTOConverter;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
@@ -33,17 +34,20 @@ public class FirstDTO implements DTO {
     private final Optional<Long> id;
     private final String time;
     private final String payload;
+    private final Optional<DTO> child;
 
     @JsonCreator
     public FirstDTO(
             @JsonProperty("type") String type,
             @JsonProperty("id") Optional<Long> id,
             @JsonProperty("time") String time,
-            @JsonProperty("payload") String payload) {
+            @JsonProperty("payload") String payload,
+            @JsonProperty("child") Optional<DTO> child) {
         this.type = type;
         this.id = id;
         this.time = time;
         this.payload = payload;
+        this.child = child;
     }
 
     public String getType() {
@@ -62,8 +66,12 @@ public class FirstDTO implements DTO {
         return payload;
     }
 
+    public Optional<DTO> getChild() {
+        return child;
+    }
+
     @JsonIgnore
-    public FirstDomainObject toDomainObject() {
-        return new FirstDomainObject(id, ZonedDateTime.parse(time), payload);
+    public FirstDomainObject toDomainObject(DTOConverter<NestedType, DTO> converter) {
+        return new FirstDomainObject(id, ZonedDateTime.parse(time), payload, child.flatMap(converter::convert));
     }
 }
diff --git a/json/src/test/java/org/apache/dto/FirstDomainObject.java b/json/src/test/java/org/apache/dto/FirstDomainObject.java
index 6c8a787..13e8462 100644
--- a/json/src/test/java/org/apache/dto/FirstDomainObject.java
+++ b/json/src/test/java/org/apache/dto/FirstDomainObject.java
@@ -27,11 +27,13 @@ public class FirstDomainObject implements BaseType {
     private final Optional<Long> id;
     private final ZonedDateTime time;
     private final String payload;
+    private final Optional<NestedType> child;
 
-    public FirstDomainObject(Optional<Long> id, ZonedDateTime time, String payload) {
+    public FirstDomainObject(Optional<Long> id, ZonedDateTime time, String payload, Optional<NestedType> child) {
         this.id = id;
         this.time = time;
         this.payload = payload;
+        this.child = child;
     }
 
     public Optional<Long> getId() {
@@ -46,6 +48,10 @@ public class FirstDomainObject implements BaseType {
         return payload;
     }
 
+    public Optional<NestedType> getChild() {
+        return child;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
@@ -53,11 +59,12 @@ public class FirstDomainObject implements BaseType {
         FirstDomainObject that = (FirstDomainObject) o;
         return Objects.equals(id, that.id) &&
                 Objects.equals(time, that.time) &&
+                Objects.equals(child, that.child) &&
                 Objects.equals(payload, that.payload);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(id, time, payload);
+        return Objects.hash(id, time, child, payload);
     }
 }
diff --git a/json/src/test/java/org/apache/dto/SecondDTO.java b/json/src/test/java/org/apache/dto/FirstNestedDTO.java
similarity index 73%
copy from json/src/test/java/org/apache/dto/SecondDTO.java
copy to json/src/test/java/org/apache/dto/FirstNestedDTO.java
index d31929a..9fd7498 100644
--- a/json/src/test/java/org/apache/dto/SecondDTO.java
+++ b/json/src/test/java/org/apache/dto/FirstNestedDTO.java
@@ -19,43 +19,35 @@
 
 package org.apache.dto;
 
-import java.util.UUID;
-
 import org.apache.james.json.DTO;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-public class SecondDTO implements DTO {
+public class FirstNestedDTO implements DTO {
+    private final int foo;
     private final String type;
-    private final String id;
-    private final String payload;
 
     @JsonCreator
-    public SecondDTO(
-            @JsonProperty("type") String type,
-            @JsonProperty("id") String id,
-            @JsonProperty("payload") String payload) {
+    public FirstNestedDTO(@JsonProperty("foo") int foo,
+                          @JsonProperty("type") String type) {
+        this.foo = foo;
         this.type = type;
-        this.id = id;
-        this.payload = payload;
-    }
-
-    public String getType() {
-        return type;
     }
 
-    public String getId() {
-        return id;
+    public int getFoo() {
+        return foo;
     }
 
-    public String getPayload() {
-        return payload;
+    @Override
+    public String getType() {
+        return type;
     }
 
     @JsonIgnore
-    public SecondDomainObject toDomainObject() {
-        return new SecondDomainObject(UUID.fromString(id), payload);
+    public FirstNestedType toDomainObject() {
+        return new FirstNestedType(foo);
     }
+
 }
diff --git a/json/src/test/java/org/apache/dto/SecondDomainObject.java b/json/src/test/java/org/apache/dto/FirstNestedType.java
similarity index 72%
copy from json/src/test/java/org/apache/dto/SecondDomainObject.java
copy to json/src/test/java/org/apache/dto/FirstNestedType.java
index 30ac702..745a582 100644
--- a/json/src/test/java/org/apache/dto/SecondDomainObject.java
+++ b/json/src/test/java/org/apache/dto/FirstNestedType.java
@@ -20,36 +20,28 @@
 package org.apache.dto;
 
 import java.util.Objects;
-import java.util.UUID;
 
-public class SecondDomainObject implements BaseType {
-    private final UUID id;
-    private final String payload;
+public class FirstNestedType implements NestedType{
+    final int foo;
 
-    public SecondDomainObject(UUID id, String payload) {
-        this.id = id;
-        this.payload = payload;
+    public FirstNestedType(int foo) {
+        this.foo = foo;
     }
 
-    public UUID getId() {
-        return id;
-    }
-
-    public String getPayload() {
-        return payload;
+    public int getFoo() {
+        return foo;
     }
 
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
-        SecondDomainObject that = (SecondDomainObject) o;
-        return Objects.equals(id, that.id) &&
-                Objects.equals(payload, that.payload);
+        FirstNestedType that = (FirstNestedType) o;
+        return foo == that.foo;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(id, payload);
+        return Objects.hash(foo);
     }
 }
diff --git a/json/src/test/java/org/apache/dto/SecondDomainObject.java b/json/src/test/java/org/apache/dto/NestedType.java
similarity index 60%
copy from json/src/test/java/org/apache/dto/SecondDomainObject.java
copy to json/src/test/java/org/apache/dto/NestedType.java
index 30ac702..80145ee 100644
--- a/json/src/test/java/org/apache/dto/SecondDomainObject.java
+++ b/json/src/test/java/org/apache/dto/NestedType.java
@@ -19,37 +19,5 @@
 
 package org.apache.dto;
 
-import java.util.Objects;
-import java.util.UUID;
-
-public class SecondDomainObject implements BaseType {
-    private final UUID id;
-    private final String payload;
-
-    public SecondDomainObject(UUID id, String payload) {
-        this.id = id;
-        this.payload = payload;
-    }
-
-    public UUID getId() {
-        return id;
-    }
-
-    public String getPayload() {
-        return payload;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        SecondDomainObject that = (SecondDomainObject) o;
-        return Objects.equals(id, that.id) &&
-                Objects.equals(payload, that.payload);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(id, payload);
-    }
+public interface NestedType {
 }
diff --git a/json/src/test/java/org/apache/dto/SecondDTO.java b/json/src/test/java/org/apache/dto/SecondDTO.java
index d31929a..be66948 100644
--- a/json/src/test/java/org/apache/dto/SecondDTO.java
+++ b/json/src/test/java/org/apache/dto/SecondDTO.java
@@ -19,9 +19,11 @@
 
 package org.apache.dto;
 
+import java.util.Optional;
 import java.util.UUID;
 
 import org.apache.james.json.DTO;
+import org.apache.james.json.DTOConverter;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
@@ -31,15 +33,18 @@ public class SecondDTO implements DTO {
     private final String type;
     private final String id;
     private final String payload;
+    private final Optional<DTO> child;
 
     @JsonCreator
     public SecondDTO(
             @JsonProperty("type") String type,
             @JsonProperty("id") String id,
-            @JsonProperty("payload") String payload) {
+            @JsonProperty("payload") String payload,
+            @JsonProperty("child") Optional<DTO> child) {
         this.type = type;
         this.id = id;
         this.payload = payload;
+        this.child = child;
     }
 
     public String getType() {
@@ -54,8 +59,12 @@ public class SecondDTO implements DTO {
         return payload;
     }
 
+    public Optional<DTO> getChild() {
+        return child;
+    }
+
     @JsonIgnore
-    public SecondDomainObject toDomainObject() {
-        return new SecondDomainObject(UUID.fromString(id), payload);
+    public SecondDomainObject toDomainObject(DTOConverter<NestedType, DTO> converter) {
+        return new SecondDomainObject(UUID.fromString(id), payload, child.flatMap(converter::convert));
     }
 }
diff --git a/json/src/test/java/org/apache/dto/SecondDomainObject.java b/json/src/test/java/org/apache/dto/SecondDomainObject.java
index 30ac702..5c20fc8 100644
--- a/json/src/test/java/org/apache/dto/SecondDomainObject.java
+++ b/json/src/test/java/org/apache/dto/SecondDomainObject.java
@@ -20,15 +20,18 @@
 package org.apache.dto;
 
 import java.util.Objects;
+import java.util.Optional;
 import java.util.UUID;
 
 public class SecondDomainObject implements BaseType {
     private final UUID id;
     private final String payload;
+    private final Optional<NestedType> child;
 
-    public SecondDomainObject(UUID id, String payload) {
+    public SecondDomainObject(UUID id, String payload, Optional<NestedType> child) {
         this.id = id;
         this.payload = payload;
+        this.child = child;
     }
 
     public UUID getId() {
@@ -39,17 +42,22 @@ public class SecondDomainObject implements BaseType {
         return payload;
     }
 
+    public Optional<NestedType> getChild() {
+        return child;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
         SecondDomainObject that = (SecondDomainObject) o;
         return Objects.equals(id, that.id) &&
+                Objects.equals(child, that.child) &&
                 Objects.equals(payload, that.payload);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(id, payload);
+        return Objects.hash(id, child, payload);
     }
 }
diff --git a/json/src/test/java/org/apache/dto/SecondDTO.java b/json/src/test/java/org/apache/dto/SecondNestedDTO.java
similarity index 73%
copy from json/src/test/java/org/apache/dto/SecondDTO.java
copy to json/src/test/java/org/apache/dto/SecondNestedDTO.java
index d31929a..9b86497 100644
--- a/json/src/test/java/org/apache/dto/SecondDTO.java
+++ b/json/src/test/java/org/apache/dto/SecondNestedDTO.java
@@ -19,43 +19,34 @@
 
 package org.apache.dto;
 
-import java.util.UUID;
-
 import org.apache.james.json.DTO;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-public class SecondDTO implements DTO {
+public class SecondNestedDTO implements DTO {
+    private final String bar;
     private final String type;
-    private final String id;
-    private final String payload;
 
     @JsonCreator
-    public SecondDTO(
-            @JsonProperty("type") String type,
-            @JsonProperty("id") String id,
-            @JsonProperty("payload") String payload) {
+    public SecondNestedDTO(@JsonProperty("bar") String bar,
+                           @JsonProperty("type") String type) {
+        this.bar = bar;
         this.type = type;
-        this.id = id;
-        this.payload = payload;
     }
 
-    public String getType() {
-        return type;
+    public String getBar() {
+        return bar;
     }
 
-    public String getId() {
-        return id;
-    }
-
-    public String getPayload() {
-        return payload;
+    @Override
+    public String getType() {
+        return type;
     }
 
     @JsonIgnore
-    public SecondDomainObject toDomainObject() {
-        return new SecondDomainObject(UUID.fromString(id), payload);
+    public SecondNestedType toDomainObject() {
+        return new SecondNestedType(bar);
     }
 }
diff --git a/json/src/test/java/org/apache/dto/SecondDomainObject.java b/json/src/test/java/org/apache/dto/SecondNestedType.java
similarity index 72%
copy from json/src/test/java/org/apache/dto/SecondDomainObject.java
copy to json/src/test/java/org/apache/dto/SecondNestedType.java
index 30ac702..0bbbf2f 100644
--- a/json/src/test/java/org/apache/dto/SecondDomainObject.java
+++ b/json/src/test/java/org/apache/dto/SecondNestedType.java
@@ -20,36 +20,28 @@
 package org.apache.dto;
 
 import java.util.Objects;
-import java.util.UUID;
 
-public class SecondDomainObject implements BaseType {
-    private final UUID id;
-    private final String payload;
+public class SecondNestedType implements NestedType {
+    final String bar;
 
-    public SecondDomainObject(UUID id, String payload) {
-        this.id = id;
-        this.payload = payload;
+    public SecondNestedType(String bar) {
+        this.bar = bar;
     }
 
-    public UUID getId() {
-        return id;
-    }
-
-    public String getPayload() {
-        return payload;
+    public String getBar() {
+        return bar;
     }
 
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
-        SecondDomainObject that = (SecondDomainObject) o;
-        return Objects.equals(id, that.id) &&
-                Objects.equals(payload, that.payload);
+        SecondNestedType that = (SecondNestedType) o;
+        return Objects.equals(bar, that.bar);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(id, payload);
+        return Objects.hash(bar);
     }
 }
diff --git a/json/src/test/java/org/apache/dto/TestModules.java b/json/src/test/java/org/apache/dto/TestModules.java
index 45c5418..ad4d04b 100644
--- a/json/src/test/java/org/apache/dto/TestModules.java
+++ b/json/src/test/java/org/apache/dto/TestModules.java
@@ -19,20 +19,44 @@
 
 package org.apache.dto;
 
+import org.apache.james.json.DTO;
+import org.apache.james.json.DTOConverter;
 import org.apache.james.json.DTOModule;
 
 public interface TestModules {
+    TestNestedModule FIRST_NESTED = DTOModule
+        .forDomainObject(FirstNestedType.class)
+        .convertToDTO(FirstNestedDTO.class)
+        .toDomainObjectConverter(FirstNestedDTO::toDomainObject)
+        .toDTOConverter((domainObject, typeName) -> new FirstNestedDTO(
+            domainObject.getFoo(),
+            typeName))
+            .typeName("first-nested")
+        .withFactory(TestNestedModule::new);
+
+    TestNestedModule SECOND_NESTED = DTOModule
+        .forDomainObject(SecondNestedType.class)
+        .convertToDTO(SecondNestedDTO.class)
+        .toDomainObjectConverter(SecondNestedDTO::toDomainObject)
+        .toDTOConverter((domainObject, typeName) -> new SecondNestedDTO(
+            domainObject.getBar(),
+            typeName))
+        .typeName("second-nested")
+        .withFactory(TestNestedModule::new);
+
+    DTOConverter NESTED_CONVERTERS = DTOConverter.of(FIRST_NESTED, SECOND_NESTED);
 
     @SuppressWarnings("rawtypes")
     TestModule FIRST_TYPE = DTOModule
         .forDomainObject(FirstDomainObject.class)
         .convertToDTO(FirstDTO.class)
-        .toDomainObjectConverter(FirstDTO::toDomainObject)
+        .toDomainObjectConverter(dto -> dto.toDomainObject(NESTED_CONVERTERS))
         .toDTOConverter((domainObject, typeName) -> new FirstDTO(
             typeName,
             domainObject.getId(),
             domainObject.getTime().toString(),
-            domainObject.getPayload()))
+            domainObject.getPayload(),
+            NESTED_CONVERTERS.convert(domainObject.getChild())))
         .typeName("first")
         .withFactory(TestModule::new);
 
@@ -40,11 +64,12 @@ public interface TestModules {
     TestModule SECOND_TYPE = DTOModule
         .forDomainObject(SecondDomainObject.class)
         .convertToDTO(SecondDTO.class)
-        .toDomainObjectConverter(SecondDTO::toDomainObject)
+        .toDomainObjectConverter(dto -> dto.toDomainObject(NESTED_CONVERTERS))
         .toDTOConverter((domainObject, typeName) -> new SecondDTO(
             typeName,
             domainObject.getId().toString(),
-            domainObject.getPayload()))
+            domainObject.getPayload(),
+            NESTED_CONVERTERS.convert(domainObject.getChild())))
         .typeName("second")
         .withFactory(TestModule::new);
 
diff --git a/json/src/test/java/org/apache/dto/SecondDomainObject.java b/json/src/test/java/org/apache/dto/TestNestedModule.java
similarity index 60%
copy from json/src/test/java/org/apache/dto/SecondDomainObject.java
copy to json/src/test/java/org/apache/dto/TestNestedModule.java
index 30ac702..e67df12 100644
--- a/json/src/test/java/org/apache/dto/SecondDomainObject.java
+++ b/json/src/test/java/org/apache/dto/TestNestedModule.java
@@ -19,37 +19,12 @@
 
 package org.apache.dto;
 
-import java.util.Objects;
-import java.util.UUID;
+import org.apache.james.json.DTO;
+import org.apache.james.json.DTOModule;
 
-public class SecondDomainObject implements BaseType {
-    private final UUID id;
-    private final String payload;
+public class TestNestedModule<T extends NestedType, U extends DTO> extends DTOModule<T, U> {
 
-    public SecondDomainObject(UUID id, String payload) {
-        this.id = id;
-        this.payload = payload;
-    }
-
-    public UUID getId() {
-        return id;
-    }
-
-    public String getPayload() {
-        return payload;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        SecondDomainObject that = (SecondDomainObject) o;
-        return Objects.equals(id, that.id) &&
-                Objects.equals(payload, that.payload);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(id, payload);
+    protected TestNestedModule(DTOConverter<T, U> converter, DomainObjectConverter<T, U> toDomainObjectConverter, Class<T> domainObjectType, Class<U> dtoType, String typeName) {
+        super(converter, toDomainObjectConverter, domainObjectType, dtoType, typeName);
     }
 }


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


[james-project] 41/41: Add news about Benoît's presentation at ApacheCon

Posted by bt...@apache.org.
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 9ed9a155934234692fa3a200ea167474a541126d
Author: Raphael Ouazana <ra...@linagora.com>
AuthorDate: Tue Nov 19 16:19:08 2019 +0100

    Add news about Benoît's presentation at ApacheCon
---
 src/homepage/_posts/2019-11-19-apache-con-eu.markdown | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/homepage/_posts/2019-11-19-apache-con-eu.markdown b/src/homepage/_posts/2019-11-19-apache-con-eu.markdown
new file mode 100644
index 0000000..84b6297
--- /dev/null
+++ b/src/homepage/_posts/2019-11-19-apache-con-eu.markdown
@@ -0,0 +1,13 @@
+---
+layout: post
+title:  "Benoit Tellier presents James at ApacheCon Europe"
+date:   2019-11-19  16:16:30 +0200
+categories: james apachecon
+---
+
+Benoit had the pleasure to present James at the ApacheCon at Berlin: "Gaining control over emails with Apache James".
+
+If you missed him you can see his conference on [youtube][Youtube], or read his [article][article].
+
+[youtube]: https://www.youtube.com/watch?v=zr8qpNkL6U4
+[article]: https://medium.com/linagora-engineering/linagora-representing-james-at-the-apachecon-europe-2019-c6e28b31242a


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


[james-project] 02/41: Changelog for Distributed Task Management

Posted by bt...@apache.org.
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 cb2dcd6aa963299f60938758d4bae14274b4d1d7
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Nov 1 18:02:00 2019 +0700

    Changelog for Distributed Task Management
---
 CHANGELOG.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 97d3e99..07e0744 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 
 ## [Unreleased]
 
+### Added
+- Distributed task management for Guice cassandra-rabbitmq product. This enables two James server to share a consistent view
+of tasks being currently executed.
+
 ### Changed
 - Multiple changes have been made to enhance ElasticSearch performance:
   - Use of routing keys to collocate documents per mailbox


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


[james-project] 19/41: JAMES-2813 use jackson built-in type detection for polymorphic types

Posted by bt...@apache.org.
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 80bb1868e0b83c449c222d45f7b3d1e6e639047b
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Fri Oct 18 16:40:40 2019 +0200

    JAMES-2813 use jackson built-in type detection for polymorphic types
---
 json/src/main/java/org/apache/james/json/DTO.java  |  6 +++
 .../apache/james/json/JsonGenericSerializer.java   | 54 ++++++++++++++--------
 2 files changed, 42 insertions(+), 18 deletions(-)

diff --git a/json/src/main/java/org/apache/james/json/DTO.java b/json/src/main/java/org/apache/james/json/DTO.java
index 2e0fbdb..34f84d4 100644
--- a/json/src/main/java/org/apache/james/json/DTO.java
+++ b/json/src/main/java/org/apache/james/json/DTO.java
@@ -19,5 +19,11 @@
 
 package org.apache.james.json;
 
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+
+@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type", visible = true)
 public interface DTO {
+
+    String getType();
+
 }
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 e84630f..a1ed925 100644
--- a/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
+++ b/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
@@ -31,7 +31,9 @@ import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.exc.InvalidTypeIdException;
 import com.fasterxml.jackson.databind.exc.MismatchedInputException;
+import com.fasterxml.jackson.databind.jsontype.NamedType;
 import com.fasterxml.jackson.datatype.guava.GuavaModule;
 import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
@@ -57,12 +59,15 @@ public class JsonGenericSerializer<T, U extends DTO> {
                     Function.identity()));
         }
 
-        public Optional<DTOModule<T, U>> findModule(T domainObject) {
-            return Optional.ofNullable(domainClassToModule.get(domainObject.getClass()));
+        public Optional<U> convert(T domainObject) {
+            return Optional.ofNullable(domainClassToModule.get(domainObject.getClass()))
+                .map(module -> module.toDTO(domainObject));
         }
 
-        public Optional<DTOModule<T, U>> findModule(String type) {
-            return Optional.ofNullable(typeToModule.get(type));
+        public Optional<T> convert(U dto) {
+            String type = dto.getType();
+            return Optional.ofNullable(typeToModule.get(type))
+                .map(module -> module.getToDomainObjectConverter().convert(dto));
         }
     }
 
@@ -98,35 +103,48 @@ public class JsonGenericSerializer<T, U extends DTO> {
         objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
         objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
         objectMapper.enable(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY);
+        modules.stream()
+            .map(module -> new NamedType(module.getDTOClass(), module.getDomainObjectType()))
+            .forEach(objectMapper::registerSubtypes);
         dtoConverter = new DTOConverter<>(modules);
     }
 
     public String serialize(T domainObject) throws JsonProcessingException {
-        U dto = dtoConverter.findModule(domainObject)
-            .map(module -> module.toDTO(domainObject))
+        U dto = dtoConverter.convert(domainObject)
             .orElseThrow(() -> new UnknownTypeException("unknown type " + domainObject.getClass()));
         return objectMapper.writeValueAsString(dto);
     }
 
 
     public T deserialize(String value) throws IOException {
-        try {
-            JsonNode jsonNode = objectMapper.readTree(value);
-
-            JsonNode typeNode = jsonNode.path("type");
+        U dto = jsonToDTO(value);
+        return dtoConverter.convert(dto)
+            .orElseThrow(() -> new UnknownTypeException("unknown type " + dto.getType()));
+    }
 
-            if (typeNode.isMissingNode()) {
-                throw new InvalidTypeException("No \"type\" property found in the json document");
+    public U jsonToDTO(String value) throws IOException {
+        try {
+            JsonNode jsonTree = detectDuplicateProperty(value);
+            return parseAsPolymorphicDTO(jsonTree);
+        } catch (InvalidTypeIdException e) {
+            String typeId = e.getTypeId();
+            if (typeId == null) {
+                throw new InvalidTypeException("Unable to deserialize the json document", e);
+            } else {
+                throw new UnknownTypeException("unknown type " + typeId);
             }
-
-            String type = typeNode.asText();
-            DTOModule<T, U> dtoModule = dtoConverter.findModule(type)
-                .orElseThrow(() -> new UnknownTypeException("unknown type " + type));
-            U dto = objectMapper.readValue(objectMapper.treeAsTokens(jsonNode), dtoModule.getDTOClass());
-            return dtoModule.getToDomainObjectConverter().convert(dto);
         } catch (MismatchedInputException e) {
             throw new InvalidTypeException("Unable to deserialize the json document", e);
         }
     }
 
+    private JsonNode detectDuplicateProperty(String value) throws IOException {
+        return objectMapper.readTree(value);
+    }
+
+    @SuppressWarnings("rawtypes")
+    private U parseAsPolymorphicDTO(JsonNode jsonTree) throws IOException {
+        return (U) objectMapper.readValue(objectMapper.treeAsTokens(jsonTree), DTO.class);
+    }
+
 }


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


[james-project] 18/41: JAMES-2813 split module finding into an inner class before further refactoring

Posted by bt...@apache.org.
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 ef1ec9ccc02ea3143c90990776cb1f71bff012a5
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Fri Oct 18 14:12:27 2019 +0200

    JAMES-2813 split module finding into an inner class before further refactoring
---
 .../apache/james/json/JsonGenericSerializer.java   | 54 ++++++++++++++--------
 1 file changed, 35 insertions(+), 19 deletions(-)

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 d3b70fd..e84630f 100644
--- a/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
+++ b/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
@@ -40,6 +40,32 @@ import com.google.common.collect.ImmutableSet;
 
 public class JsonGenericSerializer<T, U extends DTO> {
 
+    private static class DTOConverter<T, U extends DTO> {
+
+        private final Map<String, DTOModule<T, U>> typeToModule;
+        private final Map<Class<? extends T>, DTOModule<T, U>> domainClassToModule;
+
+        public DTOConverter(Set<DTOModule<T, U>> modules) {
+            typeToModule = modules.stream()
+                .collect(Guavate.toImmutableMap(
+                    DTOModule::getDomainObjectType,
+                    Function.identity()));
+
+            domainClassToModule = modules.stream()
+                .collect(Guavate.toImmutableMap(
+                    DTOModule::getDomainObjectClass,
+                    Function.identity()));
+        }
+
+        public Optional<DTOModule<T, U>> findModule(T domainObject) {
+            return Optional.ofNullable(domainClassToModule.get(domainObject.getClass()));
+        }
+
+        public Optional<DTOModule<T, U>> findModule(String type) {
+            return Optional.ofNullable(typeToModule.get(type));
+        }
+    }
+
     public static class InvalidTypeException extends RuntimeException {
         public InvalidTypeException(String message) {
             super(message);
@@ -56,9 +82,8 @@ public class JsonGenericSerializer<T, U extends DTO> {
         }
     }
 
-    private final Map<Class<? extends T>, DTOModule<T, U>> domainClassToModule;
-    private final Map<String, DTOModule<T, U>> typeToModule;
     private final ObjectMapper objectMapper;
+    private final DTOConverter<T, U> dtoConverter;
 
     @SafeVarargs
     public static <T, U extends DTO> JsonGenericSerializer<T, U> of(DTOModule<T, U>... modules) {
@@ -73,24 +98,17 @@ public class JsonGenericSerializer<T, U extends DTO> {
         objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
         objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
         objectMapper.enable(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY);
-        typeToModule = modules.stream()
-            .collect(Guavate.toImmutableMap(
-                DTOModule::getDomainObjectType,
-                Function.identity()));
-
-        domainClassToModule = modules.stream()
-            .collect(Guavate.toImmutableMap(
-                DTOModule::getDomainObjectClass,
-                Function.identity()));
+        dtoConverter = new DTOConverter<>(modules);
     }
 
     public String serialize(T domainObject) throws JsonProcessingException {
-        U dto = Optional.ofNullable(domainClassToModule.get(domainObject.getClass()))
-            .orElseThrow(() -> new UnknownTypeException("unknown type " + domainObject.getClass()))
-            .toDTO(domainObject);
+        U dto = dtoConverter.findModule(domainObject)
+            .map(module -> module.toDTO(domainObject))
+            .orElseThrow(() -> new UnknownTypeException("unknown type " + domainObject.getClass()));
         return objectMapper.writeValueAsString(dto);
     }
 
+
     public T deserialize(String value) throws IOException {
         try {
             JsonNode jsonNode = objectMapper.readTree(value);
@@ -101,7 +119,9 @@ public class JsonGenericSerializer<T, U extends DTO> {
                 throw new InvalidTypeException("No \"type\" property found in the json document");
             }
 
-            DTOModule<T, U> dtoModule = retrieveModuleForType(typeNode.asText());
+            String type = typeNode.asText();
+            DTOModule<T, U> dtoModule = dtoConverter.findModule(type)
+                .orElseThrow(() -> new UnknownTypeException("unknown type " + type));
             U dto = objectMapper.readValue(objectMapper.treeAsTokens(jsonNode), dtoModule.getDTOClass());
             return dtoModule.getToDomainObjectConverter().convert(dto);
         } catch (MismatchedInputException e) {
@@ -109,8 +129,4 @@ public class JsonGenericSerializer<T, U extends DTO> {
         }
     }
 
-    private DTOModule<T, U> retrieveModuleForType(String type) {
-        return Optional.ofNullable(typeToModule.get(type))
-            .orElseThrow(() -> new UnknownTypeException("unknown type " + type));
-    }
 }


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