You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ma...@apache.org on 2020/02/27 16:20:26 UTC

[james-project] 05/14: JAMES-3009 convert to scala JsonEventSerializer

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

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

commit 3df117d440d073a04dfebd44cf3e088bd591ed7b
Author: Rémi KOWALSKI <rk...@linagora.com>
AuthorDate: Tue Dec 10 12:15:14 2019 +0100

    JAMES-3009 convert to scala JsonEventSerializer
---
 .../eventstore/cassandra/EventNestedTypes.java     |  20 +---
 .../eventstore/cassandra/JsonEventSerializer.java  | 109 -----------------
 .../eventstore/cassandra/JsonEventSerializer.scala |  87 ++++++++++++++
 .../apache/james/json/JsonGenericSerializer.java   |   6 +-
 .../apache/james/JsonGenericSerializerTest.java    |   6 +-
 .../org/apache/james/CassandraJamesServerMain.java |   5 +-
 .../data/CassandraDLPConfigurationStoreModule.java |   4 +-
 .../james/modules/data/CassandraJmapModule.java    |   4 +-
 .../eventstore/CassandraEventStoreModule.java      |   4 +-
 .../mailbox/CassandraQuotaMailingModule.java       |   4 +-
 .../james/modules/TaskSerializationModule.java     | 129 +++++++++++----------
 .../james/modules/rabbitmq/RabbitMQModule.java     |   4 +-
 .../distributed/TasksSerializationModule.java      |  16 +--
 .../distributed/DistributedTaskManagerTest.java    |   4 +-
 .../RabbitMQTerminationSubscriberTest.java         |   3 +-
 .../distributed/TaskEventsSerializationTest.java   |   6 +-
 .../JsonTaskAdditionalInformationSerializer.java   |   4 +-
 .../james/server/task/json/JsonTaskSerializer.java |   2 +-
 18 files changed, 199 insertions(+), 218 deletions(-)

diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaMailingModule.java b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/EventNestedTypes.java
similarity index 62%
copy from server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaMailingModule.java
copy to event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/EventNestedTypes.java
index ecc2a35..30e0b94 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaMailingModule.java
+++ b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/EventNestedTypes.java
@@ -16,22 +16,8 @@
  * specific language governing permissions and limitations      *
  * under the License.                                           *
  ****************************************************************/
+package org.apache.james.eventsourcing.eventstore.cassandra;
 
-package org.apache.james.modules.mailbox;
-
-import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
-import org.apache.james.mailbox.quota.cassandra.dto.QuotaEventDTOModules;
-
-import com.google.inject.AbstractModule;
-import com.google.inject.TypeLiteral;
-import com.google.inject.multibindings.Multibinder;
-
-public class CassandraQuotaMailingModule extends AbstractModule {
-    @Override
-    protected void configure() {
-        Multibinder<EventDTOModule<?, ?>> eventDTOModuleBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<?, ?>>() {});
-
-        eventDTOModuleBinder.addBinding()
-            .toInstance(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE);
-    }
+public interface EventNestedTypes {
+    String EVENT_NESTED_TYPES_INJECTION_NAME = "EventNestedTypes";
 }
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
deleted file mode 100644
index b1bb6bc..0000000
--- a/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.java
+++ /dev/null
@@ -1,109 +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.eventsourcing.eventstore.cassandra;
-
-import java.io.IOException;
-import java.util.Arrays;
-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;
-import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
-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 final String EVENT_NESTED_TYPES_INJECTION_NAME = "EventNestedTypes";
-
-    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);
-        }
-    }
-
-    public static class UnknownEventException extends RuntimeException {
-        public UnknownEventException(JsonGenericSerializer.UnknownTypeException original) {
-            super(original);
-        }
-    }
-
-    private JsonGenericSerializer<Event, EventDTO> jsonGenericSerializer;
-
-    @Inject
-    private JsonEventSerializer(Set<EventDTOModule<?, ?>> modules, @Named(EVENT_NESTED_TYPES_INJECTION_NAME) Set<DTOModule<?, ?>> nestedTypesModules) {
-        jsonGenericSerializer = JsonGenericSerializer.forModules(modules).withNestedTypeModules(nestedTypesModules);
-    }
-    
-    public String serialize(Event event) throws JsonProcessingException {
-        try {
-            return jsonGenericSerializer.serialize(event);
-        } catch (JsonGenericSerializer.UnknownTypeException e) {
-            throw new UnknownEventException(e);
-        }
-    }
-
-    public Event deserialize(String value) throws IOException {
-        try {
-            return jsonGenericSerializer.deserialize(value);
-        } catch (JsonGenericSerializer.UnknownTypeException e) {
-            throw new UnknownEventException(e);
-        } catch (JsonGenericSerializer.InvalidTypeException e) {
-            throw new InvalidEventException(e);
-        }
-    }
-
-}
diff --git a/event-sourcing/event-store-cassandra/src/main/scala/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.scala b/event-sourcing/event-store-cassandra/src/main/scala/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.scala
new file mode 100644
index 0000000..fe28295
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/main/scala/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.scala
@@ -0,0 +1,87 @@
+ /***************************************************************
+ * 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.eventsourcing.eventstore.cassandra
+
+import java.io.IOException
+import java.util
+
+import com.fasterxml.jackson.core.JsonProcessingException
+import com.google.common.collect.ImmutableSet
+import javax.inject.{Inject, Named}
+import org.apache.james.eventsourcing.Event
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.{EventDTO, EventDTOModule}
+import org.apache.james.json.{DTO, DTOModule, JsonGenericSerializer}
+
+import scala.annotation.varargs
+import scala.jdk.CollectionConverters._
+
+object JsonEventSerializer {
+
+  def forModules(modules: util.Set[_ <: EventDTOModule[_ <: Event, _ <: EventDTO]]): RequireNestedConfiguration =
+    (nestedTypesModules: util.Set[DTOModule[_, _ <: DTO]]) =>
+      new JsonEventSerializer(ImmutableSet.copyOf(modules), ImmutableSet.copyOf(nestedTypesModules))
+
+  @SafeVarargs
+  @varargs
+  def forModules(modules: EventDTOModule[_ <: Event, _ <: EventDTO]*): RequireNestedConfiguration = forModules(ImmutableSet.copyOf(modules.toArray))
+
+  trait RequireNestedConfiguration {
+    def withNestedTypeModules(modules: util.Set[DTOModule[_, _ <: DTO]]): JsonEventSerializer
+
+    def withNestedTypeModules(modules: Set[DTOModule[_, _ <: DTO]]): JsonEventSerializer = withNestedTypeModules(modules.asJava)
+
+    @varargs
+    def withListOfNestedTypeModules(modules: DTOModule[_, _ <: DTO]*): JsonEventSerializer = withNestedTypeModules(ImmutableSet.copyOf(modules.toArray))
+
+    @varargs
+    def withNestedTypeModules(modules: util.Set[DTOModule[_, _ <: DTO]]*): JsonEventSerializer = withNestedTypeModules(modules.toList.flatMap(_.asScala).toSet)
+
+    def withoutNestedType: JsonEventSerializer = withNestedTypeModules(Set[DTOModule[_, _ <: DTO]]())
+  }
+
+  class InvalidEventException(original: JsonGenericSerializer.InvalidTypeException) extends RuntimeException(original)
+
+  class UnknownEventException(original: JsonGenericSerializer.UnknownTypeException) extends RuntimeException(original)
+
+}
+
+class JsonEventSerializer @Inject()private(modules: util.Set[EventDTOModule[_ <: Event, _ <: EventDTO]],
+                                            @Named(EventNestedTypes.EVENT_NESTED_TYPES_INJECTION_NAME)
+                                            nestedTypesModules: util.Set[DTOModule[_, _ <: DTO]]) {
+
+  private val jsonGenericSerializer: JsonGenericSerializer[Event, EventDTO] = JsonGenericSerializer
+    .forModules(modules)
+    .withNestedTypeModules(nestedTypesModules)
+
+  @throws[JsonProcessingException]
+  def serialize(event: Event): String = try jsonGenericSerializer.serialize(event)
+  catch {
+    case e: JsonGenericSerializer.UnknownTypeException =>
+      throw new JsonEventSerializer.UnknownEventException(e)
+  }
+
+  @throws[IOException]
+  def deserialize(value: String): Event = try jsonGenericSerializer.deserialize(value)
+  catch {
+    case e: JsonGenericSerializer.UnknownTypeException =>
+      throw new JsonEventSerializer.UnknownEventException(e)
+    case e: JsonGenericSerializer.InvalidTypeException =>
+      throw new JsonEventSerializer.InvalidEventException(e)
+  }
+}
\ No newline at end of file
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 371e887..6c05ebf 100644
--- a/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
+++ b/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
@@ -44,7 +44,7 @@ import com.google.common.collect.Sets;
 
 public class JsonGenericSerializer<T, U extends DTO> {
 
-    public static <T, U extends DTO> RequireNestedConfiguration<T, U> forModules(java.util.Set<? extends DTOModule<? extends T, ? extends U>> modules) {
+    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));
@@ -59,11 +59,11 @@ public class JsonGenericSerializer<T, U extends DTO> {
     public interface RequireNestedConfiguration<T, U extends DTO> {
         JsonGenericSerializer<T, U> withNestedTypeModules(Set<DTOModule<?, ?>> modules);
 
-        default JsonGenericSerializer<T, U> withNestedTypeModules(DTOModule<?, ?>... modules) {
+        default JsonGenericSerializer<T, U> withMultipleNestedTypeModules(DTOModule<?, ?>... modules) {
             return withNestedTypeModules(ImmutableSet.copyOf(modules));
         }
 
-        default JsonGenericSerializer<T, U> withNestedTypeModules(Set<DTOModule<?, ?>>... modules) {
+        default JsonGenericSerializer<T, U> withMultipleNestedTypeModules(Set<DTOModule<?, ?>>... modules) {
             return withNestedTypeModules(Arrays.stream(modules).flatMap(Collection::stream).collect(Guavate.toImmutableSet()));
         }
 
diff --git a/json/src/test/java/org/apache/james/JsonGenericSerializerTest.java b/json/src/test/java/org/apache/james/JsonGenericSerializerTest.java
index 14e528a..3a2c8ad 100644
--- a/json/src/test/java/org/apache/james/JsonGenericSerializerTest.java
+++ b/json/src/test/java/org/apache/james/JsonGenericSerializerTest.java
@@ -57,7 +57,7 @@ class JsonGenericSerializerTest {
     void shouldDeserializeNestedTypeWithSecond() throws Exception {
         assertThat(JsonGenericSerializer
             .forModules(TestModules.FIRST_TYPE, TestModules.SECOND_TYPE)
-            .withNestedTypeModules(TestModules.FIRST_NESTED, TestModules.SECOND_NESTED)
+            .withMultipleNestedTypeModules(TestModules.FIRST_NESTED, TestModules.SECOND_NESTED)
             .deserialize(SECOND_WITH_NESTED_JSON))
             .isEqualTo(SECOND_WITH_NESTED);
     }
@@ -66,7 +66,7 @@ class JsonGenericSerializerTest {
     void shouldDeserializeNestedTypeWithFirst() throws Exception {
         assertThat(JsonGenericSerializer
             .forModules(TestModules.FIRST_TYPE, TestModules.SECOND_TYPE)
-            .withNestedTypeModules(TestModules.FIRST_NESTED, TestModules.SECOND_NESTED)
+            .withMultipleNestedTypeModules(TestModules.FIRST_NESTED, TestModules.SECOND_NESTED)
             .deserialize(FIRST_JSON_WITH_NESTED))
             .isEqualTo(FIRST_WITH_NESTED);
     }
@@ -152,7 +152,7 @@ class JsonGenericSerializerTest {
     void shouldThrowWhenRegisteringDuplicateTypeIds() {
         assertThatThrownBy(() -> JsonGenericSerializer
             .forModules(TestModules.FIRST_NESTED)
-            .withNestedTypeModules(TestModules.FIRST_NESTED))
+            .withMultipleNestedTypeModules(TestModules.FIRST_NESTED))
             .isInstanceOf(IllegalArgumentException.class);
     }
 
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 05e07ea..1f5cd85 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,10 +19,9 @@
 
 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.eventsourcing.eventstore.cassandra.EventNestedTypes;
 import org.apache.james.json.DTOModule;
 import org.apache.james.modules.BlobExportMechanismModule;
 import org.apache.james.modules.MailboxModule;
@@ -116,7 +115,7 @@ public class CassandraJamesServerMain {
         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))
+        binder.bind(new TypeLiteral<Set<DTOModule<?, ? extends org.apache.james.json.DTO>>>() {}).annotatedWith(Names.named(EventNestedTypes.EVENT_NESTED_TYPES_INJECTION_NAME))
             .toInstance(ImmutableSet.of());
 
     public static final Module CASSANDRA_SERVER_CORE_MODULE = Modules.combine(
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDLPConfigurationStoreModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDLPConfigurationStoreModule.java
index 4a97f5e..f6fb7eb 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDLPConfigurationStoreModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDLPConfigurationStoreModule.java
@@ -22,6 +22,8 @@ package org.apache.james.modules.data;
 import org.apache.james.dlp.api.DLPConfigurationStore;
 import org.apache.james.dlp.eventsourcing.EventSourcingDLPConfigurationStore;
 import org.apache.james.dlp.eventsourcing.cassandra.DLPConfigurationModules;
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
 
 import com.google.inject.AbstractModule;
@@ -36,7 +38,7 @@ public class CassandraDLPConfigurationStoreModule extends AbstractModule {
         bind(EventSourcingDLPConfigurationStore.class).in(Scopes.SINGLETON);
         bind(DLPConfigurationStore.class).to(EventSourcingDLPConfigurationStore.class);
 
-        Multibinder<EventDTOModule<?, ?>> eventDTOModuleBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<?, ?>>() {});
+        Multibinder<EventDTOModule<? extends Event, ? extends EventDTO>> eventDTOModuleBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<? extends Event, ? extends EventDTO>>() {});
 
         eventDTOModuleBinder.addBinding().toInstance(DLPConfigurationModules.DLP_CONFIGURATION_STORE);
         eventDTOModuleBinder.addBinding().toInstance(DLPConfigurationModules.DLP_CONFIGURATION_CLEAR);
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java
index 01408b0..fa055af 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java
@@ -21,6 +21,8 @@ package org.apache.james.modules.data;
 
 import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.core.healthcheck.HealthCheck;
+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.jmap.api.access.AccessTokenRepository;
 import org.apache.james.jmap.api.filtering.FilteringManagement;
@@ -73,7 +75,7 @@ public class CassandraJmapModule extends AbstractModule {
         cassandraDataDefinitions.addBinding().toInstance(CassandraNotificationRegistryModule.MODULE);
         cassandraDataDefinitions.addBinding().toInstance(CassandraMessageFastViewProjectionModule.MODULE);
 
-        Multibinder<EventDTOModule<?, ?>> eventDTOModuleBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<?, ?>>() {});
+        Multibinder<EventDTOModule<? extends Event, ? extends EventDTO>> eventDTOModuleBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<? extends Event, ? extends EventDTO>>() {});
         eventDTOModuleBinder.addBinding().toInstance(FilteringRuleSetDefineDTOModules.FILTERING_RULE_SET_DEFINED);
     }
 }
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/eventstore/CassandraEventStoreModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/eventstore/CassandraEventStoreModule.java
index aa48baf..164ccd8 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/eventstore/CassandraEventStoreModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/eventstore/CassandraEventStoreModule.java
@@ -20,8 +20,10 @@
 package org.apache.james.modules.eventstore;
 
 import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.eventsourcing.Event;
 import org.apache.james.eventsourcing.eventstore.EventStore;
 import org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStore;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
 
 import com.google.inject.AbstractModule;
@@ -40,6 +42,6 @@ public class CassandraEventStoreModule extends AbstractModule {
             .addBinding()
             .toInstance(org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStoreModule.MODULE());
 
-        Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<?, ?>>() {});
+        Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<? extends Event, ? extends EventDTO>>() {});
     }
 }
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaMailingModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaMailingModule.java
index ecc2a35..2130062 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaMailingModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaMailingModule.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.modules.mailbox;
 
+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.mailbox.quota.cassandra.dto.QuotaEventDTOModules;
 
@@ -29,7 +31,7 @@ import com.google.inject.multibindings.Multibinder;
 public class CassandraQuotaMailingModule extends AbstractModule {
     @Override
     protected void configure() {
-        Multibinder<EventDTOModule<?, ?>> eventDTOModuleBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<?, ?>>() {});
+        Multibinder<EventDTOModule<? extends Event, ? extends EventDTO>> eventDTOModuleBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<? extends Event, ? extends EventDTO>>() {});
 
         eventDTOModuleBinder.addBinding()
             .toInstance(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE);
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 1346bc1..30ef794 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,8 +18,6 @@
  ****************************************************************/
 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;
 
@@ -28,6 +26,9 @@ 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.Event;
+import org.apache.james.eventsourcing.eventstore.cassandra.EventNestedTypes;
+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;
@@ -113,310 +114,310 @@ public class TaskSerializationModule extends AbstractModule {
 
     @Provides
     @Singleton
-    public DTOConverter<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> additionalInformationDTOConverter(Set<AdditionalInformationDTOModule<?, ?>> modules) {
+    public DTOConverter<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> additionalInformationDTOConverter(Set<AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends AdditionalInformationDTO>> modules) {
         return new DTOConverter<>(modules);
     }
 
     @Provides
     @Singleton
-    public DTOConverter<Task, TaskDTO> taskDTOConverter(Set<TaskDTOModule<?, ?>> taskDTOModules) {
+    public DTOConverter<Task, TaskDTO> taskDTOConverter(Set<TaskDTOModule<? extends Task, ? extends TaskDTO>> taskDTOModules) {
         return new DTOConverter<>(taskDTOModules);
 
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskCreatedSerialization(JsonTaskSerializer jsonTaskSerializer,
-                                                         DTOConverter<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> additionalInformationConverter,
-                                                         DTOConverter<Task, TaskDTO> taskConverter) {
+    public EventDTOModule<? extends Event, ? extends EventDTO> taskCreatedSerialization(JsonTaskSerializer jsonTaskSerializer,
+                                                                                        DTOConverter<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> additionalInformationConverter,
+                                                                                        DTOConverter<Task, TaskDTO> taskConverter) {
         return TasksSerializationModule.CREATED.create(jsonTaskSerializer, additionalInformationConverter, taskConverter);
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskStartedSerialization(JsonTaskSerializer jsonTaskSerializer,
+    public EventDTOModule<? extends Event, ? extends EventDTO> taskStartedSerialization(JsonTaskSerializer jsonTaskSerializer,
                                                          DTOConverter<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> additionalInformationConverter,
                                                          DTOConverter<Task, TaskDTO> taskConverter) {
         return TasksSerializationModule.STARTED.create(jsonTaskSerializer, additionalInformationConverter, taskConverter);
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskCancelRequestedSerialization(JsonTaskSerializer jsonTaskSerializer,
+    public EventDTOModule<? extends Event, ? extends EventDTO> taskCancelRequestedSerialization(JsonTaskSerializer jsonTaskSerializer,
                                                                  DTOConverter<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> additionalInformationConverter,
                                                                  DTOConverter<Task, TaskDTO> taskConverter) {
         return TasksSerializationModule.CANCEL_REQUESTED.create(jsonTaskSerializer, additionalInformationConverter, taskConverter);
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskCancelledSerialization(JsonTaskSerializer jsonTaskSerializer,
+    public EventDTOModule<? extends Event, ? extends EventDTO> taskCancelledSerialization(JsonTaskSerializer jsonTaskSerializer,
                                                            DTOConverter<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> additionalInformationConverter,
                                                            DTOConverter<Task, TaskDTO> taskConverter) {
         return TasksSerializationModule.CANCELLED.create(jsonTaskSerializer, additionalInformationConverter, taskConverter);
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskCompletedSerialization(JsonTaskSerializer jsonTaskSerializer,
+    public EventDTOModule<? extends Event, ? extends EventDTO> taskCompletedSerialization(JsonTaskSerializer jsonTaskSerializer,
                                                            DTOConverter<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> additionalInformationConverter,
                                                            DTOConverter<Task, TaskDTO> taskConverter) {
         return TasksSerializationModule.COMPLETED.create(jsonTaskSerializer, additionalInformationConverter, taskConverter);
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskFailedSerialization(JsonTaskSerializer jsonTaskSerializer,
+    public EventDTOModule<? extends Event, ? extends EventDTO> taskFailedSerialization(JsonTaskSerializer jsonTaskSerializer,
                                                         DTOConverter<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> additionalInformationConverter,
                                                         DTOConverter<Task, TaskDTO> taskConverter) {
         return TasksSerializationModule.FAILED.create(jsonTaskSerializer, additionalInformationConverter, taskConverter);
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskUpdatedSerialization(JsonTaskSerializer jsonTaskSerializer,
+    public EventDTOModule<? extends Event, ? extends EventDTO> taskUpdatedSerialization(JsonTaskSerializer jsonTaskSerializer,
                                                         DTOConverter<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> additionalInformationConverter,
                                                         DTOConverter<Task, TaskDTO> taskConverter) {
         return TasksSerializationModule.UPDATED.create(jsonTaskSerializer, additionalInformationConverter, taskConverter);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> blobStoreVaultGarbageCollectionTask(BlobStoreVaultGarbageCollectionTask.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> blobStoreVaultGarbageCollectionTask(BlobStoreVaultGarbageCollectionTask.Factory factory) {
         return BlobStoreVaultGarbageCollectionTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> cassandraMappingsSolveInconsistenciesTask(MappingsSourcesMigration migration, CassandraMappingsSourcesDAO dao) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> cassandraMappingsSolveInconsistenciesTask(MappingsSourcesMigration migration, CassandraMappingsSourcesDAO dao) {
         return CassandraMappingsSolveInconsistenciesTask.module(migration, dao);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> clearMailQueueTask(MailQueueFactory<? extends ManageableMailQueue> mailQueueFactory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> clearMailQueueTask(MailQueueFactory<? extends ManageableMailQueue> mailQueueFactory) {
         return ClearMailQueueTaskDTO.module(mailQueueFactory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> recomputeAllJmapPreviewsTask(MessageFastViewProjectionCorrector corrector) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> recomputeAllJmapPreviewsTask(MessageFastViewProjectionCorrector corrector) {
         return RecomputeAllFastViewProjectionItemsTask.module(corrector);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> recomputeUserJmapPreviewsTask(MessageFastViewProjectionCorrector corrector) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> recomputeUserJmapPreviewsTask(MessageFastViewProjectionCorrector corrector) {
         return RecomputeUserFastViewProjectionItemsTask.module(corrector);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> clearMailRepositoryTask(ClearMailRepositoryTask.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> clearMailRepositoryTask(ClearMailRepositoryTask.Factory factory) {
         return ClearMailRepositoryTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> deleteMailsFromMailQueueTask(MailQueueFactory<? extends ManageableMailQueue> mailQueueFactory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> deleteMailsFromMailQueueTask(MailQueueFactory<? extends ManageableMailQueue> mailQueueFactory) {
         return DeleteMailsFromMailQueueTaskDTO.module(mailQueueFactory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> deletedMessagesVaultDeleteTask(DeletedMessagesVaultDeleteTask.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> deletedMessagesVaultDeleteTask(DeletedMessagesVaultDeleteTask.Factory factory) {
         return DeletedMessagesVaultDeleteTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> deletedMessagesVaultExportTask(DeletedMessagesVaultExportTaskDTO.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> deletedMessagesVaultExportTask(DeletedMessagesVaultExportTaskDTO.Factory factory) {
         return DeletedMessagesVaultExportTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> deletedMessagesVaultRestoreTask(DeletedMessagesVaultRestoreTaskDTO.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> deletedMessagesVaultRestoreTask(DeletedMessagesVaultRestoreTaskDTO.Factory factory) {
         return DeletedMessagesVaultRestoreTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> eventDeadLettersRedeliverAllTask(EventDeadLettersRedeliverService service) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> eventDeadLettersRedeliverAllTask(EventDeadLettersRedeliverService service) {
         return EventDeadLettersRedeliverAllTaskDTO.module(service);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> eventDeadLettersRedeliverGroupTask(EventDeadLettersRedeliverService service) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> eventDeadLettersRedeliverGroupTask(EventDeadLettersRedeliverService service) {
         return EventDeadLettersRedeliverGroupTaskDTO.module(service);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> eventDeadLettersRedeliverOneTask(EventDeadLettersRedeliverService service) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> eventDeadLettersRedeliverOneTask(EventDeadLettersRedeliverService service) {
         return EventDeadLettersRedeliverOneTaskDTO.module(service);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> fullReindexTask(ReIndexerPerformer performer) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> fullReindexTask(ReIndexerPerformer performer) {
         return FullReindexingTask.module(performer);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> errorRecoveryIndexationTask(ErrorRecoveryIndexationTask.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> errorRecoveryIndexationTask(ErrorRecoveryIndexationTask.Factory factory) {
         return ErrorRecoveryIndexationTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> mailboxMergingTask(MailboxMergingTaskRunner taskRunner) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> mailboxMergingTask(MailboxMergingTaskRunner taskRunner) {
         return MailboxMergingTaskDTO.module(taskRunner);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> solveMailboxInconsistenciesTask(SolveMailboxInconsistenciesService service) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> solveMailboxInconsistenciesTask(SolveMailboxInconsistenciesService service) {
         return SolveMailboxInconsistenciesTaskDTO.module(service);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> messageIdReindexingTask(MessageIdReIndexingTask.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> messageIdReindexingTask(MessageIdReIndexingTask.Factory factory) {
         return MessageIdReindexingTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> migrationTask(MigrationTask.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> migrationTask(MigrationTask.Factory factory) {
         return MigrationTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> reprocessingAllMailsTask(ReprocessingService reprocessingService) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> reprocessingAllMailsTask(ReprocessingService reprocessingService) {
         return ReprocessingAllMailsTaskDTO.module(reprocessingService);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> reprocessingOneMailsTask(ReprocessingService reprocessingService) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> reprocessingOneMailsTask(ReprocessingService reprocessingService) {
         return ReprocessingOneMailTaskDTO.module(Clock.systemUTC(), reprocessingService);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> singleMailboxReindexingTask(SingleMailboxReindexingTask.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> singleMailboxReindexingTask(SingleMailboxReindexingTask.Factory factory) {
         return SingleMailboxReindexingTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> singleMessageReindexingTask(SingleMessageReindexingTask.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> singleMessageReindexingTask(SingleMessageReindexingTask.Factory factory) {
         return SingleMessageReindexingTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> userReindexingTask(UserReindexingTask.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> userReindexingTask(UserReindexingTask.Factory factory) {
         return UserReindexingTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> blobStoreVaultGarbageCollectionAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> blobStoreVaultGarbageCollectionAdditionalInformation() {
         return BlobStoreVaultGarbageCollectionTaskAdditionalInformationDTO.MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> cassandraMappingsSolveInconsistenciesAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> cassandraMappingsSolveInconsistenciesAdditionalInformation() {
         return MappingsSourcesMigrationTaskAdditionalInformationDTO.serializationModule(CassandraMappingsSolveInconsistenciesTask.TYPE);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> clearMailQueueAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> clearMailQueueAdditionalInformation() {
         return ClearMailQueueTaskAdditionalInformationDTO.SERIALIZATION_MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> clearMailRepositoryAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> clearMailRepositoryAdditionalInformation() {
         return ClearMailRepositoryTaskAdditionalInformationDTO.SERIALIZATION_MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> deleteMailsFromMailQueueAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> deleteMailsFromMailQueueAdditionalInformation() {
         return DeleteMailsFromMailQueueTaskAdditionalInformationDTO.MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> deletedMessagesVaultDeleteAdditionalInformation(MessageId.Factory factory) {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> deletedMessagesVaultDeleteAdditionalInformation(MessageId.Factory factory) {
         return DeletedMessagesVaultDeleteTaskAdditionalInformationDTO.serializationModule(factory);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> deletedMessagesVaultExportAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> deletedMessagesVaultExportAdditionalInformation() {
         return DeletedMessagesVaultExportTaskAdditionalInformationDTO.MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> deletedMessagesVaultRestoreAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> deletedMessagesVaultRestoreAdditionalInformation() {
         return DeletedMessagesVaultRestoreTaskAdditionalInformationDTO.MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> errorRecoveryAdditionalInformation(MailboxId.Factory mailboxIdFactory) {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> errorRecoveryAdditionalInformation(MailboxId.Factory mailboxIdFactory) {
         return ReprocessingContextInformationDTO.ReprocessingContextInformationForErrorRecoveryIndexationTask.serializationModule(mailboxIdFactory);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> eventDeadLettersRedeliveryAdditionalInformationForAll() {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> eventDeadLettersRedeliveryAdditionalInformationForAll() {
         return EventDeadLettersRedeliveryTaskAdditionalInformationDTO.EventDeadLettersRedeliveryTaskAdditionalInformationForAll.MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> eventDeadLettersRedeliveryAdditionalInformationForGroup() {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> eventDeadLettersRedeliveryAdditionalInformationForGroup() {
         return EventDeadLettersRedeliveryTaskAdditionalInformationDTO.EventDeadLettersRedeliveryTaskAdditionalInformationForGroup.MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> eventDeadLettersRedeliveryAdditionalInformationForOne() {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> eventDeadLettersRedeliveryAdditionalInformationForOne() {
         return EventDeadLettersRedeliveryTaskAdditionalInformationDTO.EventDeadLettersRedeliveryTaskAdditionalInformationForOne.MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> fullReindexAdditionalInformation(MailboxId.Factory mailboxIdFactory) {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> fullReindexAdditionalInformation(MailboxId.Factory mailboxIdFactory) {
         return ReprocessingContextInformationDTO.ReprocessingContextInformationForFullReindexingTask.serializationModule(mailboxIdFactory);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> mailboxMergingAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> mailboxMergingAdditionalInformation() {
         return MailboxMergingTaskAdditionalInformationDTO.SERIALIZATION_MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> solveMailboxInconsistenciesAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> solveMailboxInconsistenciesAdditionalInformation() {
         return SolveMailboxInconsistenciesTaskAdditionalInformationDTO.MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> messageIdReindexingAdditionalInformation(MessageId.Factory messageIdFactory) {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> messageIdReindexingAdditionalInformation(MessageId.Factory messageIdFactory) {
         return MessageIdReindexingTaskAdditionalInformationDTO.serializationModule(messageIdFactory);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> migrationTaskAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> migrationTaskAdditionalInformation() {
         return MigrationTaskAdditionalInformationDTO.serializationModule();
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> reprocessingAllMailsAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> reprocessingAllMailsAdditionalInformation() {
         return ReprocessingAllMailsTaskAdditionalInformationDTO.SERIALIZATION_MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> reprocessingOneMailAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> reprocessingOneMailAdditionalInformation() {
         return ReprocessingOneMailTaskAdditionalInformationDTO.SERIALIZATION_MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> singleMailboxReindexingAdditionalInformation(MailboxId.Factory mailboxIdFactory) {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> singleMailboxReindexingAdditionalInformation(MailboxId.Factory mailboxIdFactory) {
         return SingleMailboxReindexingTaskAdditionalInformationDTO.serializationModule(mailboxIdFactory);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> singleMessageReindexingAdditionalInformation(MailboxId.Factory mailboxIdFactory) {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> singleMessageReindexingAdditionalInformation(MailboxId.Factory mailboxIdFactory) {
         return SingleMessageReindexingTaskAdditionalInformationDTO.serializationModule(mailboxIdFactory);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> userReindexingAdditionalInformation(MailboxId.Factory mailboxIdFactory) {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> userReindexingAdditionalInformation(MailboxId.Factory mailboxIdFactory) {
         return UserReindexingTaskAdditionalInformationDTO.serializationModule(mailboxIdFactory);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> recomputeAllJmapPreviewsAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> recomputeAllJmapPreviewsAdditionalInformation() {
         return RecomputeAllFastViewTaskAdditionalInformationDTO.SERIALIZATION_MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> recomputeUserJmapPreviewsAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO> recomputeUserJmapPreviewsAdditionalInformation() {
         return RecomputeUserFastViewTaskAdditionalInformationDTO.SERIALIZATION_MODULE;
     }
 
-    @Named(EVENT_NESTED_TYPES_INJECTION_NAME)
+    @Named(EventNestedTypes.EVENT_NESTED_TYPES_INJECTION_NAME)
     @Provides
-    public Set<DTOModule<?, ?>> eventNestedTypes(Set<AdditionalInformationDTOModule<?, ?>> additionalInformationDTOModules,
-                                                 Set<TaskDTOModule<?, ?>> taskDTOModules) {
+    public Set<DTOModule<?, ? extends org.apache.james.json.DTO>> eventNestedTypes(Set<AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends  AdditionalInformationDTO>> additionalInformationDTOModules,
+                                                                                   Set<TaskDTOModule<? extends Task, ? extends TaskDTO>> taskDTOModules) {
         return Sets.union(additionalInformationDTOModules, taskDTOModules);
     }
 }
diff --git a/server/container/guice/rabbitmq/src/main/java/org/apache/james/modules/rabbitmq/RabbitMQModule.java b/server/container/guice/rabbitmq/src/main/java/org/apache/james/modules/rabbitmq/RabbitMQModule.java
index e887d6a..ea8c317 100644
--- a/server/container/guice/rabbitmq/src/main/java/org/apache/james/modules/rabbitmq/RabbitMQModule.java
+++ b/server/container/guice/rabbitmq/src/main/java/org/apache/james/modules/rabbitmq/RabbitMQModule.java
@@ -30,6 +30,8 @@ import org.apache.james.backends.rabbitmq.RabbitMQConfiguration;
 import org.apache.james.backends.rabbitmq.RabbitMQHealthCheck;
 import org.apache.james.backends.rabbitmq.ReactorRabbitMQChannelPool;
 import org.apache.james.core.healthcheck.HealthCheck;
+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.queue.api.MailQueueFactory;
 import org.apache.james.queue.api.ManageableMailQueue;
@@ -81,7 +83,7 @@ public class RabbitMQModule extends AbstractModule {
         cassandraModuleBinder.addBinding().toInstance(CassandraMailQueueViewModule.MODULE);
 
         bind(EventsourcingConfigurationManagement.class).in(Scopes.SINGLETON);
-        Multibinder<EventDTOModule<?, ?>> eventDTOModuleBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<?, ?>>() {});
+        Multibinder<EventDTOModule<? extends Event, ? extends EventDTO>> eventDTOModuleBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<? extends Event, ? extends EventDTO>>() {});
         eventDTOModuleBinder.addBinding().toInstance(CassandraMailQueueViewConfigurationModule.MAIL_QUEUE_VIEW_CONFIGURATION);
 
         Multibinder.newSetBinder(binder(), HealthCheck.class).addBinding().to(RabbitMQHealthCheck.class);
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 f158d0f..724d0a1 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
@@ -1,4 +1,4 @@
-/** **************************************************************
+/****************************************************************
  * 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        *
@@ -7,7 +7,7 @@
  * "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                   *
+ *   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  *
@@ -15,13 +15,15 @@
  * KIND, either express or implied.  See the License for the    *
  * specific language governing permissions and limitations      *
  * under the License.                                           *
- * ***************************************************************/
+ ****************************************************************/
 
 package org.apache.james.task.eventsourcing.distributed;
 
 import java.util.Set;
 import java.util.stream.Stream;
 
+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.server.task.json.JsonTaskSerializer;
@@ -42,7 +44,7 @@ import com.github.steveash.guavate.Guavate;
 public interface TasksSerializationModule {
     @FunctionalInterface
     interface TaskSerializationModuleFactory {
-        EventDTOModule<?, ?> create(JsonTaskSerializer taskSerializer,
+        EventDTOModule<? extends Event, ? extends EventDTO> create(JsonTaskSerializer taskSerializer,
                                     DTOConverter<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> additionalInformationConverter,
                                     DTOConverter<Task, TaskDTO> dtoConverter);
     }
@@ -103,9 +105,9 @@ public interface TasksSerializationModule {
         .typeName("task-manager-updated")
         .withFactory(EventDTOModule::new);
 
-    static Set<EventDTOModule<?, ?>> list(JsonTaskSerializer jsonTaskSerializer,
-                                          DTOConverter<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> additionalInformationConverter,
-                                          DTOConverter<Task, TaskDTO> dtoConverter) {
+    static Set<EventDTOModule<? extends Event, ? extends EventDTO>> list(JsonTaskSerializer jsonTaskSerializer,
+                                                                         DTOConverter<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> additionalInformationConverter,
+                                                                         DTOConverter<Task, TaskDTO> dtoConverter) {
         return Stream
             .of(CREATED, STARTED, CANCEL_REQUESTED, CANCELLED, COMPLETED, FAILED, UPDATED)
             .map(moduleFactory -> moduleFactory.create(jsonTaskSerializer, additionalInformationConverter, dtoConverter))
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 3bc1135..295d27c 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
@@ -35,11 +35,13 @@ import org.apache.james.backends.cassandra.init.CassandraZonedDateTimeModule;
 import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionModule;
 import org.apache.james.backends.rabbitmq.RabbitMQExtension;
 import org.apache.james.backends.rabbitmq.ReactorRabbitMQChannelPool;
+import org.apache.james.eventsourcing.Event;
 import org.apache.james.eventsourcing.EventSourcingSystem;
 import org.apache.james.eventsourcing.eventstore.EventStore;
 import org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStoreExtension;
 import org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStoreModule;
 import org.apache.james.eventsourcing.eventstore.cassandra.JsonEventSerializer;
+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.server.task.json.JsonTaskAdditionalInformationSerializer;
@@ -138,7 +140,7 @@ class DistributedTaskManagerTest implements TaskManagerContract {
 
     DTOConverter<Task, TaskDTO> taskDTOConverter = new DTOConverter<>(taskDTOModules);
 
-    Set<EventDTOModule<?, ?>> eventDtoModule = TasksSerializationModule.list(taskSerializer, TASK_ADDITIONAL_INFORMATION_DTO_CONVERTER, taskDTOConverter);
+    Set<EventDTOModule<? extends Event, ? extends EventDTO>> eventDtoModule = TasksSerializationModule.list(taskSerializer, TASK_ADDITIONAL_INFORMATION_DTO_CONVERTER, taskDTOConverter);
 
     @RegisterExtension
     CassandraEventStoreExtension eventStoreExtension = new CassandraEventStoreExtension(CASSANDRA_CLUSTER,
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 dcb5a36..3b7fa9b 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
@@ -30,6 +30,7 @@ import java.util.Set;
 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.EventDTO;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
 import org.apache.james.json.DTOConverter;
 import org.apache.james.server.task.json.JsonTaskSerializer;
@@ -43,7 +44,7 @@ import reactor.core.publisher.Flux;
 
 class RabbitMQTerminationSubscriberTest implements TerminationSubscriberContract {
     private static final JsonTaskSerializer TASK_SERIALIZER = JsonTaskSerializer.of();
-    private static final Set<EventDTOModule<?, ?>> MODULES = TasksSerializationModule.list(TASK_SERIALIZER, DTOConverter.of(), DTOConverter.of());
+    private static final Set<EventDTOModule<? extends Event, ? extends EventDTO>> MODULES = TasksSerializationModule.list(TASK_SERIALIZER, DTOConverter.of(), DTOConverter.of());
     private static final JsonEventSerializer SERIALIZER = JsonEventSerializer.forModules(MODULES).withoutNestedType();
 
     @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 e7cb068..2444edf 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
@@ -23,7 +23,9 @@ import java.time.Instant;
 import java.util.Set;
 
 import org.apache.james.JsonSerializationVerifier;
+import org.apache.james.eventsourcing.Event;
 import org.apache.james.eventsourcing.EventId;
+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.JsonGenericSerializer;
@@ -60,7 +62,7 @@ class TaskEventsSerializationTest {
     static final Hostname HOSTNAME = new Hostname("foo");
     static final MemoryReferenceWithCounterTask.AdditionalInformation COUNTER_ADDITIONAL_INFORMATION = new MemoryReferenceWithCounterTask.AdditionalInformation(3, TIMESTAMP);
 
-    private final Set<EventDTOModule<?, ?>> list = TasksSerializationModule.list(
+    private final Set<EventDTOModule<? extends Event, ? extends EventDTO>> list = TasksSerializationModule.list(
         JsonTaskSerializer.of(
             TestTaskDTOModules.COMPLETED_TASK_MODULE,
             TestTaskDTOModules.MEMORY_REFERENCE_WITH_COUNTER_TASK_MODULE.apply(new MemoryReferenceWithCounterTaskStore())),
@@ -71,7 +73,7 @@ class TaskEventsSerializationTest {
     void taskManagerEventsShouldBeSerializable() throws Exception {
         JsonSerializationVerifier.serializer(JsonGenericSerializer
             .forModules(list)
-            .withNestedTypeModules(
+            .withMultipleNestedTypeModules(
                 MemoryReferenceWithCounterTaskAdditionalInformationDTO.SERIALIZATION_MODULE,
                 TestTaskDTOModules.COMPLETED_TASK_MODULE))
             .testCase(new Created(AGGREGATE_ID, EVENT_ID, TASK, HOSTNAME),
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 52c0608..8019e7a 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
@@ -33,7 +33,7 @@ import com.google.common.collect.ImmutableSet;
 
 public class JsonTaskAdditionalInformationSerializer {
 
-    public static JsonTaskAdditionalInformationSerializer of(AdditionalInformationDTOModule<?, ?>... modules) {
+    public static JsonTaskAdditionalInformationSerializer of(AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends AdditionalInformationDTO>... modules) {
         return new JsonTaskAdditionalInformationSerializer(ImmutableSet.copyOf(modules));
     }
 
@@ -52,7 +52,7 @@ public class JsonTaskAdditionalInformationSerializer {
     private JsonGenericSerializer<TaskExecutionDetails.AdditionalInformation, AdditionalInformationDTO> jsonGenericSerializer;
 
     @Inject
-    private JsonTaskAdditionalInformationSerializer(Set<AdditionalInformationDTOModule<?, ?>> modules) {
+    private JsonTaskAdditionalInformationSerializer(Set<AdditionalInformationDTOModule<? extends TaskExecutionDetails.AdditionalInformation, ? extends AdditionalInformationDTO>> modules) {
         jsonGenericSerializer = JsonGenericSerializer.forModules(modules).withoutNestedType();
     }
 
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 f87bcff..2c5cceb 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
@@ -55,7 +55,7 @@ public class JsonTaskSerializer {
 
     @Inject
     @VisibleForTesting
-    public JsonTaskSerializer(Set<TaskDTOModule<?, ?>> modules) {
+    public JsonTaskSerializer(Set<TaskDTOModule<? extends Task, ? extends TaskDTO>> modules) {
         jsonGenericSerializer = JsonGenericSerializer.forModules(modules).withoutNestedType();
     }
 


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