You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2021/02/04 05:02:26 UTC

[james-project] branch master updated (e5cdea9 -> 3e3c83d)

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 e5cdea9  JAMES-3491 Experiment sttp for websocket client
     new 1bd539c  JAMES-3498 Move eventBus related classes to dedicated maven package
     new c4f6a0d  JAMES-3498 Move as is the In VM implementation
     new 4bc4038  JAMES-3498 Move as is the Distributed implementation
     new f9312df  JAMES-3498 Move as is the Cassandra implementation
     new a76f45f  JAMES-3498 Move the event-bus contracts out of mailbox-api
     new 48c939e  JAMES-3498 Introduce an EventSerializer API
     new 9f39436  JAMES-3498 event-bus-* should not depend on mailbox-*
     new 1484bec  JAMES-3498 event-bus-cassandra POM ordering
     new 6efd2a1  JAMES-3498 event-bus-distributed POM ordering
     new 082a63f  JAMES-3498 Mailbox event api should be in org.apache.james.mailbox.events
     new 267dd38  JAMES-3498 custom-listeners POM ordering
     new 7528019  JAMES-3498 Compilation fix: depend on event-bus-api test-jar
     new cfce689  JAMES-3498 Restore static imports
     new e5d675f  JAMES-3498 Restore JavaEvent convenience import
     new d2dfb31  JAMES-3498 Isolation for dead-letter queues in RabbitMQEventBusTest
     new 206f1df  JAMES-3498 Rename variable/classes to remove `mailbox` name component
     new 65ca313  JAMES-3498 Allow alternative namings for RabbitMQ queues/exchanges names
     new 3e3c83d  JAMES-3498 NamingStrategy should allow RabbitMQ eventBus isolation

The 18 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:
 .../event/event-memory => event-bus/api}/pom.xml   |  49 ++--
 .../main/java/org/apache/james}/events/Event.java  |   2 +-
 .../java/org/apache/james}/events/EventBus.java    |  26 +-
 .../org/apache/james}/events/EventDeadLetters.java |   2 +-
 .../james}/events/EventDeadLettersHealthCheck.java |   6 +-
 .../org/apache/james/events/EventListener.java     | 142 +++++++++++
 .../org/apache/james/events/EventSerializer.java   |   8 +-
 .../main/java/org/apache/james}/events/Group.java  |   4 +-
 .../james}/events/GroupAlreadyRegistered.java      |   4 +-
 .../james}/events/GroupRegistrationNotFound.java   |   4 +-
 .../org/apache/james}/events/Registration.java     |   2 +-
 .../org/apache/james}/events/RegistrationKey.java  |   2 +-
 .../james}/events/RetryBackoffConfiguration.java   |   2 +-
 .../apache/james/mailbox/events/GenericGroup.java  |   4 +-
 .../james}/events/ErrorHandlingContract.java       |  25 +-
 .../events/EventBusConcurrentTestContract.java     |  93 +++----
 .../org/apache/james}/events/EventBusContract.java |  18 +-
 .../apache/james/events/EventBusTestFixture.java   | 275 +++++++++++++++++++++
 .../org/apache/james/events}/EventCollector.java   |   8 +-
 .../james}/events/EventDeadLettersContract.java    |  70 +++---
 .../EventDeadLettersHealthCheckContract.java       |  24 +-
 .../org/apache/james}/events/GroupContract.java    | 136 +++++-----
 .../java/org/apache/james}/events/GroupTest.java   |   9 +-
 .../org/apache/james}/events/InsertionIdTest.java  |   2 +-
 .../java/org/apache/james}/events/KeyContract.java | 125 +++++-----
 .../events/RetryBackoffConfigurationTest.java      |   8 +-
 .../cassandra}/pom.xml                             |  36 +--
 .../james}/events/CassandraEventDeadLetters.java   |   2 +-
 .../events/CassandraEventDeadLettersDAO.java       |  13 +-
 .../events/CassandraEventDeadLettersGroupDAO.java  |  13 +-
 .../events/CassandraEventDeadLettersModule.java    |   6 +-
 .../CassandraEventDeadLettersGroupTable.java       |   2 +-
 .../tables/CassandraEventDeadLettersTable.java     |   2 +-
 .../events/CassandraEventDeadLettersDAOTest.java   |  27 +-
 .../CassandraEventDeadLettersGroupDAOTest.java     |   6 +-
 .../CassandraEventDeadLettersHealthCheckTest.java  |   9 +-
 .../events/CassandraEventDeadLettersTest.java      |   9 +-
 .../distributed}/pom.xml                           |  35 +--
 .../java/org/apache/james}/events/EventBusId.java  |   2 +-
 .../org/apache/james}/events/EventDispatcher.java  |  41 ++-
 .../apache/james}/events/GroupConsumerRetry.java   |  30 +--
 .../apache/james}/events/GroupRegistration.java    |  48 ++--
 .../james}/events/GroupRegistrationHandler.java    |  21 +-
 .../james}/events/KeyReconnectionHandler.java      |  11 +-
 .../org/apache/james}/events/KeyRegistration.java  |   2 +-
 .../james}/events/KeyRegistrationHandler.java      |  36 +--
 .../org/apache/james/events/ListenerExecutor.java  |  14 +-
 .../james}/events/LocalListenerRegistry.java       |  22 +-
 .../org/apache/james/events/NamingStrategy.java    |  43 ++--
 .../org/apache/james}/events/RabbitMQEventBus.java |  31 ++-
 .../apache/james}/events/RegistrationBinder.java   |  10 +-
 .../james}/events/RegistrationQueueName.java       |   2 +-
 .../apache/james}/events/RoutingKeyConverter.java  |   2 +-
 .../apache/james}/events/WaitDelayGenerator.java   |   2 +-
 .../org/apache/james}/events/EventBusIdTest.java   |   2 +-
 .../james}/events/LocalListenerRegistryTest.java   |  87 ++++---
 .../org/apache/james}/events/NetworkErrorTest.java |  27 +-
 ...RabbitMQEventBusDeadLetterQueueUpgradeTest.java |  36 ++-
 .../apache/james}/events/RabbitMQEventBusTest.java | 210 +++++++++-------
 .../james}/events/RoutingKeyConverterTest.java     |  41 +--
 .../james}/events/WaitDelayGeneratorTest.java      |   2 +-
 .../event/event-memory => event-bus/in-vm}/pom.xml |  33 ++-
 .../org/apache/james}/events/InVMEventBus.java     |  28 +--
 .../james}/events/MemoryEventDeadLetters.java      |   6 +-
 .../james}/events/delivery/EventDelivery.java      |  38 +--
 .../james}/events/delivery/InVmEventDelivery.java  |  36 +--
 .../org/apache/james}/events/InVMEventBusTest.java |   4 +-
 .../MemoryEventDeadLettersHealthCheckTest.java     |   2 +-
 .../james}/events/MemoryEventDeadLettersTest.java  |   2 +-
 .../events/delivery/InVmEventDeliveryTest.java     |  63 +++--
 {examples => event-bus}/pom.xml                    |  36 +--
 examples/custom-listeners/pom.xml                  |  59 +++--
 .../listeners/SetCustomFlagOnBigMessages.java      |  13 +-
 .../listeners/SetCustomFlagOnBigMessagesTest.java  |   2 +-
 examples/custom-mailets/pom.xml                    |  25 +-
 examples/pom.xml                                   |   5 +-
 mailbox/api/pom.xml                                |   4 +
 .../{MailboxListener.java => MailboxEvents.java}   | 120 +--------
 .../mailbox/events/MailboxIdRegistrationKey.java   |   1 +
 .../james/mailbox/events/MessageMoveEvent.java     |   1 +
 .../java/org/apache/james/mailbox/EventTest.java   |  10 +-
 .../apache/james/mailbox/MailboxListenerTest.java  |  51 ++--
 .../mailbox/MailboxManagerStressContract.java      |   6 +-
 .../apache/james/mailbox/MailboxManagerTest.java   |  55 +++--
 .../james/mailbox/events/EventBusTestFixture.java  | 138 -----------
 .../apache/james/mailbox/util/EventCollector.java  |   8 +-
 mailbox/backup/pom.xml                             |   6 +
 mailbox/cassandra/pom.xml                          |  16 +-
 .../mailbox/cassandra/CassandraMailboxManager.java |   2 +-
 .../mailbox/cassandra/CassandraMessageManager.java |   2 +-
 .../mailbox/cassandra/DeleteMessageListener.java   |  10 +-
 .../cassandra/MailboxOperationLoggingListener.java |  11 +-
 .../cassandra/CassandraCombinationManagerTest.java |   8 +-
 .../CassandraCombinationManagerTestSystem.java     |   2 +-
 .../cassandra/CassandraMailboxManagerProvider.java |   8 +-
 .../CassandraMailboxManagerStressTest.java         |   2 +-
 .../cassandra/CassandraMailboxManagerTest.java     |   2 +-
 .../CassandraMessageIdManagerSideEffectTest.java   |   2 +-
 .../CassandraMessageIdManagerStorageTest.java      |   8 +-
 .../CassandraMessageIdManagerTestSystem.java       |   2 +-
 .../cassandra/CassandraTestSystemFixture.java      |  10 +-
 .../MailboxOperationLoggingListenerTest.java       |   2 +-
 .../CassandraMailboxManagerAttachmentTest.java     |   8 +-
 .../cassandra/mail/CassandraMailboxMapperTest.java |   1 -
 mailbox/elasticsearch/pom.xml                      |  16 +-
 .../ElasticSearchListeningMessageSearchIndex.java  |   2 +-
 .../ElasticSearchIntegrationTest.java              |   4 -
 ...asticSearchListeningMessageSearchIndexTest.java |   3 +-
 mailbox/event/json/pom.xml                         |   4 +
 ...rializer.scala => MailboxEventSerializer.scala} |  14 +-
 .../james/event/json/AddedSerializationTest.java   |   7 +-
 .../event/json/ExpungedSerializationTest.java      |   6 +-
 .../event/json/FlagsUpdatedSerializationTest.java  |   8 +-
 .../MailboxACLUpdatedEventSerializationTest.java   |   4 +-
 .../event/json/MailboxAddedSerializationTest.java  |   4 +-
 .../json/MailboxDeletionSerializationTest.java     |   6 +-
 .../json/MailboxRenamedSerializationTest.java      |   4 +-
 .../json/MessageMoveEventSerializationTest.java    |   2 +-
 .../QuotaUsageUpdatedEventSerializationTest.java   |   4 +-
 .../apache/james/event/json/SerializerFixture.java |   4 +-
 mailbox/jpa/pom.xml                                |  16 +-
 .../mailbox/jpa/openjpa/OpenJPAMailboxManager.java |   2 +-
 .../mailbox/jpa/openjpa/OpenJPAMessageManager.java |   2 +-
 .../james/mailbox/jpa/JPAMailboxManagerTest.java   |   2 +-
 .../mailbox/jpa/JpaMailboxManagerProvider.java     |   8 +-
 .../mailbox/jpa/JpaMailboxManagerStressTest.java   |   2 +-
 mailbox/lucene/pom.xml                             |  16 +-
 .../lucene/search/LuceneMessageSearchIndex.java    |   6 +-
 .../search/LuceneMessageSearchIndexTest.java       |  13 -
 mailbox/maildir/pom.xml                            |  10 +-
 .../DomainUserMaildirMailboxManagerStressTest.java |   2 +-
 .../DomainUserMaildirMailboxManagerTest.java       |   2 +-
 .../FullUserMaildirMailboxManagerStressTest.java   |   2 +-
 .../maildir/FullUserMaildirMailboxManagerTest.java |   2 +-
 .../maildir/MaildirMailboxManagerProvider.java     |   8 +-
 .../UserMaildirMailboxManagerStressTest.java       |   2 +-
 mailbox/memory/pom.xml                             |   6 +
 .../mailbox/inmemory/InMemoryMailboxManager.java   |   2 +-
 .../mailbox/inmemory/InMemoryMessageManager.java   |   2 +-
 .../inmemory/MemoryMailboxManagerStressTest.java   |   2 +-
 .../mailbox/inmemory/MemoryMailboxManagerTest.java |   2 +-
 .../manager/InMemoryIntegrationResources.java      |  14 +-
 .../InMemoryMessageIdManagerSideEffectTest.java    |   2 +-
 .../deleted-messages-vault-cassandra/pom.xml       |   6 +
 mailbox/plugin/deleted-messages-vault/pom.xml      |   7 +
 mailbox/plugin/quota-mailing-cassandra/pom.xml     |   6 +
 mailbox/plugin/quota-mailing-memory/pom.xml        |   6 +
 mailbox/plugin/quota-mailing/pom.xml               |  14 +-
 .../listeners/QuotaThresholdCrossingListener.java  |   9 +-
 .../QuotaThresholdConfigurationChangesTest.java    |   2 +-
 .../QuotaThresholdCrossingListenerTest.java        |   2 +-
 .../QuotaThresholdListenersTestSystem.java         |  14 +-
 .../QuotaThresholdMailingIntegrationTest.java      |   2 +-
 mailbox/plugin/quota-search-elasticsearch/pom.xml  |   6 +
 .../events/ElasticSearchQuotaMailboxListener.java  |   9 +-
 .../json/QuotaRatioToElasticSearchJson.java        |   2 +-
 .../ElasticSearchQuotaMailboxListenerTest.java     |   4 +-
 .../json/QuotaRatioToElasticSearchJsonTest.java    |   4 +-
 mailbox/plugin/quota-search-scanning/pom.xml       |   6 +
 mailbox/plugin/quota-search/pom.xml                |   6 +
 mailbox/plugin/spamassassin/pom.xml                |   6 +
 .../mailbox/spamassassin/SpamAssassinListener.java |   5 +-
 .../spamassassin/SpamAssassinListenerTest.java     |  11 +-
 mailbox/pom.xml                                    |   3 -
 mailbox/scanning-search/pom.xml                    |   6 +
 mailbox/spring/pom.xml                             |   8 +-
 .../james/mailbox/spring/MailboxInitializer.java   |   2 +-
 .../resources/META-INF/spring/event-system.xml     |   8 +-
 mailbox/store/pom.xml                              |   2 +-
 .../james/mailbox/store/StoreMailboxManager.java   |   2 +-
 .../james/mailbox/store/StoreMessageIdManager.java |   2 +-
 .../james/mailbox/store/StoreMessageManager.java   |   6 +-
 .../james/mailbox/store/StoreRightManager.java     |   2 +-
 .../james/mailbox/store/event/EventFactory.java    |  43 ++--
 .../store/event/MailboxAnnotationListener.java     |   9 +-
 .../mailbox/store/event/SpamEventListener.java     |   4 +-
 .../store/quota/ListeningCurrentQuotaUpdater.java  |  16 +-
 .../store/search/LazyMessageSearchIndex.java       |   2 +-
 .../store/search/ListeningMessageSearchIndex.java  |  13 +-
 .../AbstractMessageIdManagerSideEffectTest.java    |  52 ++--
 .../mailbox/store/StoreMailboxManagerTest.java     |  17 +-
 .../james/mailbox/store/StoreRightManagerTest.java |   2 +-
 .../store/event/MailboxAnnotationListenerTest.java |  11 +-
 .../quota/ListeningCurrentQuotaUpdaterTest.java    |  23 +-
 .../search/AbstractMessageSearchIndexTest.java     |   2 -
 .../store/search/CombinedComparatorTest.java       |   1 -
 .../store/search/LazyMessageSearchIndexTest.java   |   2 +-
 mailbox/tools/copier/pom.xml                       |   6 +
 mailbox/tools/indexer/pom.xml                      |   6 +
 mpt/impl/imap-mailbox/cassandra/pom.xml            |  14 +-
 .../cassandra/host/CassandraHostSystem.java        |   8 +-
 mpt/impl/imap-mailbox/elasticsearch/pom.xml        |  16 +-
 mpt/impl/imap-mailbox/inmemory/pom.xml             |   6 +
 mpt/impl/imap-mailbox/jpa/pom.xml                  |  16 +-
 .../mpt/imapmailbox/jpa/host/JPAHostSystem.java    |   8 +-
 mpt/impl/imap-mailbox/lucenesearch/pom.xml         |  14 +-
 mpt/impl/imap-mailbox/maildir/pom.xml              |  12 +-
 .../maildir/host/MaildirHostSystem.java            |   8 +-
 mpt/impl/imap-mailbox/rabbitmq/pom.xml             |  14 +-
 .../rabbitmq/host/RabbitMQEventBusHostSystem.java  |  17 +-
 pom.xml                                            |  42 ++--
 protocols/imap/pom.xml                             |   6 +
 .../imap/processor/AbstractSelectionProcessor.java |   2 +-
 .../imap/processor/DefaultProcessorChain.java      |   2 +-
 .../james/imap/processor/ExamineProcessor.java     |   2 +-
 .../apache/james/imap/processor/IdleProcessor.java |  13 +-
 .../james/imap/processor/SelectProcessor.java      |   2 +-
 .../imap/processor/base/SelectedMailboxImpl.java   |  16 +-
 .../main/DefaultImapProcessorFactory.java          |   2 +-
 .../processor/base/MailboxEventAnalyserTest.java   |  31 +--
 .../processor/base/SelectedMailboxImplTest.java    |  37 +--
 .../james/app/spring/JamesSpringContextTest.java   |   2 +-
 server/container/guice/cassandra-guice/pom.xml     |   8 +-
 .../java/org/apache/james/SearchModuleChooser.java |   2 +-
 .../modules/mailbox/CassandraDeadLetterModule.java |  12 +-
 .../modules/mailbox/CassandraMailboxModule.java    |   4 +-
 .../modules/mailbox/CassandraQuotaModule.java      |   4 +-
 .../mailbox/ElasticSearchMailboxModule.java        |   4 +-
 .../mailbox/ElasticSearchQuotaSearcherModule.java  |   4 +-
 .../guice/cassandra-rabbitmq-guice/pom.xml         |   8 +-
 .../modules/event/RabbitMQEventBusModule.java      |  20 +-
 .../apache/james/PeriodicalHealthChecksTest.java   |   2 +-
 .../james/modules/mailbox/JPAMailboxModule.java    |   4 +-
 .../james/modules/mailbox/JpaQuotaModule.java      |   4 +-
 .../modules/mailbox/LuceneSearchMailboxModule.java |   4 +-
 server/container/guice/mailbox/pom.xml             |  12 +-
 .../james/modules/EventDeadLettersProbe.java       |   2 +-
 .../james/modules/mailbox/DefaultEventModule.java  |  21 +-
 .../modules/mailbox/FastRetryBackoffModule.java    |   2 +-
 .../modules/mailbox/MailboxListenerFactory.java    |  16 +-
 .../modules/mailbox/MailboxListenersLoader.java    |   8 +-
 .../mailbox/MailboxListenersLoaderImpl.java        |  46 ++--
 .../modules/mailbox/MemoryDeadLetterModule.java    |   6 +-
 .../mailbox/MailboxListenersLoaderImplTest.java    |  14 +-
 .../james/modules/mailbox/NoopMailboxListener.java |   8 +-
 .../mailbox/ReactiveNoopMailboxListener.java       |   8 +-
 .../org/apache/james/FakeMessageSearchIndex.java   |   2 +-
 .../james/modules/mailbox/MemoryMailboxModule.java |   4 +-
 .../james/modules/mailbox/MemoryQuotaModule.java   |   4 +-
 .../apache/james/DisabledGroupExecutionTest.java   |  10 +-
 .../james/modules/protocols/IMAPServerModule.java  |   2 +-
 .../apache/james/jmap/draft/JMAPCommonModule.java  |   4 +-
 .../org/apache/james/jmap/draft/JMAPModule.java    |   6 +-
 .../apache/james/jmap/draft/JmapGuiceProbe.java    |   6 +-
 server/container/mailbox-jmx/pom.xml               |   6 +
 .../apache/james/jmap/api/change/EmailChange.java  |   9 +-
 .../james/jmap/api/change/MailboxChange.java       |  14 +-
 server/mailet/mailets/pom.xml                      |   6 +
 .../methods/integration/SetMessagesMethodTest.java |  10 +-
 server/protocols/jmap-draft/pom.xml                |   6 +
 .../ComputeMessageFastViewProjectionListener.java  |   9 +-
 .../jmap/event/PopulateEmailQueryViewListener.java |  11 +-
 .../jmap/event/PropagateLookupRightListener.java   |  10 +-
 ...mputeMessageFastViewProjectionListenerTest.java |  10 +-
 .../event/PopulateEmailQueryViewListenerTest.java  |  10 +-
 .../event/PropagateLookupRightListenerTest.java    |   6 +-
 server/protocols/jmap-rfc-8621/pom.xml             |   6 +
 .../james/jmap/change/MailboxChangeListener.scala  |  13 +-
 .../jmap/change/MailboxChangeListenerTest.scala    |   7 +-
 server/protocols/protocols-pop3/pom.xml            |   7 +
 .../rabbitmq/ConsistencyTasksIntegrationTest.java  |   2 +-
 .../RabbitMQEventDeadLettersIntegrationTest.java   |  15 +-
 ...RabbitMQReindexingWithEventDeadLettersTest.java |   2 +-
 ...dminServerTaskSerializationIntegrationTest.java |  14 +-
 server/protocols/webadmin/webadmin-jmap/pom.xml    |   6 +
 .../webadmin-mailbox-deleted-message-vault/pom.xml |   6 +
 server/protocols/webadmin/webadmin-mailbox/pom.xml |  16 +-
 .../webadmin/routes/EventDeadLettersRoutes.java    |   8 +-
 .../EventDeadLettersRedeliverGroupTask.java        |   2 +-
 .../EventDeadLettersRedeliverGroupTaskDTO.java     |   2 +-
 .../service/EventDeadLettersRedeliverOneTask.java  |   4 +-
 .../EventDeadLettersRedeliverOneTaskDTO.java       |   4 +-
 .../service/EventDeadLettersRedeliverService.java  |   8 +-
 ...LettersRedeliveryTaskAdditionalInformation.java |   4 +-
 ...tersRedeliveryTaskAdditionalInformationDTO.java |   4 +-
 .../webadmin/service/EventDeadLettersService.java  |   6 +-
 .../james/webadmin/service/EventRetriever.java     |   6 +-
 .../routes/EventDeadLettersRoutesTest.java         |  30 +--
 .../james/webadmin/routes/MailboxesRoutesTest.java |   2 -
 .../webadmin/routes/UserMailboxesRoutesTest.java   |   2 -
 .../service/EventDeadLettersRedeliverTaskTest.java |   4 +-
 281 files changed, 2342 insertions(+), 1870 deletions(-)
 copy {mailbox/event/event-memory => event-bus/api}/pom.xml (68%)
 rename {mailbox/api/src/main/java/org/apache/james/mailbox => event-bus/api/src/main/java/org/apache/james}/events/Event.java (98%)
 rename {mailbox/api/src/main/java/org/apache/james/mailbox => event-bus/api/src/main/java/org/apache/james}/events/EventBus.java (64%)
 rename {mailbox/api/src/main/java/org/apache/james/mailbox => event-bus/api/src/main/java/org/apache/james}/events/EventDeadLetters.java (98%)
 rename {mailbox/api/src/main/java/org/apache/james/mailbox => event-bus/api/src/main/java/org/apache/james}/events/EventDeadLettersHealthCheck.java (94%)
 create mode 100644 event-bus/api/src/main/java/org/apache/james/events/EventListener.java
 copy mailbox/api/src/main/java/org/apache/james/mailbox/events/Registration.java => event-bus/api/src/main/java/org/apache/james/events/EventSerializer.java (89%)
 rename {mailbox/api/src/main/java/org/apache/james/mailbox => event-bus/api/src/main/java/org/apache/james}/events/Group.java (97%)
 rename {mailbox/api/src/main/java/org/apache/james/mailbox => event-bus/api/src/main/java/org/apache/james}/events/GroupAlreadyRegistered.java (95%)
 rename {mailbox/api/src/main/java/org/apache/james/mailbox => event-bus/api/src/main/java/org/apache/james}/events/GroupRegistrationNotFound.java (95%)
 rename {mailbox/api/src/main/java/org/apache/james/mailbox => event-bus/api/src/main/java/org/apache/james}/events/Registration.java (96%)
 rename {mailbox/api/src/main/java/org/apache/james/mailbox => event-bus/api/src/main/java/org/apache/james}/events/RegistrationKey.java (97%)
 rename {mailbox/api/src/main/java/org/apache/james/mailbox => event-bus/api/src/main/java/org/apache/james}/events/RetryBackoffConfiguration.java (99%)
 rename {mailbox => event-bus}/api/src/main/java/org/apache/james/mailbox/events/GenericGroup.java (95%)
 rename {mailbox/api/src/test/java/org/apache/james/mailbox => event-bus/api/src/test/java/org/apache/james}/events/ErrorHandlingContract.java (94%)
 rename {mailbox/api/src/test/java/org/apache/james/mailbox => event-bus/api/src/test/java/org/apache/james}/events/EventBusConcurrentTestContract.java (68%)
 rename {mailbox/api/src/test/java/org/apache/james/mailbox => event-bus/api/src/test/java/org/apache/james}/events/EventBusContract.java (83%)
 create mode 100644 event-bus/api/src/test/java/org/apache/james/events/EventBusTestFixture.java
 copy {mailbox/api/src/test/java/org/apache/james/mailbox/util => event-bus/api/src/test/java/org/apache/james/events}/EventCollector.java (87%)
 rename {mailbox/api/src/test/java/org/apache/james/mailbox => event-bus/api/src/test/java/org/apache/james}/events/EventDeadLettersContract.java (81%)
 rename {mailbox/api/src/test/java/org/apache/james/mailbox => event-bus/api/src/test/java/org/apache/james}/events/EventDeadLettersHealthCheckContract.java (80%)
 rename {mailbox/api/src/test/java/org/apache/james/mailbox => event-bus/api/src/test/java/org/apache/james}/events/GroupContract.java (76%)
 rename {mailbox/api/src/test/java/org/apache/james/mailbox => event-bus/api/src/test/java/org/apache/james}/events/GroupTest.java (94%)
 rename {mailbox/api/src/test/java/org/apache/james/mailbox => event-bus/api/src/test/java/org/apache/james}/events/InsertionIdTest.java (98%)
 rename {mailbox/api/src/test/java/org/apache/james/mailbox => event-bus/api/src/test/java/org/apache/james}/events/KeyContract.java (77%)
 rename {mailbox/api/src/test/java/org/apache/james/mailbox => event-bus/api/src/test/java/org/apache/james}/events/RetryBackoffConfigurationTest.java (94%)
 rename {mailbox/event/event-cassandra => event-bus/cassandra}/pom.xml (70%)
 rename {mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox => event-bus/cassandra/src/main/java/org/apache/james}/events/CassandraEventDeadLetters.java (98%)
 rename {mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox => event-bus/cassandra/src/main/java/org/apache/james}/events/CassandraEventDeadLettersDAO.java (91%)
 rename {mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox => event-bus/cassandra/src/main/java/org/apache/james}/events/CassandraEventDeadLettersGroupDAO.java (84%)
 rename {mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox => event-bus/cassandra/src/main/java/org/apache/james}/events/CassandraEventDeadLettersModule.java (92%)
 rename {mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox => event-bus/cassandra/src/main/java/org/apache/james}/events/tables/CassandraEventDeadLettersGroupTable.java (96%)
 rename {mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox => event-bus/cassandra/src/main/java/org/apache/james}/events/tables/CassandraEventDeadLettersTable.java (96%)
 rename {mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox => event-bus/cassandra/src/test/java/org/apache/james}/events/CassandraEventDeadLettersDAOTest.java (82%)
 rename {mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox => event-bus/cassandra/src/test/java/org/apache/james}/events/CassandraEventDeadLettersGroupDAOTest.java (92%)
 rename {mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox => event-bus/cassandra/src/test/java/org/apache/james}/events/CassandraEventDeadLettersHealthCheckTest.java (86%)
 rename {mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox => event-bus/cassandra/src/test/java/org/apache/james}/events/CassandraEventDeadLettersTest.java (82%)
 rename {mailbox/event/event-rabbitmq => event-bus/distributed}/pom.xml (78%)
 rename {mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox => event-bus/distributed/src/main/java/org/apache/james}/events/EventBusId.java (98%)
 rename {mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox => event-bus/distributed/src/main/java/org/apache/james}/events/EventDispatcher.java (82%)
 rename {mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox => event-bus/distributed/src/main/java/org/apache/james}/events/GroupConsumerRetry.java (84%)
 rename {mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox => event-bus/distributed/src/main/java/org/apache/james}/events/GroupRegistration.java (79%)
 rename {mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox => event-bus/distributed/src/main/java/org/apache/james}/events/GroupRegistrationHandler.java (81%)
 rename {mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox => event-bus/distributed/src/main/java/org/apache/james}/events/KeyReconnectionHandler.java (84%)
 rename {mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox => event-bus/distributed/src/main/java/org/apache/james}/events/KeyRegistration.java (97%)
 rename {mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox => event-bus/distributed/src/main/java/org/apache/james}/events/KeyRegistrationHandler.java (84%)
 rename mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/MailboxListenerExecutor.java => event-bus/distributed/src/main/java/org/apache/james/events/ListenerExecutor.java (79%)
 rename {mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox => event-bus/distributed/src/main/java/org/apache/james}/events/LocalListenerRegistry.java (78%)
 copy mailbox/api/src/test/java/org/apache/james/mailbox/util/EventCollector.java => event-bus/distributed/src/main/java/org/apache/james/events/NamingStrategy.java (56%)
 rename {mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox => event-bus/distributed/src/main/java/org/apache/james}/events/RabbitMQEventBus.java (78%)
 rename {mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox => event-bus/distributed/src/main/java/org/apache/james}/events/RegistrationBinder.java (87%)
 rename {mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox => event-bus/distributed/src/main/java/org/apache/james}/events/RegistrationQueueName.java (97%)
 rename {mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox => event-bus/distributed/src/main/java/org/apache/james}/events/RoutingKeyConverter.java (98%)
 rename {mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox => event-bus/distributed/src/main/java/org/apache/james}/events/WaitDelayGenerator.java (98%)
 rename {mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox => event-bus/distributed/src/test/java/org/apache/james}/events/EventBusIdTest.java (97%)
 rename {mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox => event-bus/distributed/src/test/java/org/apache/james}/events/LocalListenerRegistryTest.java (73%)
 rename {mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox => event-bus/distributed/src/test/java/org/apache/james}/events/NetworkErrorTest.java (72%)
 rename {mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox => event-bus/distributed/src/test/java/org/apache/james}/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java (69%)
 rename {mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox => event-bus/distributed/src/test/java/org/apache/james}/events/RabbitMQEventBusTest.java (82%)
 rename {mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox => event-bus/distributed/src/test/java/org/apache/james}/events/RoutingKeyConverterTest.java (73%)
 rename {mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox => event-bus/distributed/src/test/java/org/apache/james}/events/WaitDelayGeneratorTest.java (99%)
 rename {mailbox/event/event-memory => event-bus/in-vm}/pom.xml (75%)
 rename {mailbox/event/event-memory/src/main/java/org/apache/james/mailbox => event-bus/in-vm/src/main/java/org/apache/james}/events/InVMEventBus.java (76%)
 rename {mailbox/event/event-memory/src/main/java/org/apache/james/mailbox => event-bus/in-vm/src/main/java/org/apache/james}/events/MemoryEventDeadLetters.java (95%)
 rename {mailbox/event/event-memory/src/main/java/org/apache/james/mailbox => event-bus/in-vm/src/main/java/org/apache/james}/events/delivery/EventDelivery.java (76%)
 rename {mailbox/event/event-memory/src/main/java/org/apache/james/mailbox => event-bus/in-vm/src/main/java/org/apache/james}/events/delivery/InVmEventDelivery.java (73%)
 rename {mailbox/event/event-memory/src/test/java/org/apache/james/mailbox => event-bus/in-vm/src/test/java/org/apache/james}/events/InVMEventBusTest.java (95%)
 rename {mailbox/event/event-memory/src/test/java/org/apache/james/mailbox => event-bus/in-vm/src/test/java/org/apache/james}/events/MemoryEventDeadLettersHealthCheckTest.java (98%)
 rename {mailbox/event/event-memory/src/test/java/org/apache/james/mailbox => event-bus/in-vm/src/test/java/org/apache/james}/events/MemoryEventDeadLettersTest.java (97%)
 rename {mailbox/event/event-memory/src/test/java/org/apache/james/mailbox => event-bus/in-vm/src/test/java/org/apache/james}/events/delivery/InVmEventDeliveryTest.java (75%)
 copy {examples => event-bus}/pom.xml (52%)
 rename mailbox/api/src/main/java/org/apache/james/mailbox/events/{MailboxListener.java => MailboxEvents.java} (85%)
 delete mode 100644 mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusTestFixture.java
 rename mailbox/event/json/src/main/scala/org/apache/james/event/json/{EventSerializer.scala => MailboxEventSerializer.scala} (95%)


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


[james-project] 09/18: JAMES-3498 event-bus-distributed POM ordering

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 6efd2a1b90e164e942b1249c6e591c64f193ed72
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 25 15:48:44 2021 +0700

    JAMES-3498 event-bus-distributed POM ordering
---
 event-bus/distributed/pom.xml | 34 ++++++++++++++++------------------
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/event-bus/distributed/pom.xml b/event-bus/distributed/pom.xml
index ea6a729..0efc066 100644
--- a/event-bus/distributed/pom.xml
+++ b/event-bus/distributed/pom.xml
@@ -17,9 +17,7 @@
     specific language governing permissions and limitations
     under the License.
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.james</groupId>
@@ -33,16 +31,6 @@
 
     <dependencies>
         <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-backends-rabbitmq</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-backends-rabbitmq</artifactId>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-api</artifactId>
         </dependency>
@@ -67,10 +55,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>metrics-api</artifactId>
-        </dependency>
-        <dependency>
             <groupId>${james.groupId}</groupId>
             <artifactId>metrics-tests</artifactId>
             <scope>test</scope>
@@ -81,6 +65,20 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-backends-rabbitmq</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-backends-rabbitmq</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>metrics-api</artifactId>
+        </dependency>
+        <dependency>
             <groupId>io.projectreactor</groupId>
             <artifactId>reactor-core</artifactId>
         </dependency>
@@ -108,4 +106,4 @@
             <scope>test</scope>
         </dependency>
     </dependencies>
-</project>
\ No newline at end of file
+</project>


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


[james-project] 02/18: JAMES-3498 Move as is the In VM implementation

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 c4f6a0d82af3560f07aba5889a8c8d3d5dd48d99
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 25 13:47:59 2021 +0700

    JAMES-3498 Move as is the In VM implementation
---
 event-bus/in-vm/pom.xml                            |  44 +
 .../listeners/SetCustomFlagOnBigMessages.java      |   6 +-
 .../apache/james/mailbox/events/MailboxEvents.java | 582 ------------
 .../mailbox/events/MailboxIdRegistrationKey.java   |  78 --
 .../james/mailbox/events/MessageMoveEvent.java     | 154 ----
 .../mailbox/events/RetryBackoffConfiguration.java  | 125 ---
 .../java/org/apache/james/mailbox/EventTest.java   |   2 +-
 .../apache/james/mailbox/MailboxListenerTest.java  |  16 +-
 .../mailbox/MailboxManagerStressContract.java      |   4 +-
 .../apache/james/mailbox/MailboxManagerTest.java   |  16 +-
 .../apache/james/mailbox/MessageMoveEventTest.java |   2 +-
 .../mailbox/events/ErrorHandlingContract.java      | 367 --------
 .../events/EventBusConcurrentTestContract.java     | 240 -----
 .../james/mailbox/events/EventBusContract.java     |  73 --
 .../james/mailbox/events/EventBusTestFixture.java  | 145 ---
 .../mailbox/events/EventDeadLettersContract.java   | 493 -----------
 .../EventDeadLettersHealthCheckContract.java       | 134 ---
 .../apache/james/mailbox/events/GroupContract.java | 504 -----------
 .../org/apache/james/mailbox/events/GroupTest.java | 135 ---
 .../james/mailbox/events/InsertionIdTest.java      |  57 --
 .../apache/james/mailbox/events/KeyContract.java   | 458 ----------
 .../events/MailboxIdRegistrationKeyTest.java       |  60 --
 .../events/RetryBackoffConfigurationTest.java      | 141 ---
 .../james/mailbox/model/MessageMovesTest.java      |   2 +-
 mailbox/cassandra/pom.xml                          |  10 +-
 .../mailbox/cassandra/DeleteMessageListener.java   |   4 +-
 .../cassandra/MailboxOperationLoggingListener.java |   6 +-
 .../cassandra/CassandraCombinationManagerTest.java |   8 +-
 .../cassandra/CassandraMailboxManagerProvider.java |   8 +-
 .../CassandraMessageIdManagerStorageTest.java      |   8 +-
 .../cassandra/CassandraTestSystemFixture.java      |   8 +-
 .../CassandraMailboxManagerAttachmentTest.java     |   8 +-
 mailbox/elasticsearch/pom.xml                      |  10 +-
 .../mailbox/events/CassandraEventDeadLetters.java  |  89 --
 .../events/CassandraEventDeadLettersDAO.java       | 132 ---
 .../events/CassandraEventDeadLettersGroupDAO.java  |  71 --
 .../events/CassandraEventDeadLettersModule.java    |  46 -
 .../CassandraEventDeadLettersGroupTable.java       |  27 -
 .../tables/CassandraEventDeadLettersTable.java     |  29 -
 .../events/CassandraEventDeadLettersDAOTest.java   | 145 ---
 .../CassandraEventDeadLettersGroupDAOTest.java     |  60 --
 .../CassandraEventDeadLettersHealthCheckTest.java  |  70 --
 .../events/CassandraEventDeadLettersTest.java      |  50 --
 mailbox/event/event-memory/pom.xml                 |  79 --
 .../apache/james/mailbox/events/InVMEventBus.java  | 134 ---
 .../mailbox/events/MemoryEventDeadLetters.java     |  95 --
 .../mailbox/events/delivery/EventDelivery.java     | 134 ---
 .../mailbox/events/delivery/InVmEventDelivery.java | 104 ---
 .../james/mailbox/events/InVMEventBusTest.java     |  55 --
 .../MemoryEventDeadLettersHealthCheckTest.java     |  59 --
 .../mailbox/events/MemoryEventDeadLettersTest.java |  38 -
 .../events/delivery/InVmEventDeliveryTest.java     | 253 ------
 mailbox/event/event-rabbitmq/pom.xml               |  10 +-
 .../apache/james/mailbox/events/EventBusId.java    |  72 --
 .../james/mailbox/events/EventDispatcher.java      | 201 -----
 .../james/mailbox/events/GroupConsumerRetry.java   | 145 ---
 .../james/mailbox/events/GroupRegistration.java    | 198 -----
 .../mailbox/events/GroupRegistrationHandler.java   |  93 --
 .../mailbox/events/KeyReconnectionHandler.java     |  60 --
 .../james/mailbox/events/KeyRegistration.java      |  35 -
 .../mailbox/events/KeyRegistrationHandler.java     | 204 -----
 .../mailbox/events/LocalListenerRegistry.java      | 112 ---
 .../mailbox/events/MailboxListenerExecutor.java    |  56 --
 .../james/mailbox/events/RabbitMQEventBus.java     | 177 ----
 .../james/mailbox/events/RegistrationBinder.java   |  56 --
 .../mailbox/events/RegistrationQueueName.java      |  32 -
 .../james/mailbox/events/RoutingKeyConverter.java  |  92 --
 .../james/mailbox/events/WaitDelayGenerator.java   |  83 --
 .../james/mailbox/events/EventBusIdTest.java       |  50 --
 .../mailbox/events/LocalListenerRegistryTest.java  | 256 ------
 .../james/mailbox/events/NetworkErrorTest.java     |  89 --
 ...RabbitMQEventBusDeadLetterQueueUpgradeTest.java |  88 --
 .../james/mailbox/events/RabbitMQEventBusTest.java | 980 ---------------------
 .../mailbox/events/RoutingKeyConverterTest.java    | 144 ---
 .../mailbox/events/WaitDelayGeneratorTest.java     | 103 ---
 .../apache/james/event/json/EventSerializer.scala  |   8 +-
 .../james/event/json/AddedSerializationTest.java   |   2 +-
 .../event/json/ExpungedSerializationTest.java      |   2 +-
 .../event/json/FlagsUpdatedSerializationTest.java  |   2 +-
 .../MailboxACLUpdatedEventSerializationTest.java   |   2 +-
 .../event/json/MailboxAddedSerializationTest.java  |   2 +-
 .../json/MailboxDeletionSerializationTest.java     |   2 +-
 .../json/MailboxRenamedSerializationTest.java      |   2 +-
 .../json/MessageMoveEventSerializationTest.java    |   2 +-
 .../QuotaUsageUpdatedEventSerializationTest.java   |   2 +-
 mailbox/jpa/pom.xml                                |  10 +-
 .../mailbox/jpa/JpaMailboxManagerProvider.java     |   8 +-
 mailbox/lucene/pom.xml                             |  10 +-
 mailbox/maildir/pom.xml                            |   6 +-
 .../maildir/MaildirMailboxManagerProvider.java     |   8 +-
 .../manager/InMemoryIntegrationResources.java      |   8 +-
 mailbox/plugin/quota-mailing/pom.xml               |  10 +-
 .../listeners/QuotaThresholdCrossingListener.java  |   2 +-
 .../QuotaThresholdListenersTestSystem.java         |   8 +-
 .../events/ElasticSearchQuotaMailboxListener.java  |   2 +-
 .../json/QuotaRatioToElasticSearchJson.java        |   2 +-
 .../json/QuotaRatioToElasticSearchJsonTest.java    |   2 +-
 .../mailbox/spamassassin/SpamAssassinListener.java |   4 +-
 .../spamassassin/SpamAssassinListenerTest.java     |   4 +-
 mailbox/pom.xml                                    |   1 -
 mailbox/spring/pom.xml                             |   8 +-
 .../resources/META-INF/spring/event-system.xml     |   8 +-
 mailbox/store/pom.xml                              |   2 +-
 .../james/mailbox/store/StoreMailboxManager.java   |   2 +-
 .../james/mailbox/store/StoreMessageIdManager.java |   2 +-
 .../james/mailbox/store/StoreMessageManager.java   |   2 +-
 .../james/mailbox/store/StoreRightManager.java     |   2 +-
 .../james/mailbox/store/event/EventFactory.java    |  18 +-
 .../store/event/MailboxAnnotationListener.java     |   2 +-
 .../store/quota/ListeningCurrentQuotaUpdater.java  |   8 +-
 .../store/search/ListeningMessageSearchIndex.java  |  10 +-
 .../AbstractMessageIdManagerSideEffectTest.java    |  18 +-
 .../mailbox/store/MessageIdManagerTestSystem.java  |   2 +-
 .../mailbox/store/StoreMailboxManagerTest.java     |   8 +-
 .../store/event/MailboxAnnotationListenerTest.java |   4 +-
 .../quota/ListeningCurrentQuotaUpdaterTest.java    |   6 +-
 mpt/impl/imap-mailbox/cassandra/pom.xml            |   8 +-
 .../cassandra/host/CassandraHostSystem.java        |   8 +-
 mpt/impl/imap-mailbox/elasticsearch/pom.xml        |  10 +-
 mpt/impl/imap-mailbox/jpa/pom.xml                  |   2 +-
 .../mpt/imapmailbox/jpa/host/JPAHostSystem.java    |   8 +-
 mpt/impl/imap-mailbox/lucenesearch/pom.xml         |   2 +-
 mpt/impl/imap-mailbox/maildir/pom.xml              |   8 +-
 .../maildir/host/MaildirHostSystem.java            |   8 +-
 .../rabbitmq/host/RabbitMQEventBusHostSystem.java  |  12 +-
 pom.xml                                            |  10 +-
 .../apache/james/imap/processor/IdleProcessor.java |   8 +-
 .../imap/processor/base/SelectedMailboxImpl.java   |  14 +-
 .../processor/base/MailboxEventAnalyserTest.java   |  18 +-
 .../processor/base/SelectedMailboxImplTest.java    |  10 +-
 .../james/app/spring/JamesSpringContextTest.java   |   2 +-
 .../modules/mailbox/CassandraDeadLetterModule.java |   8 +-
 .../modules/event/RabbitMQEventBusModule.java      |  10 +-
 server/container/guice/mailbox/pom.xml             |   6 +-
 .../james/modules/mailbox/DefaultEventModule.java  |   8 +-
 .../modules/mailbox/FastRetryBackoffModule.java    |   2 +-
 .../modules/mailbox/MemoryDeadLetterModule.java    |   2 +-
 .../mailbox/MailboxListenersLoaderImplTest.java    |   9 +-
 .../apache/james/jmap/api/change/EmailChange.java  |   6 +-
 .../james/jmap/api/change/MailboxChange.java       |  14 +-
 .../methods/integration/SetMessagesMethodTest.java |   4 +-
 .../ComputeMessageFastViewProjectionListener.java  |   2 +-
 .../jmap/event/PopulateEmailQueryViewListener.java |   6 +-
 .../jmap/event/PropagateLookupRightListener.java   |   4 +-
 ...mputeMessageFastViewProjectionListenerTest.java |   8 +-
 .../event/PopulateEmailQueryViewListenerTest.java  |   8 +-
 .../james/jmap/change/MailboxChangeListener.scala  |   7 +-
 .../jmap/change/MailboxChangeListenerTest.scala    |   7 +-
 .../rabbitmq/ConsistencyTasksIntegrationTest.java  |   2 +-
 .../RabbitMQEventDeadLettersIntegrationTest.java   |   4 +-
 ...RabbitMQReindexingWithEventDeadLettersTest.java |   2 +-
 ...dminServerTaskSerializationIntegrationTest.java |   2 +-
 server/protocols/webadmin/webadmin-mailbox/pom.xml |   2 +-
 .../routes/EventDeadLettersRoutesTest.java         |  12 +-
 154 files changed, 346 insertions(+), 9044 deletions(-)

diff --git a/event-bus/in-vm/pom.xml b/event-bus/in-vm/pom.xml
index 99fc5c2..a0a178c 100644
--- a/event-bus/in-vm/pom.xml
+++ b/event-bus/in-vm/pom.xml
@@ -31,4 +31,48 @@
     <name>Apache James :: Event Bus :: In VM</name>
     <description>In VM (non distributed) implementation for the eventBus</description>
 
+    <dependencies>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>metrics-tests</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>testing-base</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-util</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>metrics-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.projectreactor</groupId>
+            <artifactId>reactor-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
 </project>
\ No newline at end of file
diff --git a/examples/custom-listeners/src/main/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessages.java b/examples/custom-listeners/src/main/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessages.java
index d541029..6c942ce 100644
--- a/examples/custom-listeners/src/main/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessages.java
+++ b/examples/custom-listeners/src/main/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessages.java
@@ -22,15 +22,15 @@ package org.apache.james.examples.custom.listeners;
 import javax.inject.Inject;
 import javax.mail.Flags;
 
+import org.apache.james.events.Event;
 import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
+import org.apache.james.events.MailboxEvents.Added;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageManager.FlagsUpdateMode;
 import org.apache.james.mailbox.MessageUid;
-import org.apache.james.events.Event;
-import org.apache.james.events.Group;
-import org.apache.james.mailbox.events.MailboxEvents.Added;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MessageRange;
 import org.slf4j.Logger;
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxEvents.java b/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxEvents.java
deleted file mode 100644
index d544e35..0000000
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxEvents.java
+++ /dev/null
@@ -1,582 +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.mailbox.events;
-
-import java.time.Instant;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.SortedMap;
-
-import org.apache.james.core.Username;
-import org.apache.james.core.quota.QuotaCountLimit;
-import org.apache.james.core.quota.QuotaCountUsage;
-import org.apache.james.core.quota.QuotaSizeLimit;
-import org.apache.james.core.quota.QuotaSizeUsage;
-import org.apache.james.events.Event;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.MessageUid;
-import org.apache.james.mailbox.acl.ACLDiff;
-import org.apache.james.mailbox.model.MailboxACL;
-import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.mailbox.model.MessageMetaData;
-import org.apache.james.mailbox.model.Quota;
-import org.apache.james.mailbox.model.QuotaRoot;
-import org.apache.james.mailbox.model.UpdatedFlags;
-
-import com.github.steveash.guavate.Guavate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
-public interface MailboxEvents {
-
-    interface QuotaEvent extends Event {
-        QuotaRoot getQuotaRoot();
-    }
-
-    class QuotaUsageUpdatedEvent implements QuotaEvent {
-        private final EventId eventId;
-        private final Username username;
-        private final QuotaRoot quotaRoot;
-        private final Quota<QuotaCountLimit, QuotaCountUsage> countQuota;
-        private final Quota<QuotaSizeLimit, QuotaSizeUsage> sizeQuota;
-        private final Instant instant;
-
-        public QuotaUsageUpdatedEvent(EventId eventId, Username username, QuotaRoot quotaRoot, Quota<QuotaCountLimit, QuotaCountUsage> countQuota, Quota<QuotaSizeLimit, QuotaSizeUsage> sizeQuota, Instant instant) {
-            this.eventId = eventId;
-            this.username = username;
-            this.quotaRoot = quotaRoot;
-            this.countQuota = countQuota;
-            this.sizeQuota = sizeQuota;
-            this.instant = instant;
-        }
-
-        @Override
-        public boolean isNoop() {
-            return false;
-        }
-
-        @Override
-        public Username getUsername() {
-            return username;
-        }
-
-        public Quota<QuotaCountLimit, QuotaCountUsage> getCountQuota() {
-            return countQuota;
-        }
-
-        public Quota<QuotaSizeLimit, QuotaSizeUsage> getSizeQuota() {
-            return sizeQuota;
-        }
-
-        @Override
-        public QuotaRoot getQuotaRoot() {
-            return quotaRoot;
-        }
-
-        public Instant getInstant() {
-            return instant;
-        }
-
-        @Override
-        public EventId getEventId() {
-            return eventId;
-        }
-
-        @Override
-        public final boolean equals(Object o) {
-            if (o instanceof QuotaUsageUpdatedEvent) {
-                QuotaUsageUpdatedEvent that = (QuotaUsageUpdatedEvent) o;
-
-                return Objects.equals(this.eventId, that.eventId)
-                    && Objects.equals(this.username, that.username)
-                    && Objects.equals(this.quotaRoot, that.quotaRoot)
-                    && Objects.equals(this.countQuota, that.countQuota)
-                    && Objects.equals(this.sizeQuota, that.sizeQuota)
-                    && Objects.equals(this.instant, that.instant);
-            }
-            return false;
-        }
-
-        @Override
-        public final int hashCode() {
-            return Objects.hash(eventId, username, quotaRoot, countQuota, sizeQuota, instant);
-        }
-
-    }
-
-    /**
-     * A mailbox event.
-     */
-    abstract class MailboxEvent implements Event {
-        protected final MailboxPath path;
-        protected final MailboxId mailboxId;
-        protected final Username username;
-        protected final MailboxSession.SessionId sessionId;
-        protected final EventId eventId;
-
-        public MailboxEvent(MailboxSession.SessionId sessionId, Username username, MailboxPath path, MailboxId mailboxId, EventId eventId) {
-            this.username = username;
-            this.path = path;
-            this.mailboxId = mailboxId;
-            this.sessionId = sessionId;
-            this.eventId = eventId;
-        }
-
-        /**
-         * Gets the {@link Username} in which's context the {@link MailboxEvent}
-         * happened
-         *
-         * @return user
-         */
-        @Override
-        public Username getUsername() {
-            return username;
-        }
-
-        @Override
-        public EventId getEventId() {
-            return eventId;
-        }
-
-        /**
-         * Gets the sessionId in which's context the {@link MailboxEvent}
-         * happened
-         *
-         * @return sessionId
-         */
-        public MailboxSession.SessionId getSessionId() {
-            return sessionId;
-        }
-
-        /**
-         * Return the path of the Mailbox this event belongs to.
-         *
-         * @return path
-         */
-        public MailboxPath getMailboxPath() {
-            return path;
-        }
-
-        /**
-         * Return the id of the Mailbox this event belongs to.
-         *
-         * @return mailboxId
-         */
-        public MailboxId getMailboxId() {
-            return mailboxId;
-        }
-    }
-
-    /**
-     * Indicates that mailbox has been deleted.
-     */
-    class MailboxDeletion extends MailboxEvent {
-        private final MailboxACL mailboxACL;
-        private final QuotaRoot quotaRoot;
-        private final QuotaCountUsage deletedMessageCount;
-        private final QuotaSizeUsage totalDeletedSize;
-
-        public MailboxDeletion(MailboxSession.SessionId sessionId, Username username, MailboxPath path, MailboxACL mailboxACL, QuotaRoot quotaRoot, QuotaCountUsage deletedMessageCount, QuotaSizeUsage totalDeletedSize,
-                               MailboxId mailboxId, EventId eventId) {
-            super(sessionId, username, path, mailboxId, eventId);
-            this.mailboxACL = mailboxACL;
-            this.quotaRoot = quotaRoot;
-            this.deletedMessageCount = deletedMessageCount;
-            this.totalDeletedSize = totalDeletedSize;
-        }
-
-        @Override
-        public boolean isNoop() {
-            return false;
-        }
-
-        public MailboxACL getMailboxACL() {
-            return mailboxACL;
-        }
-
-        public QuotaRoot getQuotaRoot() {
-            return quotaRoot;
-        }
-
-        public QuotaCountUsage getDeletedMessageCount() {
-            return deletedMessageCount;
-        }
-
-        public QuotaSizeUsage getTotalDeletedSize() {
-            return totalDeletedSize;
-        }
-
-        @Override
-        public final boolean equals(Object o) {
-            if (o instanceof MailboxDeletion) {
-                MailboxDeletion that = (MailboxDeletion) o;
-
-                return Objects.equals(this.eventId, that.eventId)
-                    && Objects.equals(this.sessionId, that.sessionId)
-                    && Objects.equals(this.username, that.username)
-                    && Objects.equals(this.path, that.path)
-                    && Objects.equals(this.mailboxACL, that.mailboxACL)
-                    && Objects.equals(this.mailboxId, that.mailboxId)
-                    && Objects.equals(this.quotaRoot, that.quotaRoot)
-                    && Objects.equals(this.deletedMessageCount, that.deletedMessageCount)
-                    && Objects.equals(this.totalDeletedSize, that.totalDeletedSize);
-            }
-            return false;
-        }
-
-        @Override
-        public final int hashCode() {
-            return Objects.hash(eventId, sessionId, username, path, mailboxACL, mailboxId, quotaRoot, deletedMessageCount, totalDeletedSize);
-        }
-    }
-
-    /**
-     * Indicates that a mailbox has been Added.
-     */
-    class MailboxAdded extends MailboxEvent {
-
-        public MailboxAdded(MailboxSession.SessionId sessionId, Username username, MailboxPath path, MailboxId mailboxId, EventId eventId) {
-            super(sessionId, username, path, mailboxId, eventId);
-        }
-
-        @Override
-        public boolean isNoop() {
-            return false;
-        }
-
-        @Override
-        public final boolean equals(Object o) {
-            if (o instanceof MailboxAdded) {
-                MailboxAdded that = (MailboxAdded) o;
-
-                return Objects.equals(this.eventId, that.eventId)
-                    && Objects.equals(this.sessionId, that.sessionId)
-                    && Objects.equals(this.username, that.username)
-                    && Objects.equals(this.path, that.path)
-                    && Objects.equals(this.mailboxId, that.mailboxId);
-            }
-            return false;
-        }
-
-        @Override
-        public final int hashCode() {
-            return Objects.hash(eventId, sessionId, username, path, mailboxId);
-        }
-    }
-
-    /**
-     * Indicates that a mailbox has been renamed.
-     */
-    class MailboxRenamed extends MailboxEvent {
-        private final MailboxPath newPath;
-
-        public MailboxRenamed(MailboxSession.SessionId sessionId, Username username, MailboxPath path, MailboxId mailboxId, MailboxPath newPath, EventId eventId) {
-            super(sessionId, username, path, mailboxId, eventId);
-            this.newPath = newPath;
-        }
-
-        @Override
-        public boolean isNoop() {
-            return newPath.equals(path);
-        }
-
-        /**
-         * Gets the new name for this mailbox.
-         *
-         * @return name, not null
-         */
-        public MailboxPath getNewPath() {
-            return newPath;
-        }
-
-        @Override
-        public final boolean equals(Object o) {
-            if (o instanceof MailboxRenamed) {
-                MailboxRenamed that = (MailboxRenamed) o;
-
-                return Objects.equals(this.eventId, that.eventId)
-                    && Objects.equals(this.sessionId, that.sessionId)
-                    && Objects.equals(this.username, that.username)
-                    && Objects.equals(this.path, that.path)
-                    && Objects.equals(this.mailboxId, that.mailboxId)
-                    && Objects.equals(this.newPath, that.newPath);
-            }
-            return false;
-        }
-
-        @Override
-        public final int hashCode() {
-            return Objects.hash(eventId, sessionId, username, path, mailboxId, newPath);
-        }
-    }
-
-
-    /**
-     * A mailbox event related to updated ACL
-     */
-    class MailboxACLUpdated extends MailboxEvent {
-        private final ACLDiff aclDiff;
-
-        public MailboxACLUpdated(MailboxSession.SessionId sessionId, Username username, MailboxPath path, ACLDiff aclDiff, MailboxId mailboxId, EventId eventId) {
-            super(sessionId, username, path, mailboxId, eventId);
-            this.aclDiff = aclDiff;
-        }
-
-        public ACLDiff getAclDiff() {
-            return aclDiff;
-        }
-
-        @Override
-        public boolean isNoop() {
-            return aclDiff.getNewACL().equals(aclDiff.getOldACL());
-        }
-
-        @Override
-        public final boolean equals(Object o) {
-            if (o instanceof MailboxACLUpdated) {
-                MailboxACLUpdated that = (MailboxACLUpdated) o;
-
-                return Objects.equals(this.eventId, that.eventId)
-                    && Objects.equals(this.sessionId, that.sessionId)
-                    && Objects.equals(this.username, that.username)
-                    && Objects.equals(this.path, that.path)
-                    && Objects.equals(this.aclDiff, that.aclDiff)
-                    && Objects.equals(this.mailboxId, that.mailboxId);
-            }
-            return false;
-        }
-
-        @Override
-        public final int hashCode() {
-            return Objects.hash(eventId, sessionId, username, path, aclDiff, mailboxId);
-        }
-
-    }
-
-    /**
-     * A mailbox event related to a message.
-     */
-    abstract class MessageEvent extends MailboxEvent {
-
-        public MessageEvent(MailboxSession.SessionId sessionId, Username username, MailboxPath path, MailboxId mailboxId, EventId eventId) {
-            super(sessionId, username, path, mailboxId, eventId);
-        }
-
-        /**
-         * Gets the message UIDs for the subject of this event.
-         *
-         * @return message uids
-         */
-        public abstract Collection<MessageUid> getUids();
-    }
-
-    abstract class MetaDataHoldingEvent extends MessageEvent {
-
-        public MetaDataHoldingEvent(MailboxSession.SessionId sessionId, Username username, MailboxPath path, MailboxId mailboxId, EventId eventId) {
-            super(sessionId, username, path, mailboxId, eventId);
-        }
-
-        /**
-         * Return the flags which were set for the affected message
-         *
-         * @return flags
-         */
-        public abstract MessageMetaData getMetaData(MessageUid uid);
-
-        public ImmutableSet<MessageId> getMessageIds() {
-            return getUids()
-                .stream()
-                .map(uid -> getMetaData(uid).getMessageId())
-                .collect(Guavate.toImmutableSet());
-        }
-    }
-
-    class Expunged extends MetaDataHoldingEvent {
-        private final Map<MessageUid, MessageMetaData> expunged;
-
-        public Expunged(MailboxSession.SessionId sessionId, Username username, MailboxPath path, MailboxId mailboxId, Map<MessageUid, MessageMetaData> uids, EventId eventId) {
-            super(sessionId, username, path, mailboxId, eventId);
-            this.expunged = ImmutableMap.copyOf(uids);
-        }
-
-        @Override
-        public Collection<MessageUid> getUids() {
-            return expunged.keySet();
-        }
-
-        /**
-         * Return the flags which were set for the added message
-         *
-         * @return flags
-         */
-        @Override
-        public MessageMetaData getMetaData(MessageUid uid) {
-            return expunged.get(uid);
-        }
-
-        public Map<MessageUid, MessageMetaData> getExpunged() {
-            return expunged;
-        }
-
-        @Override
-        public boolean isNoop() {
-            return expunged.isEmpty();
-        }
-
-        @Override
-        public final boolean equals(Object o) {
-            if (o instanceof Expunged) {
-                Expunged that = (Expunged) o;
-
-                return Objects.equals(this.eventId, that.eventId)
-                    && Objects.equals(this.sessionId, that.sessionId)
-                    && Objects.equals(this.username, that.username)
-                    && Objects.equals(this.path, that.path)
-                    && Objects.equals(this.mailboxId, that.mailboxId)
-                    && Objects.equals(this.expunged, that.expunged);
-            }
-            return false;
-        }
-
-        @Override
-        public final int hashCode() {
-            return Objects.hash(eventId, sessionId, username, path, mailboxId, expunged);
-        }
-    }
-
-    /**
-     * A mailbox event related to updated flags
-     */
-    class FlagsUpdated extends MessageEvent {
-        private final List<UpdatedFlags> updatedFlags;
-
-        public FlagsUpdated(MailboxSession.SessionId sessionId, Username username, MailboxPath path,
-                            MailboxId mailboxId, List<UpdatedFlags> updatedFlags, EventId eventId) {
-            super(sessionId, username, path, mailboxId, eventId);
-            this.updatedFlags = ImmutableList.copyOf(updatedFlags);
-        }
-
-        @Override
-        public Collection<MessageUid> getUids() {
-            return updatedFlags.stream()
-                .map(UpdatedFlags::getUid)
-                .collect(Guavate.toImmutableList());
-        }
-
-        public Collection<MessageId> getMessageIds() {
-            return updatedFlags.stream()
-                .map(UpdatedFlags::getMessageId)
-                .flatMap(Optional::stream)
-                .collect(Guavate.toImmutableList());
-        }
-
-        public List<UpdatedFlags> getUpdatedFlags() {
-            return updatedFlags;
-        }
-
-        @Override
-        public boolean isNoop() {
-            return updatedFlags.isEmpty();
-        }
-
-        @Override
-        public final boolean equals(Object o) {
-            if (o instanceof FlagsUpdated) {
-                FlagsUpdated that = (FlagsUpdated) o;
-
-                return Objects.equals(this.eventId, that.eventId)
-                    && Objects.equals(this.sessionId, that.sessionId)
-                    && Objects.equals(this.username, that.username)
-                    && Objects.equals(this.path, that.path)
-                    && Objects.equals(this.mailboxId, that.mailboxId)
-                    && Objects.equals(this.updatedFlags, that.updatedFlags);
-            }
-            return false;
-        }
-
-        @Override
-        public final int hashCode() {
-            return Objects.hash(eventId, sessionId, username, path, mailboxId, updatedFlags);
-        }
-    }
-
-    /**
-     * A mailbox event related to added message
-     */
-    class Added extends MetaDataHoldingEvent {
-        private final Map<MessageUid, MessageMetaData> added;
-
-        public Added(MailboxSession.SessionId sessionId, Username username, MailboxPath path, MailboxId mailboxId,
-                     SortedMap<MessageUid, MessageMetaData> uids, EventId eventId) {
-            super(sessionId, username, path, mailboxId, eventId);
-            this.added = ImmutableMap.copyOf(uids);
-        }
-
-        /**
-         * Return the flags which were set for the added message
-         *
-         * @return flags
-         */
-        public MessageMetaData getMetaData(MessageUid uid) {
-            return added.get(uid);
-        }
-
-        @Override
-        public Collection<MessageUid> getUids() {
-            return added.keySet();
-        }
-
-        public Map<MessageUid, MessageMetaData> getAdded() {
-            return added;
-        }
-
-        @Override
-        public boolean isNoop() {
-            return added.isEmpty();
-        }
-
-        @Override
-        public final boolean equals(Object o) {
-            if (o instanceof Added) {
-                Added that = (Added) o;
-
-                return Objects.equals(this.eventId, that.eventId)
-                    && Objects.equals(this.sessionId, that.sessionId)
-                    && Objects.equals(this.username, that.username)
-                    && Objects.equals(this.path, that.path)
-                    && Objects.equals(this.mailboxId, that.mailboxId)
-                    && Objects.equals(this.added, that.added);
-            }
-            return false;
-        }
-
-        @Override
-        public final int hashCode() {
-            return Objects.hash(eventId, sessionId, username, path, mailboxId, added);
-        }
-    }
-
-}
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxIdRegistrationKey.java b/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxIdRegistrationKey.java
deleted file mode 100644
index cbbd20b..0000000
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxIdRegistrationKey.java
+++ /dev/null
@@ -1,78 +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.mailbox.events;
-
-import java.util.Objects;
-
-import javax.inject.Inject;
-
-import org.apache.james.events.RegistrationKey;
-import org.apache.james.mailbox.model.MailboxId;
-
-public class MailboxIdRegistrationKey implements RegistrationKey {
-    public static class Factory implements RegistrationKey.Factory {
-        private final MailboxId.Factory mailboxIdFactory;
-
-        @Inject
-        public Factory(MailboxId.Factory mailboxIdFactory) {
-            this.mailboxIdFactory = mailboxIdFactory;
-        }
-
-        @Override
-        public Class<? extends RegistrationKey> forClass() {
-            return MailboxIdRegistrationKey.class;
-        }
-
-        @Override
-        public RegistrationKey fromString(String asString) {
-            return new MailboxIdRegistrationKey(mailboxIdFactory.fromString(asString));
-        }
-    }
-
-    private final MailboxId mailboxId;
-
-    public MailboxIdRegistrationKey(MailboxId mailboxId) {
-        this.mailboxId = mailboxId;
-    }
-
-    public MailboxId getMailboxId() {
-        return mailboxId;
-    }
-
-    @Override
-    public String asString() {
-        return mailboxId.serialize();
-    }
-
-    @Override
-    public final boolean equals(Object o) {
-        if (o instanceof MailboxIdRegistrationKey) {
-            MailboxIdRegistrationKey that = (MailboxIdRegistrationKey) o;
-
-            return Objects.equals(this.mailboxId, that.mailboxId);
-        }
-        return false;
-    }
-
-    @Override
-    public final int hashCode() {
-        return Objects.hash(mailboxId);
-    }
-}
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MessageMoveEvent.java b/mailbox/api/src/main/java/org/apache/james/mailbox/events/MessageMoveEvent.java
deleted file mode 100644
index 69173d2..0000000
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MessageMoveEvent.java
+++ /dev/null
@@ -1,154 +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.mailbox.events;
-
-import java.util.Collection;
-import java.util.Objects;
-import java.util.Optional;
-
-import org.apache.james.core.Username;
-import org.apache.james.events.Event;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.mailbox.model.MessageMoves;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-
-public class MessageMoveEvent implements Event {
-
-    public static Builder builder() {
-        return new Builder();
-    }
-
-    public static class Builder {
-        private ImmutableList.Builder<MessageId> messageIds;
-        private Username username;
-        private MessageMoves messageMoves;
-        private Optional<EventId> eventId;
-
-        private Builder() {
-            messageIds = ImmutableList.builder();
-            eventId = Optional.empty();
-        }
-
-        public Builder session(MailboxSession session) {
-            this.username = session.getUser();
-            return this;
-        }
-
-        public Builder user(Username username) {
-            this.username = username;
-            return this;
-        }
-
-        public Builder messageMoves(MessageMoves messageMoves) {
-            this.messageMoves = messageMoves;
-            return this;
-        }
-
-        public Builder messageId(MessageId messageId) {
-            this.messageIds.add(messageId);
-            return this;
-        }
-
-        public Builder eventId(EventId eventId) {
-            this.eventId = Optional.of(eventId);
-            return this;
-        }
-
-        public Builder messageId(Iterable<MessageId> messageIds) {
-            this.messageIds.addAll(messageIds);
-            return this;
-        }
-
-        public MessageMoveEvent build() {
-            Preconditions.checkNotNull(username, "'user' is mandatory");
-            Preconditions.checkNotNull(messageMoves, "'messageMoves' is mandatory");
-
-            return new MessageMoveEvent(eventId.orElse(EventId.random()), username, messageMoves, messageIds.build());
-        }
-    }
-
-    private final EventId eventId;
-    private final Username username;
-    private final MessageMoves messageMoves;
-    private final Collection<MessageId> messageIds;
-
-    @VisibleForTesting
-    MessageMoveEvent(EventId eventId, Username username, MessageMoves messageMoves, Collection<MessageId> messageIds) {
-        this.eventId = eventId;
-        this.username = username;
-        this.messageMoves = messageMoves;
-        this.messageIds = messageIds;
-    }
-
-    @Override
-    public boolean isNoop() {
-        return messageIds.isEmpty();
-    }
-
-    public Collection<MessageId> getMessageIds() {
-        return messageIds;
-    }
-
-    @Override
-    public EventId getEventId() {
-        return eventId;
-    }
-
-    @Override
-    public Username getUsername() {
-        return username;
-    }
-
-    public MessageMoves getMessageMoves() {
-        return messageMoves;
-    }
-
-    public boolean isMoveTo(MailboxId mailboxId) {
-        return messageMoves.addedMailboxIds()
-                .contains(mailboxId);
-    }
-
-    public boolean isMoveFrom(MailboxId mailboxId) {
-        return messageMoves.removedMailboxIds()
-                .contains(mailboxId);
-    }
-
-    @Override
-    public final boolean equals(Object o) {
-        if (o instanceof MessageMoveEvent) {
-            MessageMoveEvent that = (MessageMoveEvent) o;
-
-            return Objects.equals(this.eventId, that.eventId)
-                && Objects.equals(this.username, that.username)
-                && Objects.equals(this.messageMoves, that.messageMoves)
-                && Objects.equals(this.messageIds, that.messageIds);
-        }
-        return false;
-    }
-
-    @Override
-    public final int hashCode() {
-        return Objects.hash(eventId, username, messageMoves, messageIds);
-    }
-}
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/RetryBackoffConfiguration.java b/mailbox/api/src/main/java/org/apache/james/mailbox/events/RetryBackoffConfiguration.java
deleted file mode 100644
index f90a4d4..0000000
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/RetryBackoffConfiguration.java
+++ /dev/null
@@ -1,125 +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.mailbox.events;
-
-import java.time.Duration;
-import java.util.Objects;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Preconditions;
-
-public class RetryBackoffConfiguration {
-
-    @FunctionalInterface
-    public interface RequireMaxRetries {
-        RequireFirstBackoff maxRetries(int maxRetries);
-    }
-
-    @FunctionalInterface
-    public interface RequireFirstBackoff {
-        RequireJitterFactor firstBackoff(Duration firstBackoff);
-    }
-
-    @FunctionalInterface
-    public interface RequireJitterFactor {
-        ReadyToBuild jitterFactor(double jitterFactor);
-    }
-
-    public static class ReadyToBuild {
-        private final int maxRetries;
-        private final Duration firstBackoff;
-        private final double jitterFactor;
-
-        private ReadyToBuild(int maxRetries, Duration firstBackoff, double jitterFactor) {
-            this.maxRetries = maxRetries;
-            this.firstBackoff = firstBackoff;
-            this.jitterFactor = jitterFactor;
-        }
-
-        public RetryBackoffConfiguration build() {
-            return new RetryBackoffConfiguration(maxRetries, firstBackoff, jitterFactor);
-        }
-    }
-
-    public static RequireMaxRetries builder() {
-        return maxRetries -> firstBackoff -> jitterFactor -> new ReadyToBuild(maxRetries, firstBackoff, jitterFactor);
-    }
-
-    static final double DEFAULT_JITTER_FACTOR = 0.5;
-    static final int DEFAULT_MAX_RETRIES = 8;
-    static final Duration DEFAULT_FIRST_BACKOFF = Duration.ofMillis(100);
-    public static final RetryBackoffConfiguration DEFAULT = new RetryBackoffConfiguration(
-        DEFAULT_MAX_RETRIES,
-        DEFAULT_FIRST_BACKOFF,
-        DEFAULT_JITTER_FACTOR);
-
-    private final int maxRetries;
-    private final Duration firstBackoff;
-    private final double jitterFactor;
-
-    private RetryBackoffConfiguration(int maxRetries, Duration firstBackoff, double jitterFactor) {
-        Preconditions.checkArgument(!firstBackoff.isNegative(), "firstBackoff is not allowed to be negative");
-        Preconditions.checkArgument(maxRetries >= 0, "maxRetries is not allowed to be negative");
-        Preconditions.checkArgument(jitterFactor >= 0 && jitterFactor <= 1.0, "jitterFactor is not " +
-            "allowed to be negative or greater than 1");
-
-        this.maxRetries = maxRetries;
-        this.firstBackoff = firstBackoff;
-        this.jitterFactor = jitterFactor;
-    }
-
-    public int getMaxRetries() {
-        return maxRetries;
-    }
-
-    public Duration getFirstBackoff() {
-        return firstBackoff;
-    }
-
-    public double getJitterFactor() {
-        return jitterFactor;
-    }
-
-    @Override
-    public final boolean equals(Object o) {
-        if (o instanceof RetryBackoffConfiguration) {
-            RetryBackoffConfiguration that = (RetryBackoffConfiguration) o;
-
-            return Objects.equals(this.maxRetries, that.maxRetries)
-                && Objects.equals(this.jitterFactor, that.jitterFactor)
-                && Objects.equals(this.firstBackoff, that.firstBackoff);
-        }
-        return false;
-    }
-
-    @Override
-    public final int hashCode() {
-        return Objects.hash(maxRetries, firstBackoff, jitterFactor);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(this)
-            .add("maxRetries", maxRetries)
-            .add("firstBackoff", firstBackoff)
-            .add("jitterFactor", jitterFactor)
-            .toString();
-    }
-}
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/EventTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/EventTest.java
index c25f7df..1d36cd7 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/EventTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/EventTest.java
@@ -28,7 +28,7 @@ import javax.mail.Flags;
 
 import org.apache.james.core.Username;
 import org.apache.james.events.Event;
-import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.events.MailboxEvents.Added;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.TestId;
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxListenerTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxListenerTest.java
index 13fa417..5ff940d 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxListenerTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxListenerTest.java
@@ -34,15 +34,15 @@ import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
 import org.apache.james.events.Event;
+import org.apache.james.events.MailboxEvents.Added;
+import org.apache.james.events.MailboxEvents.Expunged;
+import org.apache.james.events.MailboxEvents.FlagsUpdated;
+import org.apache.james.events.MailboxEvents.MailboxACLUpdated;
+import org.apache.james.events.MailboxEvents.MailboxAdded;
+import org.apache.james.events.MailboxEvents.MailboxDeletion;
+import org.apache.james.events.MailboxEvents.MailboxRenamed;
+import org.apache.james.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.acl.ACLDiff;
-import org.apache.james.mailbox.events.MailboxEvents.Added;
-import org.apache.james.mailbox.events.MailboxEvents.Expunged;
-import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxACLUpdated;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxRenamed;
-import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageMetaData;
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java
index d8667e2..bd95fd3 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java
@@ -33,8 +33,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.james.core.Username;
 import org.apache.james.events.EventBus;
-import org.apache.james.mailbox.events.MailboxEvents.Added;
-import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
+import org.apache.james.events.MailboxEvents.Added;
+import org.apache.james.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.MailboxId;
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
index 7a23c69..03c5a46 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
@@ -47,17 +47,17 @@ import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
 import org.apache.james.events.EventBus;
+import org.apache.james.events.MailboxEvents.Added;
+import org.apache.james.events.MailboxEvents.Expunged;
+import org.apache.james.events.MailboxEvents.FlagsUpdated;
+import org.apache.james.events.MailboxEvents.MailboxAdded;
+import org.apache.james.events.MailboxEvents.MailboxDeletion;
+import org.apache.james.events.MailboxEvents.QuotaUsageUpdatedEvent;
+import org.apache.james.events.MailboxIdRegistrationKey;
+import org.apache.james.events.MessageMoveEvent;
 import org.apache.james.mailbox.MailboxManager.MailboxCapabilities;
 import org.apache.james.mailbox.MailboxManager.MailboxRenamedResult;
 import org.apache.james.mailbox.MessageManager.AppendCommand;
-import org.apache.james.mailbox.events.MailboxEvents.Added;
-import org.apache.james.mailbox.events.MailboxEvents.Expunged;
-import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
-import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
-import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
-import org.apache.james.mailbox.events.MessageMoveEvent;
 import org.apache.james.mailbox.exception.AnnotationException;
 import org.apache.james.mailbox.exception.HasEmptyMailboxNameInHierarchyException;
 import org.apache.james.mailbox.exception.InboxAlreadyCreated;
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MessageMoveEventTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MessageMoveEventTest.java
index 0069e62..73859f4 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MessageMoveEventTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MessageMoveEventTest.java
@@ -22,7 +22,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import org.apache.james.core.Username;
-import org.apache.james.mailbox.events.MessageMoveEvent;
+import org.apache.james.events.MessageMoveEvent;
 import org.apache.james.mailbox.model.MessageMoves;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/ErrorHandlingContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/ErrorHandlingContract.java
deleted file mode 100644
index 226f1bb..0000000
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/ErrorHandlingContract.java
+++ /dev/null
@@ -1,367 +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.mailbox.events;
-
-import static org.apache.james.mailbox.events.EventBusTestFixture.DEFAULT_FIRST_BACKOFF;
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT;
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT_2;
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT_ID;
-import static org.apache.james.mailbox.events.EventBusTestFixture.GROUP_A;
-import static org.apache.james.mailbox.events.EventBusTestFixture.KEY_1;
-import static org.apache.james.mailbox.events.EventBusTestFixture.NO_KEYS;
-import static org.apache.james.mailbox.events.EventBusTestFixture.RETRY_BACKOFF_CONFIGURATION;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.spy;
-
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.james.events.Event;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.events.EventListener;
-import org.apache.james.mailbox.util.EventCollector;
-import org.assertj.core.api.SoftAssertions;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-
-import com.google.common.collect.ImmutableSet;
-
-import reactor.core.publisher.Mono;
-
-interface ErrorHandlingContract extends EventBusContract {
-
-    class ThrowingListener implements EventListener {
-        private final List<Instant> timeElapsed;
-
-        private ThrowingListener() {
-            timeElapsed = new ArrayList<>();
-        }
-
-        @Override
-        public boolean isHandling(Event event) {
-            return true;
-        }
-
-        @Override
-        public void event(Event event) {
-            timeElapsed.add(Instant.now());
-            throw new RuntimeException("throw to trigger reactor retry");
-        }
-
-        public int executionCount() {
-            return timeElapsed.size();
-        }
-    }
-
-    EventDeadLetters deadLetter();
-
-    default EventCollector eventCollector() {
-        return spy(new EventCollector());
-    }
-
-    default ThrowingListener throwingListener() {
-        return new ThrowingListener();
-    }
-
-    @Test
-    default void retryingIsNotAppliedForKeyRegistrations() {
-        EventCollector eventCollector = eventCollector();
-
-        doThrow(new RuntimeException())
-            .when(eventCollector).event(EVENT);
-
-        Mono.from(eventBus().register(eventCollector, KEY_1)).block();
-        eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
-        assertThat(eventCollector.getEvents())
-            .isEmpty();
-    }
-
-    @Test
-    default void listenerShouldReceiveWhenFailsLessThanMaxRetries() {
-        EventCollector eventCollector = eventCollector();
-
-        doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doCallRealMethod()
-            .when(eventCollector).event(EVENT);
-
-        eventBus().register(eventCollector, GROUP_A);
-        eventBus().dispatch(EVENT, NO_KEYS).block();
-
-        getSpeedProfile().shortWaitCondition()
-            .untilAsserted(() -> assertThat(eventCollector.getEvents()).hasSize(1));
-    }
-
-    @Test
-    default void listenerShouldReceiveWhenFailsEqualsMaxRetries() {
-        EventCollector eventCollector = eventCollector();
-        //do throw  RetryBackoffConfiguration.DEFAULT.DEFAULT_MAX_RETRIES
-        doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doCallRealMethod()
-            .when(eventCollector).event(EVENT);
-
-        eventBus().register(eventCollector, GROUP_A);
-        eventBus().dispatch(EVENT, NO_KEYS).block();
-
-        getSpeedProfile().longWaitCondition()
-            .untilAsserted(() -> assertThat(eventCollector.getEvents()).hasSize(1));
-    }
-
-    @Test
-    default void listenerShouldNotReceiveWhenFailsGreaterThanMaxRetries() throws Exception {
-        EventCollector eventCollector = eventCollector();
-
-        //do throw  RetryBackoffConfiguration.DEFAULT.DEFAULT_MAX_RETRIES + 1 times
-        doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doCallRealMethod()
-            .when(eventCollector).event(EVENT);
-
-        eventBus().register(eventCollector, GROUP_A);
-        eventBus().dispatch(EVENT, NO_KEYS).block();
-
-        TimeUnit.SECONDS.sleep(1);
-        assertThat(eventCollector.getEvents())
-            .isEmpty();
-    }
-
-    @Test
-    default void exceedingMaxRetriesShouldStopConsumingFailedEvent() throws Exception {
-        ThrowingListener throwingListener = throwingListener();
-
-        eventBus().register(throwingListener, GROUP_A);
-        eventBus().dispatch(EVENT, NO_KEYS).block();
-
-        getSpeedProfile().shortWaitCondition()
-            .untilAsserted(() -> assertThat(throwingListener.executionCount()).isEqualTo(4));
-        Thread.sleep(getSpeedProfile().getShortWaitTime().toMillis());
-
-        assertThat(throwingListener.executionCount())
-            .isEqualTo(4);
-    }
-
-    @Test
-    default void retriesBackOffShouldDelayByExponentialGrowth() {
-        ThrowingListener throwingListener = throwingListener();
-
-        eventBus().register(throwingListener, GROUP_A);
-        eventBus().dispatch(EVENT, NO_KEYS).block();
-
-        getSpeedProfile().shortWaitCondition()
-            .untilAsserted(() -> assertThat(throwingListener.executionCount()).isEqualTo(4));
-        SoftAssertions.assertSoftly(softly -> {
-            List<Instant> timeElapsed = throwingListener.timeElapsed;
-            softly.assertThat(timeElapsed).hasSize(RETRY_BACKOFF_CONFIGURATION.getMaxRetries() + 1);
-
-            long minFirstDelayAfter = DEFAULT_FIRST_BACKOFF.toMillis(); // first backOff
-            long minSecondDelayAfter = DEFAULT_FIRST_BACKOFF.toMillis() / 2; // first_backOff * jitter factor (first_backOff * 0.5)
-            long minThirdDelayAfter = DEFAULT_FIRST_BACKOFF.toMillis(); // first_backOff * jitter factor (first_backOff * 1)
-
-            softly.assertThat(timeElapsed.get(1))
-                .isAfterOrEqualTo(timeElapsed.get(0).plusMillis(minFirstDelayAfter));
-
-            softly.assertThat(timeElapsed.get(2))
-                .isAfterOrEqualTo(timeElapsed.get(1).plusMillis(minSecondDelayAfter));
-
-            softly.assertThat(timeElapsed.get(3))
-                .isAfterOrEqualTo(timeElapsed.get(2).plusMillis(minThirdDelayAfter));
-        });
-    }
-
-    @Test
-    default void retryingListenerCallingDispatchShouldNotFail() {
-        AtomicBoolean firstExecution = new AtomicBoolean(true);
-        AtomicBoolean successfulRetry = new AtomicBoolean(false);
-        EventListener listener = event -> {
-            if (event.getEventId().equals(EVENT_ID)) {
-                if (firstExecution.get()) {
-                    firstExecution.set(false);
-                    throw new RuntimeException();
-                }
-                eventBus().dispatch(EVENT_2, NO_KEYS).block();
-                successfulRetry.set(true);
-            }
-        };
-
-        eventBus().register(listener, GROUP_A);
-        eventBus().dispatch(EVENT, NO_KEYS).block();
-
-        getSpeedProfile().shortWaitCondition().until(successfulRetry::get);
-    }
-
-    @Test
-    default void deadLettersIsNotAppliedForKeyRegistrations() throws Exception {
-        EventCollector eventCollector = eventCollector();
-
-        //do throw  RetryBackoffConfiguration.DEFAULT.DEFAULT_MAX_RETRIES + 1 times
-        doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doCallRealMethod()
-            .when(eventCollector).event(EVENT);
-
-        Mono.from(eventBus().register(eventCollector, KEY_1)).block();
-        eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
-        TimeUnit.SECONDS.sleep(1);
-        SoftAssertions.assertSoftly(softly -> {
-            softly.assertThat(eventCollector.getEvents()).isEmpty();
-            softly.assertThat(deadLetter().groupsWithFailedEvents().toIterable())
-                .isEmpty();
-        });
-    }
-
-    @Test
-    default void deadLetterShouldNotStoreWhenFailsLessThanMaxRetries() {
-        EventCollector eventCollector = eventCollector();
-
-        doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doCallRealMethod()
-            .when(eventCollector).event(EVENT);
-
-        eventBus().register(eventCollector, new EventBusTestFixture.GroupA());
-        eventBus().dispatch(EVENT, NO_KEYS).block();
-
-        getSpeedProfile().shortWaitCondition()
-            .untilAsserted(() -> assertThat(eventCollector.getEvents()).hasSize(1));
-
-        assertThat(deadLetter().groupsWithFailedEvents().toIterable())
-            .isEmpty();
-    }
-
-    @Test
-    default void deadLetterShouldStoreWhenDispatchFailsGreaterThanMaxRetries() {
-        EventCollector eventCollector = eventCollector();
-        //do throw  RetryBackoffConfiguration.DEFAULT.DEFAULT_MAX_RETRIES + 1 times
-        doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doCallRealMethod()
-            .when(eventCollector).event(EVENT);
-
-        eventBus().register(eventCollector, GROUP_A);
-        eventBus().dispatch(EVENT, NO_KEYS).block();
-
-        getSpeedProfile().longWaitCondition()
-            .untilAsserted(() -> assertThat(deadLetter().failedIds(GROUP_A)
-                .flatMap(insertionId -> deadLetter().failedEvent(GROUP_A, insertionId))
-                .toIterable())
-            .containsOnly(EVENT));
-        assertThat(eventCollector.getEvents())
-            .isEmpty();
-    }
-
-    @Test
-    default void deadLetterShouldStoreWhenRedeliverFailsGreaterThanMaxRetries() {
-        EventCollector eventCollector = eventCollector();
-
-        //do throw  RetryBackoffConfiguration.DEFAULT.DEFAULT_MAX_RETRIES + 1 times
-        doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doCallRealMethod()
-            .when(eventCollector).event(EVENT);
-
-        eventBus().register(eventCollector, GROUP_A);
-        eventBus().reDeliver(GROUP_A, EVENT).block();
-
-        getSpeedProfile().longWaitCondition()
-            .untilAsserted(() ->
-                assertThat(
-                        deadLetter()
-                            .failedIds(GROUP_A)
-                            .flatMap(insertionId -> deadLetter().failedEvent(GROUP_A, insertionId))
-                            .toIterable())
-                .containsOnly(EVENT));
-        assertThat(eventCollector.getEvents()).isEmpty();
-    }
-
-    @Disabled("JAMES-2907 redeliver should work as initial dispatch")
-    @Test
-    default void retryShouldDeliverAsManyTimesAsInitialDeliveryAttempt() {
-        EventCollector eventCollector = eventCollector();
-
-        //do throw  RetryBackoffConfiguration.DEFAULT.DEFAULT_MAX_RETRIES + 1 times
-        doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doThrow(new RuntimeException())
-            .doCallRealMethod()
-            .when(eventCollector).event(EVENT);
-
-        eventBus().register(eventCollector, GROUP_A);
-        eventBus().reDeliver(GROUP_A, EVENT).block();
-
-        getSpeedProfile().longWaitCondition()
-            .untilAsserted(() -> assertThat(eventCollector.getEvents()).isNotEmpty());
-    }
-
-    @Test
-    default void redeliverShouldNotSendEventsToKeyListeners() {
-        EventCollector eventCollector = eventCollector();
-        EventCollector eventCollector2 = eventCollector();
-
-        eventBus().register(eventCollector, GROUP_A);
-        Mono.from(eventBus().register(eventCollector2, KEY_1)).block();
-        eventBus().reDeliver(GROUP_A, EVENT).block();
-
-        getSpeedProfile().longWaitCondition()
-            .untilAsserted(() -> assertThat(eventCollector.getEvents()).hasSize(1));
-        assertThat(eventCollector2.getEvents()).isEmpty();
-    }
-}
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusConcurrentTestContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusConcurrentTestContract.java
deleted file mode 100644
index 8b73023..0000000
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusConcurrentTestContract.java
+++ /dev/null
@@ -1,240 +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.mailbox.events;
-
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT;
-import static org.apache.james.mailbox.events.EventBusTestFixture.KEY_1;
-import static org.apache.james.mailbox.events.EventBusTestFixture.KEY_2;
-import static org.apache.james.mailbox.events.EventBusTestFixture.KEY_3;
-import static org.apache.james.mailbox.events.EventBusTestFixture.NO_KEYS;
-import static org.apache.james.mailbox.events.EventDeadLettersContract.GROUP_A;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.awaitility.Awaitility.await;
-
-import java.time.Duration;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.james.events.EventBus;
-import org.apache.james.events.RegistrationKey;
-import org.apache.james.util.concurrency.ConcurrentTestRunner;
-import org.awaitility.core.ConditionFactory;
-import org.junit.jupiter.api.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-import reactor.core.publisher.Mono;
-
-public interface EventBusConcurrentTestContract {
-
-    Duration FIVE_SECONDS = Duration.ofSeconds(5);
-    ConditionFactory AWAIT_CONDITION = await().timeout(new org.awaitility.Duration(5, TimeUnit.SECONDS));
-
-    int THREAD_COUNT = 10;
-    int OPERATION_COUNT = 30;
-    int TOTAL_DISPATCH_OPERATIONS = THREAD_COUNT * OPERATION_COUNT;
-
-    Set<RegistrationKey> ALL_KEYS = ImmutableSet.of(KEY_1, KEY_2, KEY_3);
-
-    static EventBusTestFixture.EventListenerCountingSuccessfulExecution newCountingListener() {
-        return new EventBusTestFixture.EventListenerCountingSuccessfulExecution();
-    }
-
-    static int totalEventsReceived(ImmutableList<EventBusTestFixture.EventListenerCountingSuccessfulExecution> allListeners) {
-        return allListeners.stream()
-            .mapToInt(EventBusTestFixture.EventListenerCountingSuccessfulExecution::numberOfEventCalls)
-            .sum();
-    }
-
-    interface SingleEventBusConcurrentContract extends EventBusContract {
-
-        @Test
-        default void concurrentDispatchGroupShouldDeliverAllEventsToListenersWithSingleEventBus() throws Exception {
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
-
-            eventBus().register(countingListener1, new EventBusTestFixture.GroupA());
-            eventBus().register(countingListener2, new EventBusTestFixture.GroupB());
-            eventBus().register(countingListener3, new EventBusTestFixture.GroupC());
-            int totalGlobalRegistrations = 3; // GroupA + GroupB + GroupC
-
-            ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, NO_KEYS).block())
-                .threadCount(THREAD_COUNT)
-                .operationCount(OPERATION_COUNT)
-                .runSuccessfullyWithin(FIVE_SECONDS);
-
-            AWAIT_CONDITION.untilAsserted(() ->
-                assertThat(totalEventsReceived(ImmutableList.of(countingListener1, countingListener2, countingListener3)))
-                    .isEqualTo(totalGlobalRegistrations * TOTAL_DISPATCH_OPERATIONS));
-        }
-
-        @Test
-        default void concurrentDispatchKeyShouldDeliverAllEventsToListenersWithSingleEventBus() throws Exception {
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
-            Mono.from(eventBus().register(countingListener1, KEY_1)).block();
-            Mono.from(eventBus().register(countingListener2, KEY_2)).block();
-            Mono.from(eventBus().register(countingListener3, KEY_3)).block();
-
-            int totalKeyListenerRegistrations = 3; // KEY1 + KEY2 + KEY3
-            int totalEventBus = 1;
-
-            ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, ALL_KEYS).block())
-                .threadCount(THREAD_COUNT)
-                .operationCount(OPERATION_COUNT)
-                .runSuccessfullyWithin(FIVE_SECONDS);
-
-            AWAIT_CONDITION.untilAsserted(() ->
-                assertThat(totalEventsReceived(ImmutableList.of(countingListener1, countingListener2, countingListener3)))
-                    .isEqualTo(totalKeyListenerRegistrations * totalEventBus * TOTAL_DISPATCH_OPERATIONS));
-        }
-
-        @Test
-        default void concurrentDispatchShouldDeliverAllEventsToListenersWithSingleEventBus() throws Exception {
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
-
-            eventBus().register(countingListener1, new EventBusTestFixture.GroupA());
-            eventBus().register(countingListener2, new EventBusTestFixture.GroupB());
-            eventBus().register(countingListener3, new EventBusTestFixture.GroupC());
-
-            int totalGlobalRegistrations = 3; // GroupA + GroupB + GroupC
-            int totalEventDeliveredGlobally = totalGlobalRegistrations * TOTAL_DISPATCH_OPERATIONS;
-
-            Mono.from(eventBus().register(countingListener1, KEY_1)).block();
-            Mono.from(eventBus().register(countingListener2, KEY_2)).block();
-            Mono.from(eventBus().register(countingListener3, KEY_3)).block();
-            int totalKeyListenerRegistrations = 3; // KEY1 + KEY2 + KEY3
-            int totalEventDeliveredByKeys = totalKeyListenerRegistrations * TOTAL_DISPATCH_OPERATIONS;
-
-            ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, ALL_KEYS).block())
-                .threadCount(THREAD_COUNT)
-                .operationCount(OPERATION_COUNT)
-                .runSuccessfullyWithin(FIVE_SECONDS);
-
-            AWAIT_CONDITION.untilAsserted(() ->
-                assertThat(totalEventsReceived(ImmutableList.of(countingListener1, countingListener2, countingListener3)))
-                    .isEqualTo(totalEventDeliveredGlobally + totalEventDeliveredByKeys));
-        }
-    }
-
-    interface MultiEventBusConcurrentContract extends EventBusContract.MultipleEventBusContract {
-
-        EventBus eventBus3();
-
-        @Test
-        default void concurrentDispatchGroupShouldDeliverAllEventsToListenersWithMultipleEventBus() throws Exception {
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
-
-            eventBus().register(countingListener1, new EventBusTestFixture.GroupA());
-            eventBus().register(countingListener2, new EventBusTestFixture.GroupB());
-            eventBus().register(countingListener3, new EventBusTestFixture.GroupC());
-
-            eventBus2().register(countingListener1, new EventBusTestFixture.GroupA());
-            eventBus2().register(countingListener2, new EventBusTestFixture.GroupB());
-            eventBus2().register(countingListener3, new EventBusTestFixture.GroupC());
-
-            int totalGlobalRegistrations = 3; // GroupA + GroupB + GroupC
-
-            ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, NO_KEYS).block())
-                .threadCount(THREAD_COUNT)
-                .operationCount(OPERATION_COUNT)
-                .runSuccessfullyWithin(FIVE_SECONDS);
-
-            AWAIT_CONDITION.untilAsserted(() ->
-                assertThat(totalEventsReceived(ImmutableList.of(countingListener1, countingListener2, countingListener3)))
-                    .isEqualTo(totalGlobalRegistrations * TOTAL_DISPATCH_OPERATIONS));
-        }
-
-        @Test
-        default void concurrentDispatchKeyShouldDeliverAllEventsToListenersWithMultipleEventBus() throws Exception {
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
-
-            Mono.from(eventBus().register(countingListener1, KEY_1)).block();
-            Mono.from(eventBus().register(countingListener2, KEY_2)).block();
-            Mono.from(eventBus().register(countingListener3, KEY_3)).block();
-
-            Mono.from(eventBus2().register(countingListener1, KEY_1)).block();
-            Mono.from(eventBus2().register(countingListener2, KEY_2)).block();
-            Mono.from(eventBus2().register(countingListener3, KEY_3)).block();
-
-            int totalKeyListenerRegistrations = 3; // KEY1 + KEY2 + KEY3
-            int totalEventBus = 2; // eventBus1 + eventBus2
-
-            ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, ALL_KEYS).block())
-                .threadCount(THREAD_COUNT)
-                .operationCount(OPERATION_COUNT)
-                .runSuccessfullyWithin(FIVE_SECONDS);
-
-            AWAIT_CONDITION.untilAsserted(() ->
-                assertThat(totalEventsReceived(ImmutableList.of(countingListener1, countingListener2, countingListener3)))
-                    .isEqualTo(totalKeyListenerRegistrations * totalEventBus * TOTAL_DISPATCH_OPERATIONS));
-        }
-
-        @Test
-        default void concurrentDispatchShouldDeliverAllEventsToListenersWithMultipleEventBus() throws Exception {
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
-
-            eventBus2().register(countingListener1, GROUP_A);
-            eventBus2().register(countingListener2, new EventBusTestFixture.GroupB());
-            eventBus2().register(countingListener3, new EventBusTestFixture.GroupC());
-            int totalGlobalRegistrations = 3; // GroupA + GroupB + GroupC
-            int totalEventDeliveredGlobally = totalGlobalRegistrations * TOTAL_DISPATCH_OPERATIONS;
-
-            Mono.from(eventBus().register(countingListener1, KEY_1)).block();
-            Mono.from(eventBus().register(countingListener2, KEY_2)).block();
-
-            Mono.from(eventBus2().register(countingListener1, KEY_1)).block();
-            Mono.from(eventBus2().register(countingListener2, KEY_2)).block();
-
-            Mono.from(eventBus3().register(countingListener3, KEY_1)).block();
-            Mono.from(eventBus3().register(countingListener3, KEY_2)).block();
-
-            int totalKeyListenerRegistrations = 2; // KEY1 + KEY2
-            int totalEventBus = 3; // eventBus1 + eventBus2 + eventBus3
-            int totalEventDeliveredByKeys = totalKeyListenerRegistrations * totalEventBus * TOTAL_DISPATCH_OPERATIONS;
-
-            ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, ALL_KEYS).block())
-                .threadCount(THREAD_COUNT)
-                .operationCount(OPERATION_COUNT)
-                .runSuccessfullyWithin(FIVE_SECONDS);
-
-            AWAIT_CONDITION.untilAsserted(() ->
-                assertThat(totalEventsReceived(ImmutableList.of(countingListener1, countingListener2, countingListener3)))
-                    .isEqualTo(totalEventDeliveredGlobally + totalEventDeliveredByKeys));
-        }
-    }
-}
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusContract.java
deleted file mode 100644
index c94c5a3..0000000
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusContract.java
+++ /dev/null
@@ -1,73 +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.mailbox.events;
-
-import static org.awaitility.Awaitility.await;
-
-import java.time.Duration;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.james.events.EventBus;
-import org.awaitility.core.ConditionFactory;
-
-public interface EventBusContract {
-
-    enum EnvironmentSpeedProfile {
-        SLOW(Duration.ofSeconds(2), Duration.ofSeconds(10)),
-        FAST(Duration.ofMillis(200), Duration.ofSeconds(5));
-
-        private final Duration shortWaitTime;
-        private final Duration longWaitTime;
-
-        EnvironmentSpeedProfile(Duration shortWaitTime, Duration longWaitTime) {
-            this.shortWaitTime = shortWaitTime;
-            this.longWaitTime = longWaitTime;
-        }
-
-        public Duration getShortWaitTime() {
-            return shortWaitTime;
-        }
-
-        public Duration getLongWaitTime() {
-            return longWaitTime;
-        }
-
-        public ConditionFactory shortWaitCondition() {
-            return await().pollDelay(org.awaitility.Duration.ZERO)
-                .pollInterval(org.awaitility.Duration.ONE_HUNDRED_MILLISECONDS)
-                .timeout(new org.awaitility.Duration(this.getShortWaitTime().toMillis(), TimeUnit.MILLISECONDS));
-        }
-
-        public ConditionFactory longWaitCondition() {
-            return await().pollDelay(org.awaitility.Duration.ZERO)
-                .pollInterval(org.awaitility.Duration.ONE_HUNDRED_MILLISECONDS)
-                .timeout(new org.awaitility.Duration(this.getLongWaitTime().toMillis(), TimeUnit.MILLISECONDS));
-        }
-    }
-
-    EnvironmentSpeedProfile getSpeedProfile();
-
-    interface MultipleEventBusContract extends EventBusContract {
-
-        EventBus eventBus2();
-    }
-
-    EventBus eventBus();
-}
\ No newline at end of file
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusTestFixture.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusTestFixture.java
deleted file mode 100644
index dccec61..0000000
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusTestFixture.java
+++ /dev/null
@@ -1,145 +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.mailbox.events;
-
-import static org.apache.james.mailbox.events.RetryBackoffConfiguration.DEFAULT_JITTER_FACTOR;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.james.core.Username;
-import org.apache.james.events.Event;
-import org.apache.james.events.EventListener;
-import org.apache.james.events.Group;
-import org.apache.james.events.RegistrationKey;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxEvent;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxRenamed;
-import org.apache.james.mailbox.model.MailboxConstants;
-import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.TestId;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-public interface EventBusTestFixture {
-
-    class EventListenerCountingSuccessfulExecution implements EventListener {
-        private final AtomicInteger calls = new AtomicInteger(0);
-
-        @Override
-        public boolean isHandling(Event event) {
-            return true;
-        }
-
-        @Override
-        public void event(Event event) {
-            calls.incrementAndGet();
-        }
-
-        public int numberOfEventCalls() {
-            return calls.get();
-        }
-    }
-
-    class EventMatcherThrowingListener extends EventListenerCountingSuccessfulExecution {
-        private final ImmutableSet<Event> eventsCauseThrowing;
-
-        EventMatcherThrowingListener(ImmutableSet<Event> eventsCauseThrowing) {
-            this.eventsCauseThrowing = eventsCauseThrowing;
-        }
-
-        @Override
-        public boolean isHandling(Event event) {
-            return true;
-        }
-
-        @Override
-        public void event(Event event) {
-            if (eventsCauseThrowing.contains(event)) {
-                throw new RuntimeException("event triggers throwing");
-            }
-            super.event(event);
-        }
-    }
-
-    class GroupA extends Group {
-
-    }
-
-    class GroupB extends Group {
-
-    }
-
-    class GroupC extends Group {
-
-    }
-
-    MailboxSession.SessionId SESSION_ID = MailboxSession.SessionId.of(42);
-    Username USERNAME = Username.of("user");
-    MailboxPath MAILBOX_PATH = new MailboxPath(MailboxConstants.USER_NAMESPACE, USERNAME, "mailboxName");
-    TestId TEST_ID = TestId.of(18);
-    Event.EventId EVENT_ID = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
-    Event.EventId EVENT_ID_2 = Event.EventId.of("5a7a9f3f-5f03-44be-b457-a51e93760645");
-    MailboxEvent EVENT = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, EVENT_ID);
-    MailboxEvent EVENT_2 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, EVENT_ID_2);
-    MailboxRenamed EVENT_UNSUPPORTED_BY_LISTENER = new MailboxRenamed(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, MAILBOX_PATH, EVENT_ID_2);
-
-    java.time.Duration ONE_SECOND = java.time.Duration.ofSeconds(1);
-    java.time.Duration FIVE_HUNDRED_MS = java.time.Duration.ofMillis(500);
-    MailboxId ID_1 = TEST_ID;
-    MailboxId ID_2 = TestId.of(24);
-    MailboxId ID_3 = TestId.of(36);
-    ImmutableSet<RegistrationKey> NO_KEYS = ImmutableSet.of();
-    MailboxIdRegistrationKey KEY_1 = new MailboxIdRegistrationKey(ID_1);
-    MailboxIdRegistrationKey KEY_2 = new MailboxIdRegistrationKey(ID_2);
-    MailboxIdRegistrationKey KEY_3 = new MailboxIdRegistrationKey(ID_3);
-    GroupA GROUP_A = new GroupA();
-    GroupB GROUP_B = new GroupB();
-    GroupC GROUP_C = new GroupC();
-    List<Group> ALL_GROUPS = ImmutableList.of(GROUP_A, GROUP_B, GROUP_C);
-
-    java.time.Duration DEFAULT_FIRST_BACKOFF = java.time.Duration.ofMillis(5);
-    //Retry backoff configuration for testing with a shorter first backoff to accommodate the shorter retry interval in tests
-    RetryBackoffConfiguration RETRY_BACKOFF_CONFIGURATION = RetryBackoffConfiguration.builder()
-        .maxRetries(3)
-        .firstBackoff(DEFAULT_FIRST_BACKOFF)
-        .jitterFactor(DEFAULT_JITTER_FACTOR)
-        .build();
-
-    static EventListener newListener() {
-        EventListener listener = mock(EventListener.class);
-        when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
-        when(listener.isHandling(any(MailboxAdded.class))).thenReturn(true);
-        return listener;
-    }
-
-    static EventListener newAsyncListener() {
-        EventListener listener = mock(EventListener.class);
-        when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
-        when(listener.isHandling(any(MailboxAdded.class))).thenReturn(true);
-        return listener;
-    }
-}
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersContract.java
deleted file mode 100644
index 1e8f003..0000000
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersContract.java
+++ /dev/null
@@ -1,493 +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.mailbox.events;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import java.time.Duration;
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Function;
-import java.util.stream.IntStream;
-import java.util.stream.Stream;
-
-import org.apache.james.core.Username;
-import org.apache.james.events.Event;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.events.Group;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
-import org.apache.james.mailbox.model.MailboxConstants;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.util.concurrency.ConcurrentTestRunner;
-import org.junit.jupiter.api.Test;
-
-import com.github.steveash.guavate.Guavate;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multimaps;
-
-interface EventDeadLettersContract {
-
-    class Group0 extends Group {
-
-    }
-
-    class Group1 extends Group {
-
-    }
-
-    class Group2 extends Group {
-
-    }
-
-    class Group3 extends Group {
-
-    }
-
-    class Group4 extends Group {
-
-    }
-
-    class Group5 extends Group {
-
-    }
-
-    class Group6 extends Group {
-
-    }
-
-    class Group7 extends Group {
-
-    }
-
-    class Group8 extends Group {
-
-    }
-
-    class Group9 extends Group {
-
-    }
-
-    static ImmutableMap<Integer, Group> concurrentGroups() {
-        return IntStream.range(0, CONCURRENT_GROUPS.size()).boxed()
-            .collect(Guavate.toImmutableMap(Function.identity(), CONCURRENT_GROUPS::get));
-    }
-
-    static Event event(Event.EventId eventId) {
-        return new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, eventId);
-    }
-
-    List<Group> CONCURRENT_GROUPS = ImmutableList.of(new Group0(), new Group1(), new Group2(), new Group3(), new Group4(), new Group5(),
-        new Group6(), new Group7(), new Group8(), new Group9());
-    Duration RUN_SUCCESSFULLY_IN = Duration.ofSeconds(5);
-    int THREAD_COUNT = 10;
-    int OPERATION_COUNT = 50;
-
-    Username USERNAME = Username.of("user");
-    MailboxPath MAILBOX_PATH = new MailboxPath(MailboxConstants.USER_NAMESPACE, USERNAME, "mailboxName");
-    MailboxSession.SessionId SESSION_ID = MailboxSession.SessionId.of(235);
-    TestId MAILBOX_ID = TestId.of(563);
-    Event.EventId EVENT_ID_1 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
-    Event.EventId EVENT_ID_2 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b5");
-    Event.EventId EVENT_ID_3 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b6");
-    MailboxAdded EVENT_1 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_1);
-    MailboxAdded EVENT_2 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_2);
-    MailboxAdded EVENT_3 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_3);
-    EventDeadLetters.InsertionId INSERTION_ID_1 = EventDeadLetters.InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b7");
-    EventDeadLetters.InsertionId INSERTION_ID_2 = EventDeadLetters.InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b8");
-    EventDeadLetters.InsertionId INSERTION_ID_3 = EventDeadLetters.InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b9");
-
-    Group GROUP_A = new EventBusTestFixture.GroupA();
-    Group GROUP_B = new EventBusTestFixture.GroupB();
-    Group NULL_GROUP = null;
-    Event NULL_EVENT = null;
-    EventDeadLetters.InsertionId NULL_INSERTION_ID = null;
-
-    EventDeadLetters eventDeadLetters();
-
-    default Stream<EventDeadLetters.InsertionId> allInsertionIds() {
-        EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-        return eventDeadLetters.groupsWithFailedEvents()
-            .flatMap(eventDeadLetters::failedIds)
-            .toStream();
-    }
-
-    interface StoreContract extends EventDeadLettersContract {
-
-        @Test
-        default void storeShouldThrowWhenNullGroup() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            assertThatThrownBy(() -> eventDeadLetters.store(NULL_GROUP, EVENT_1))
-                .isInstanceOf(IllegalArgumentException.class);
-        }
-
-        @Test
-        default void storeShouldThrowWhenNullEvent() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            assertThatThrownBy(() -> eventDeadLetters.store(GROUP_A, NULL_EVENT))
-                .isInstanceOf(IllegalArgumentException.class);
-        }
-
-        @Test
-        default void storeShouldThrowWhenBothGroupAndEventAndInsertionIdAreNull() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            assertThatThrownBy(() -> eventDeadLetters.store(NULL_GROUP, NULL_EVENT))
-                .isInstanceOf(IllegalArgumentException.class);
-        }
-
-        @Test
-        default void storeShouldStoreGroupWithCorrespondingEvent() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            EventDeadLetters.InsertionId insertionId = eventDeadLetters.store(GROUP_A, EVENT_1).block();
-            assertThat(eventDeadLetters.failedEvent(GROUP_A, insertionId).block())
-                .isEqualTo(EVENT_1);
-        }
-
-        @Test
-        default void storeShouldKeepConsistencyWhenConcurrentStore() throws Exception {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            ImmutableMap<Integer, Group> groups = concurrentGroups();
-            Multimap<Integer, EventDeadLetters.InsertionId> storedInsertionIds = Multimaps.synchronizedSetMultimap(HashMultimap.create());
-
-            ConcurrentTestRunner.builder()
-                .operation((threadNumber, step) -> {
-                    Event.EventId eventId = Event.EventId.random();
-                    EventDeadLetters.InsertionId insertionId = eventDeadLetters.store(groups.get(threadNumber), event(eventId)).block();
-                    storedInsertionIds.put(threadNumber, insertionId);
-                })
-                .threadCount(THREAD_COUNT)
-                .operationCount(OPERATION_COUNT)
-                .runSuccessfullyWithin(RUN_SUCCESSFULLY_IN);
-
-            groups.forEach((groupId, group) -> {
-                Group storedGroup = groups.get(groupId);
-                assertThat(eventDeadLetters.failedIds(storedGroup).collectList().block())
-                    .hasSameElementsAs(storedInsertionIds.get(groupId));
-            });
-        }
-    }
-
-    interface RemoveContract extends EventDeadLettersContract {
-
-        @Test
-        default void removeShouldThrowWhenGroupIsNull() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            assertThatThrownBy(() -> eventDeadLetters.remove(NULL_GROUP, INSERTION_ID_1))
-                .isInstanceOf(IllegalArgumentException.class);
-        }
-
-        @Test
-        default void removeShouldThrowWhenInsertionIdIsNull() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            assertThatThrownBy(() -> eventDeadLetters.remove(GROUP_A, NULL_INSERTION_ID))
-                .isInstanceOf(IllegalArgumentException.class);
-        }
-
-        @Test
-        default void removeShouldThrowWhenBothGroupAndInsertionIdAreNull() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            assertThatThrownBy(() -> eventDeadLetters.remove(NULL_GROUP, NULL_INSERTION_ID))
-                .isInstanceOf(IllegalArgumentException.class);
-        }
-
-        @Test
-        default void removeShouldRemoveMatched() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            eventDeadLetters.store(GROUP_A, EVENT_1).block();
-            eventDeadLetters.store(GROUP_A, EVENT_2).block();
-
-            eventDeadLetters.remove(GROUP_A, INSERTION_ID_1).block();
-
-            assertThat(eventDeadLetters.failedEvent(GROUP_A, INSERTION_ID_1).block())
-                .isNull();
-        }
-
-        @Test
-        default void removeShouldKeepNonMatched() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            EventDeadLetters.InsertionId insertionId1 = eventDeadLetters.store(GROUP_A, EVENT_1).block();
-            EventDeadLetters.InsertionId insertionId2 = eventDeadLetters.store(GROUP_A, EVENT_2).block();
-            EventDeadLetters.InsertionId insertionId3 = eventDeadLetters.store(GROUP_A, EVENT_3).block();
-
-            eventDeadLetters.remove(GROUP_A, insertionId1).block();
-
-            assertThat(eventDeadLetters.failedIds(GROUP_A).toStream())
-                .containsOnly(insertionId2, insertionId3);
-        }
-
-        @Test
-        default void removeShouldNotThrowWhenNoInsertionIdMatched() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            eventDeadLetters.store(GROUP_A, EVENT_1).block();
-
-            assertThatCode(() -> eventDeadLetters.remove(GROUP_A, INSERTION_ID_2).block())
-                .doesNotThrowAnyException();
-        }
-
-        @Test
-        default void removeShouldNotThrowWhenNoGroupMatched() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            eventDeadLetters.store(GROUP_A, EVENT_1).block();
-
-            assertThatCode(() -> eventDeadLetters.remove(GROUP_B, INSERTION_ID_1).block())
-                .doesNotThrowAnyException();
-        }
-
-        @Test
-        default void removeShouldKeepConsistencyWhenConcurrentRemove() throws Exception {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            ImmutableMap<Integer, Group> groups = concurrentGroups();
-            ConcurrentHashMap<Integer, EventDeadLetters.InsertionId> storedInsertionIds = new ConcurrentHashMap<>();
-
-            ConcurrentTestRunner.builder()
-                .operation((threadNumber, step) -> {
-                    int operationIndex = threadNumber * OPERATION_COUNT + step;
-                    Event.EventId eventId = Event.EventId.random();
-                    EventDeadLetters.InsertionId insertionId = eventDeadLetters.store(groups.get(threadNumber), event(eventId)).block();
-                    storedInsertionIds.put(operationIndex, insertionId);
-                })
-                .threadCount(THREAD_COUNT)
-                .operationCount(OPERATION_COUNT)
-                .runSuccessfullyWithin(RUN_SUCCESSFULLY_IN);
-
-            ConcurrentTestRunner.builder()
-                .operation((threadNumber, step) -> {
-                    int operationIndex = threadNumber * OPERATION_COUNT + step;
-                    eventDeadLetters.remove(groups.get(threadNumber), storedInsertionIds.get(operationIndex))
-                        .block();
-                })
-                .threadCount(THREAD_COUNT)
-                .operationCount(OPERATION_COUNT)
-                .runSuccessfullyWithin(RUN_SUCCESSFULLY_IN);
-
-            assertThat(allInsertionIds())
-                .isEmpty();
-        }
-    }
-
-    interface FailedEventContract extends EventDeadLettersContract {
-
-        @Test
-        default void failedEventShouldThrowWhenGroupIsNull() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            assertThatThrownBy(() -> eventDeadLetters.failedEvent(NULL_GROUP, INSERTION_ID_1))
-                .isInstanceOf(IllegalArgumentException.class);
-        }
-
-        @Test
-        default void failedEventShouldThrowWhenInsertionIdIsNull() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            assertThatThrownBy(() -> eventDeadLetters.failedEvent(GROUP_A, NULL_INSERTION_ID))
-                .isInstanceOf(IllegalArgumentException.class);
-        }
-
-        @Test
-        default void failedEventShouldThrowWhenBothGroupAndInsertionIdAreNull() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            assertThatThrownBy(() -> eventDeadLetters.failedEvent(NULL_GROUP, NULL_INSERTION_ID))
-                .isInstanceOf(IllegalArgumentException.class);
-        }
-
-        @Test
-        default void failedEventShouldReturnEmptyWhenNotFound() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            eventDeadLetters.store(GROUP_A, EVENT_1).block();
-            eventDeadLetters.store(GROUP_A, EVENT_2).block();
-
-            assertThat(eventDeadLetters.failedEvent(GROUP_A, INSERTION_ID_3).block())
-                .isNull();
-        }
-
-        @Test
-        default void failedEventShouldReturnEventWhenContains() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            EventDeadLetters.InsertionId insertionId = eventDeadLetters.store(GROUP_A, EVENT_1).block();
-            eventDeadLetters.store(GROUP_A, EVENT_2).block();
-
-            assertThat(eventDeadLetters.failedEvent(GROUP_A, insertionId).block())
-                .isEqualTo(EVENT_1);
-        }
-
-        @Test
-        default void failedEventShouldNotRemoveEvent() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            EventDeadLetters.InsertionId insertionId1 = eventDeadLetters.store(GROUP_A, EVENT_1).block();
-            EventDeadLetters.InsertionId insertionId2 = eventDeadLetters.store(GROUP_A, EVENT_2).block();
-            EventDeadLetters.InsertionId insertionId3 = eventDeadLetters.store(GROUP_A, EVENT_3).block();
-
-            eventDeadLetters.failedEvent(GROUP_A, insertionId1).block();
-
-            assertThat(allInsertionIds())
-                .containsOnly(insertionId1, insertionId2, insertionId3);
-        }
-
-        @Test
-        default void failedEventShouldNotThrowWhenNoGroupMatched() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            EventDeadLetters.InsertionId insertionId = eventDeadLetters.store(GROUP_A, EVENT_1).block();
-
-            assertThatCode(() -> eventDeadLetters.failedEvent(GROUP_B, insertionId).block())
-                .doesNotThrowAnyException();
-        }
-    }
-
-    interface FailedEventsContract extends EventDeadLettersContract {
-
-        @Test
-        default void failedEventsShouldThrowWhenGroupIsNull() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            assertThatThrownBy(() -> eventDeadLetters.failedIds(NULL_GROUP))
-                .isInstanceOf(IllegalArgumentException.class);
-        }
-
-        @Test
-        default void failedEventsByGroupShouldReturnEmptyWhenNonMatch() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            eventDeadLetters.store(GROUP_A, EVENT_1).block();
-            eventDeadLetters.store(GROUP_A, EVENT_2).block();
-            eventDeadLetters.store(GROUP_A, EVENT_3).block();
-
-            assertThat(eventDeadLetters.failedIds(GROUP_B).toStream())
-                .isEmpty();
-        }
-
-        @Test
-        default void failedEventsByGroupShouldReturnAllEventsCorrespondingToGivenGroup() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            EventDeadLetters.InsertionId insertionId = eventDeadLetters.store(GROUP_A, EVENT_1).block();
-            eventDeadLetters.store(GROUP_B, EVENT_2).block();
-            eventDeadLetters.store(GROUP_B, EVENT_3).block();
-
-            assertThat(eventDeadLetters.failedIds(GROUP_A).toStream())
-                .containsOnly(insertionId);
-        }
-
-        @Test
-        default void failedEventsByGroupShouldNotRemoveEvents() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            EventDeadLetters.InsertionId insertionId1 = eventDeadLetters.store(GROUP_A, EVENT_1).block();
-            EventDeadLetters.InsertionId insertionId2 = eventDeadLetters.store(GROUP_A, EVENT_2).block();
-            EventDeadLetters.InsertionId insertionId3 = eventDeadLetters.store(GROUP_B, EVENT_3).block();
-
-            eventDeadLetters.failedIds(GROUP_A).toStream();
-
-            assertThat(allInsertionIds())
-                .containsOnly(insertionId1, insertionId2, insertionId3);
-        }
-    }
-
-    interface GroupsWithFailedEventsContract extends EventDeadLettersContract {
-        @Test
-        default void groupsWithFailedEventsShouldReturnAllStoredGroups() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-            eventDeadLetters.store(GROUP_A, EVENT_1).block();
-            eventDeadLetters.store(GROUP_B, EVENT_1).block();
-
-            assertThat(eventDeadLetters.groupsWithFailedEvents().collectList().block())
-                .containsOnly(GROUP_A, GROUP_B);
-        }
-
-        @Test
-        default void groupsWithFailedEventsShouldReturnEmptyWhenNoStored() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            assertThat(eventDeadLetters.groupsWithFailedEvents().toStream()).isEmpty();
-        }
-    }
-
-    interface ContainEventsContract extends EventDeadLettersContract {
-        @Test
-        default void containEventsShouldReturnFalseOnNothingStored() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-
-            assertThat(eventDeadLetters.containEvents().block()).isFalse();
-        }
-
-        @Test
-        default void containEventsShouldReturnTrueOnStoredEvents() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-            eventDeadLetters.store(GROUP_A, EVENT_1).block();
-
-            assertThat(eventDeadLetters.containEvents().block()).isTrue();
-        }
-
-        @Test
-        default void containEventsShouldReturnFalseWhenRemoveAllStoredEvents() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-            EventDeadLetters.InsertionId insertionId1 = eventDeadLetters().store(GROUP_A, EVENT_1).block();
-            EventDeadLetters.InsertionId insertionId2 = eventDeadLetters().store(GROUP_A, EVENT_2).block();
-
-            assertThat(eventDeadLetters.containEvents().block()).isTrue();
-
-            eventDeadLetters.remove(GROUP_A, insertionId1).block();
-            eventDeadLetters.remove(GROUP_A, insertionId2).block();
-
-            assertThat(eventDeadLetters.containEvents().block()).isFalse();
-        }
-
-        @Test
-        default void containEventsShouldReturnTrueWhenRemoveSomeStoredEvents() {
-            EventDeadLetters eventDeadLetters = eventDeadLetters();
-            EventDeadLetters.InsertionId insertionId1 = eventDeadLetters().store(GROUP_A, EVENT_1).block();
-            eventDeadLetters().store(GROUP_B, EVENT_2).block();
-
-            assertThat(eventDeadLetters.containEvents().block()).isTrue();
-
-            eventDeadLetters.remove(GROUP_A, insertionId1).block();
-
-            assertThat(eventDeadLetters.containEvents().block()).isTrue();
-        }
-    }
-
-    interface AllContracts extends StoreContract, RemoveContract, FailedEventContract, FailedEventsContract, GroupsWithFailedEventsContract, ContainEventsContract {
-
-    }
-}
\ No newline at end of file
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersHealthCheckContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersHealthCheckContract.java
deleted file mode 100644
index 4479714..0000000
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersHealthCheckContract.java
+++ /dev/null
@@ -1,134 +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.mailbox.events;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.apache.james.core.Username;
-import org.apache.james.core.healthcheck.ComponentName;
-import org.apache.james.core.healthcheck.Result;
-import org.apache.james.events.Event;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.events.EventDeadLettersHealthCheck;
-import org.apache.james.events.Group;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
-import org.apache.james.mailbox.model.MailboxConstants;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.TestId;
-import org.junit.jupiter.api.Test;
-
-interface EventDeadLettersHealthCheckContract {
-
-    ComponentName COMPONENT_NAME = new ComponentName("EventDeadLettersHealthCheck");
-    String EXPECTED_DEGRADED_MESSAGE = "EventDeadLetters contain events. This might indicate transient failure on mailbox event processing.";
-
-    Username USERNAME = Username.of("user");
-    MailboxPath MAILBOX_PATH = new MailboxPath(MailboxConstants.USER_NAMESPACE, USERNAME, "mailboxName");
-    MailboxSession.SessionId SESSION_ID = MailboxSession.SessionId.of(235);
-    TestId MAILBOX_ID = TestId.of(563);
-    Event.EventId EVENT_ID_1 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
-    Event.EventId EVENT_ID_2 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b5");
-    MailboxAdded EVENT_1 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_1);
-    MailboxAdded EVENT_2 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_2);
-
-    Group GROUP_A = new EventBusTestFixture.GroupA();
-    Group GROUP_B = new EventBusTestFixture.GroupB();
-
-    EventDeadLettersHealthCheck testee();
-
-    EventDeadLetters eventDeadLetters();
-
-    void createErrorWhenDoingHealthCheck();
-
-    void resolveErrorWhenDoingHealthCheck();
-
-    @Test
-    default void checkShouldReturnHealthyWhenEventDeadLetterEmpty() {
-        assertThat(testee().check().block().isHealthy()).isTrue();
-        assertThat(testee().check().block())
-            .isEqualTo(Result.healthy(COMPONENT_NAME));
-    }
-
-    @Test
-    default void checkShouldReturnDegradedWhenEventDeadLetterContainEvent() {
-        eventDeadLetters().store(GROUP_A, EVENT_1).block();
-
-        assertThat(testee().check().block().isDegraded()).isTrue();
-        assertThat(testee().check().block())
-            .isEqualTo(Result.degraded(COMPONENT_NAME, EXPECTED_DEGRADED_MESSAGE));
-    }
-
-    @Test
-    default void checkShouldReturnDegradedWhenEventDeadLetterContainEvents() {
-        eventDeadLetters().store(GROUP_A, EVENT_1).block();
-        eventDeadLetters().store(GROUP_B, EVENT_2).block();
-
-        assertThat(testee().check().block().isDegraded()).isTrue();
-        assertThat(testee().check().block())
-            .isEqualTo(Result.degraded(COMPONENT_NAME, EXPECTED_DEGRADED_MESSAGE));
-    }
-
-    @Test
-    default void checkShouldReturnHealthyWhenRemovedAllEventDeadLetters() {
-        EventDeadLetters.InsertionId insertionId1 = eventDeadLetters().store(GROUP_A, EVENT_1).block();
-        EventDeadLetters.InsertionId insertionId2 = eventDeadLetters().store(GROUP_B, EVENT_2).block();
-
-        assertThat(testee().check().block().isDegraded()).isTrue();
-        assertThat(testee().check().block())
-            .isEqualTo(Result.degraded(COMPONENT_NAME, EXPECTED_DEGRADED_MESSAGE));
-
-        eventDeadLetters().remove(GROUP_A, insertionId1).block();
-        eventDeadLetters().remove(GROUP_B, insertionId2).block();
-
-        assertThat(testee().check().block().isHealthy()).isTrue();
-        assertThat(testee().check().block())
-            .isEqualTo(Result.healthy(COMPONENT_NAME));
-    }
-
-    @Test
-    default void checkShouldReturnDegradedWhenRemovedSomeEventDeadLetters() {
-        EventDeadLetters.InsertionId insertionId1 = eventDeadLetters().store(GROUP_A, EVENT_1).block();
-        eventDeadLetters().store(GROUP_B, EVENT_2).block();
-
-        assertThat(testee().check().block().isDegraded()).isTrue();
-        assertThat(testee().check().block())
-            .isEqualTo(Result.degraded(COMPONENT_NAME, EXPECTED_DEGRADED_MESSAGE));
-
-        eventDeadLetters().remove(GROUP_A, insertionId1).block();
-
-        assertThat(testee().check().block().isDegraded()).isTrue();
-        assertThat(testee().check().block())
-            .isEqualTo(Result.degraded(COMPONENT_NAME, EXPECTED_DEGRADED_MESSAGE));
-    }
-
-    @Test
-    default void checkShouldReturnUnHealthyWhenEventDeadLetterError() {
-        Result actualResult;
-        try {
-            createErrorWhenDoingHealthCheck();
-            actualResult = testee().check().block();
-        } finally {
-            resolveErrorWhenDoingHealthCheck();
-        }
-
-        assertThat(actualResult.isUnHealthy()).isTrue();
-    }
-}
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupContract.java
deleted file mode 100644
index fb5131d..0000000
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupContract.java
+++ /dev/null
@@ -1,504 +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.mailbox.events;
-
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT;
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT_2;
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT_ID;
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT_UNSUPPORTED_BY_LISTENER;
-import static org.apache.james.mailbox.events.EventBusTestFixture.FIVE_HUNDRED_MS;
-import static org.apache.james.mailbox.events.EventBusTestFixture.GROUP_A;
-import static org.apache.james.mailbox.events.EventBusTestFixture.GROUP_B;
-import static org.apache.james.mailbox.events.EventBusTestFixture.GROUP_C;
-import static org.apache.james.mailbox.events.EventBusTestFixture.NO_KEYS;
-import static org.apache.james.mailbox.events.EventBusTestFixture.ONE_SECOND;
-import static org.apache.james.mailbox.events.EventBusTestFixture.newListener;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.after;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.time.Duration;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.IntStream;
-
-import org.apache.james.core.Username;
-import org.apache.james.events.Event;
-import org.apache.james.events.EventBus;
-import org.apache.james.events.EventListener;
-import org.apache.james.events.GenericGroup;
-import org.apache.james.events.Group;
-import org.apache.james.events.GroupAlreadyRegistered;
-import org.apache.james.events.GroupRegistrationNotFound;
-import org.apache.james.events.Registration;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.events.MailboxEvents.Added;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.TestId;
-import org.junit.jupiter.api.Test;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedMap;
-
-import reactor.core.scheduler.Schedulers;
-
-public interface GroupContract {
-
-    interface SingleEventBusGroupContract extends EventBusContract {
-
-        @Test
-        default void groupDeliveryShouldNotExceedRate() {
-            int eventCount = 50;
-            AtomicInteger nbCalls = new AtomicInteger(0);
-            AtomicInteger finishedExecutions = new AtomicInteger(0);
-            AtomicBoolean rateExceeded = new AtomicBoolean(false);
-
-            eventBus().register(new EventListener.GroupEventListener() {
-                @Override
-                public Group getDefaultGroup() {
-                    return new GenericGroup("group");
-                }
-
-                @Override
-                public boolean isHandling(Event event) {
-                    return true;
-                }
-
-                @Override
-                public void event(Event event) throws Exception {
-                    if (nbCalls.get() - finishedExecutions.get() > EventBus.EXECUTION_RATE) {
-                        rateExceeded.set(true);
-                    }
-                    nbCalls.incrementAndGet();
-                    Thread.sleep(Duration.ofMillis(20).toMillis());
-                    finishedExecutions.incrementAndGet();
-
-                }
-            }, GROUP_A);
-
-            IntStream.range(0, eventCount)
-                .forEach(i -> eventBus().dispatch(EVENT, NO_KEYS).block());
-
-            getSpeedProfile().shortWaitCondition().atMost(org.awaitility.Duration.TEN_MINUTES)
-                .untilAsserted(() -> assertThat(finishedExecutions.get()).isEqualTo(eventCount));
-            assertThat(rateExceeded).isFalse();
-        }
-
-        @Test
-        default void groupNotificationShouldDeliverASingleEventToAllListenersAtTheSameTime() {
-            CountDownLatch countDownLatch = new CountDownLatch(1);
-            try {
-                ConcurrentLinkedQueue<String> threads = new ConcurrentLinkedQueue<>();
-                eventBus().register(new EventListener.GroupEventListener() {
-                    @Override
-                    public Group getDefaultGroup() {
-                        return new GenericGroup("groupA");
-                    }
-
-                    @Override
-                    public void event(Event event) throws Exception {
-                        threads.add(Thread.currentThread().getName());
-                        countDownLatch.await();
-                    }
-                }, GROUP_A);
-                eventBus().register(new EventListener.GroupEventListener() {
-                    @Override
-                    public Group getDefaultGroup() {
-                        return new GenericGroup("groupB");
-                    }
-
-                    @Override
-                    public void event(Event event) throws Exception {
-                        threads.add(Thread.currentThread().getName());
-                        countDownLatch.await();
-                    }
-                }, GROUP_B);
-                eventBus().register(new EventListener.GroupEventListener() {
-                    @Override
-                    public Group getDefaultGroup() {
-                        return new GenericGroup("groupC");
-                    }
-
-                    @Override
-                    public void event(Event event) throws Exception {
-                        threads.add(Thread.currentThread().getName());
-                        countDownLatch.await();
-                    }
-                }, GROUP_C);
-
-                eventBus().dispatch(EVENT, NO_KEYS).subscribeOn(Schedulers.elastic()).subscribe();
-
-
-                getSpeedProfile().shortWaitCondition().atMost(org.awaitility.Duration.TEN_SECONDS)
-                    .untilAsserted(() -> assertThat(threads).hasSize(3));
-                assertThat(threads).doesNotHaveDuplicates();
-            } finally {
-                countDownLatch.countDown();
-            }
-        }
-
-        @Test
-        default void listenersShouldBeAbleToDispatch() {
-            AtomicBoolean successfulRetry = new AtomicBoolean(false);
-            EventListener listener = event -> {
-                if (event.getEventId().equals(EVENT_ID)) {
-                    eventBus().dispatch(EVENT_2, NO_KEYS)
-                        .subscribeOn(Schedulers.elastic())
-                        .block();
-                    successfulRetry.set(true);
-                }
-            };
-
-            eventBus().register(listener, GROUP_A);
-            eventBus().dispatch(EVENT, NO_KEYS).block();
-
-            getSpeedProfile().shortWaitCondition().until(successfulRetry::get);
-        }
-
-        @Test
-        default void registerShouldNotDispatchPastEventsForGroups() throws Exception {
-            EventListener listener = newListener();
-
-            eventBus().dispatch(EVENT, NO_KEYS).block();
-
-            eventBus().register(listener, GROUP_A);
-
-            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
-                .event(any());
-        }
-
-        @Test
-        default void listenerGroupShouldReceiveEvents() throws Exception {
-            EventListener listener = newListener();
-
-            eventBus().register(listener, GROUP_A);
-
-            eventBus().dispatch(EVENT, NO_KEYS).block();
-
-            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void groupListenersShouldNotReceiveNoopEvents() throws Exception {
-            EventListener listener = newListener();
-
-            eventBus().register(listener, GROUP_A);
-
-            Username bob = Username.of("bob");
-            Added noopEvent = new Added(MailboxSession.SessionId.of(18), bob, MailboxPath.forUser(bob, "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
-            eventBus().dispatch(noopEvent, NO_KEYS).block();
-
-            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
-                .event(any());
-        }
-
-        @Test
-        default void groupListenersShouldReceiveOnlyHandledEvents() throws Exception {
-            EventListener listener = newListener();
-
-            eventBus().register(listener, GROUP_A);
-
-            eventBus().dispatch(EVENT_UNSUPPORTED_BY_LISTENER, NO_KEYS).block();
-
-            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
-                .event(any());
-        }
-
-        @Test
-        default void dispatchShouldNotThrowWhenAGroupListenerFails() throws Exception {
-            EventListener listener = newListener();
-            doThrow(new RuntimeException()).when(listener).event(any());
-
-            eventBus().register(listener, GROUP_A);
-
-            assertThatCode(() -> eventBus().dispatch(EVENT, NO_KEYS).block())
-                .doesNotThrowAnyException();
-        }
-
-        @Test
-        default void eachListenerGroupShouldReceiveEvents() throws Exception {
-            EventListener listener = newListener();
-            EventListener listener2 = newListener();
-            eventBus().register(listener, GROUP_A);
-            eventBus().register(listener2, GROUP_B);
-
-            eventBus().dispatch(EVENT, NO_KEYS).block();
-
-            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-            verify(listener2, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void unregisteredGroupListenerShouldNotReceiveEvents() throws Exception {
-            EventListener listener = newListener();
-            Registration registration = eventBus().register(listener, GROUP_A);
-
-            registration.unregister();
-
-            eventBus().dispatch(EVENT, NO_KEYS).block();
-            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
-                .event(any());
-        }
-
-        @Test
-        default void registerShouldThrowWhenAGroupIsAlreadyUsed() {
-            EventListener listener = newListener();
-            EventListener listener2 = newListener();
-
-            eventBus().register(listener, GROUP_A);
-
-            assertThatThrownBy(() -> eventBus().register(listener2, GROUP_A))
-                .isInstanceOf(GroupAlreadyRegistered.class);
-        }
-
-        @Test
-        default void registerShouldNotThrowOnAnUnregisteredGroup() {
-            EventListener listener = newListener();
-            EventListener listener2 = newListener();
-
-            eventBus().register(listener, GROUP_A).unregister();
-
-            assertThatCode(() -> eventBus().register(listener2, GROUP_A))
-                .doesNotThrowAnyException();
-        }
-
-        @Test
-        default void unregisterShouldBeIdempotentForGroups() {
-            EventListener listener = newListener();
-
-            Registration registration = eventBus().register(listener, GROUP_A);
-            registration.unregister();
-
-            assertThatCode(registration::unregister)
-                .doesNotThrowAnyException();
-        }
-
-        @Test
-        default void registerShouldAcceptAlreadyUnregisteredGroups() throws Exception {
-            EventListener listener = newListener();
-
-            eventBus().register(listener, GROUP_A).unregister();
-            eventBus().register(listener, GROUP_A);
-
-            eventBus().dispatch(EVENT, NO_KEYS).block();
-
-            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void dispatchShouldCallSynchronousListener() throws Exception {
-            EventListener listener = newListener();
-
-            eventBus().register(listener, GROUP_A);
-
-            eventBus().dispatch(EVENT, NO_KEYS).block();
-
-            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void failingGroupListenersShouldNotAbortGroupDelivery() {
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution listener = new EventBusTestFixture.EventMatcherThrowingListener(ImmutableSet.of(EVENT));
-            eventBus().register(listener, GROUP_A);
-
-            eventBus().dispatch(EVENT, NO_KEYS).block();
-            eventBus().dispatch(EVENT_2, NO_KEYS).block();
-
-            getSpeedProfile().shortWaitCondition()
-                .untilAsserted(() -> assertThat(listener.numberOfEventCalls()).isEqualTo(1));
-        }
-
-        @Test
-        default void allGroupListenersShouldBeExecutedWhenAGroupListenerFails() throws Exception {
-            EventListener listener = newListener();
-
-            EventListener failingListener = mock(EventListener.class);
-            when(failingListener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
-            doThrow(new RuntimeException()).when(failingListener).event(any());
-
-            eventBus().register(failingListener, GROUP_A);
-            eventBus().register(listener, GROUP_B);
-
-            eventBus().dispatch(EVENT, NO_KEYS).block();
-
-            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void allGroupListenersShouldBeExecutedWhenGenericGroups() throws Exception {
-            EventListener listener1 = newListener();
-            EventListener listener2 = newListener();
-
-            eventBus().register(listener1, new GenericGroup("a"));
-            eventBus().register(listener2, new GenericGroup("b"));
-
-            eventBus().dispatch(EVENT, NO_KEYS).block();
-
-            verify(listener1, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-            verify(listener2, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void groupListenerShouldReceiveEventWhenRedeliver() throws Exception {
-            EventListener listener = newListener();
-
-            eventBus().register(listener, GROUP_A);
-
-            eventBus().reDeliver(GROUP_A, EVENT).block();
-
-            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void redeliverShouldNotThrowWhenAGroupListenerFails() throws Exception {
-            EventListener listener = newListener();
-            doThrow(new RuntimeException()).when(listener).event(any());
-
-            eventBus().register(listener, GROUP_A);
-
-            assertThatCode(() -> eventBus().reDeliver(GROUP_A, EVENT).block())
-                .doesNotThrowAnyException();
-        }
-
-        @Test
-        default void redeliverShouldThrowWhenGroupNotRegistered() {
-            assertThatThrownBy(() -> eventBus().reDeliver(GROUP_A, EVENT).block())
-                .isInstanceOf(GroupRegistrationNotFound.class);
-        }
-
-        @Test
-        default void redeliverShouldThrowAfterGroupIsUnregistered() {
-            EventListener listener = newListener();
-
-            eventBus().register(listener, GROUP_A).unregister();
-
-            assertThatThrownBy(() -> eventBus().reDeliver(GROUP_A, EVENT).block())
-                .isInstanceOf(GroupRegistrationNotFound.class);
-        }
-
-        @Test
-        default void redeliverShouldOnlySendEventToDefinedGroup() throws Exception {
-            EventListener listener = newListener();
-            EventListener listener2 = newListener();
-            eventBus().register(listener, GROUP_A);
-            eventBus().register(listener2, GROUP_B);
-
-            eventBus().reDeliver(GROUP_A, EVENT).block();
-
-            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-            verify(listener2, after(FIVE_HUNDRED_MS.toMillis()).never()).event(any());
-        }
-
-        @Test
-        default void groupListenersShouldNotReceiveNoopRedeliveredEvents() throws Exception {
-            EventListener listener = newListener();
-
-            eventBus().register(listener, GROUP_A);
-
-            Username bob = Username.of("bob");
-            Added noopEvent = new Added(MailboxSession.SessionId.of(18), bob, MailboxPath.forUser(bob, "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
-            eventBus().reDeliver(GROUP_A, noopEvent).block();
-
-            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never()).event(any());
-        }
-    }
-
-    interface MultipleEventBusGroupContract extends EventBusContract.MultipleEventBusContract {
-
-        @Test
-        default void groupsDefinedOnlyOnSomeNodesShouldBeNotifiedWhenDispatch() throws Exception {
-            EventListener mailboxListener = newListener();
-
-            eventBus().register(mailboxListener, GROUP_A);
-
-            eventBus2().dispatch(EVENT, NO_KEYS).block();
-
-            verify(mailboxListener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void groupsDefinedOnlyOnSomeNodesShouldNotBeNotifiedWhenRedeliver() {
-            EventListener mailboxListener = newListener();
-
-            eventBus().register(mailboxListener, GROUP_A);
-
-            assertThatThrownBy(() -> eventBus2().reDeliver(GROUP_A, EVENT).block())
-                .isInstanceOf(GroupRegistrationNotFound.class);
-        }
-
-        @Test
-        default void groupListenersShouldBeExecutedOnceWhenRedeliverInADistributedEnvironment() throws Exception {
-            EventListener mailboxListener = newListener();
-
-            eventBus().register(mailboxListener, GROUP_A);
-            eventBus2().register(mailboxListener, GROUP_A);
-
-            eventBus2().reDeliver(GROUP_A, EVENT).block();
-
-            verify(mailboxListener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void groupListenersShouldBeExecutedOnceInAControlledEnvironment() throws Exception {
-            EventListener mailboxListener = newListener();
-
-            eventBus().register(mailboxListener, GROUP_A);
-            eventBus2().register(mailboxListener, GROUP_A);
-
-            eventBus2().dispatch(EVENT, NO_KEYS).block();
-
-            verify(mailboxListener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void unregisterShouldStopNotificationForDistantGroups() throws Exception {
-            EventListener mailboxListener = newListener();
-
-            eventBus().register(mailboxListener, GROUP_A).unregister();
-
-            eventBus2().dispatch(EVENT, NO_KEYS).block();
-
-
-            verify(mailboxListener, after(FIVE_HUNDRED_MS.toMillis()).never())
-                .event(any());
-        }
-
-        @Test
-        default void registerShouldNotDispatchPastEventsForGroupsInADistributedContext() throws Exception {
-            EventListener listener = newListener();
-
-            eventBus().dispatch(EVENT, NO_KEYS).block();
-
-            eventBus2().register(listener, GROUP_A);
-
-            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
-                .event(any());
-        }
-    }
-}
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupTest.java
deleted file mode 100644
index 53176df..0000000
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupTest.java
+++ /dev/null
@@ -1,135 +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.mailbox.events;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import org.apache.james.events.GenericGroup;
-import org.apache.james.events.Group;
-import org.junit.jupiter.api.Test;
-
-import nl.jqno.equalsverifier.EqualsVerifier;
-
-class GroupTest {
-    static class GroupA extends Group {
-
-    }
-
-    static class GroupB extends Group {
-
-    }
-
-    static class GroupC extends GroupA {
-
-    }
-
-    @Test
-    void shouldMatchBeanContract() {
-        EqualsVerifier.forClass(Group.class)
-            .usingGetClass()
-            .verify();
-    }
-
-    @Test
-    void equalsShouldReturnTrueOnSameClass() {
-        assertThat(new GroupA()).isEqualTo(new GroupA());
-    }
-
-    @Test
-    void equalsShouldReturnFalseOnDifferentClass() {
-        assertThat(new GroupA()).isNotEqualTo(new GroupB());
-    }
-
-    @Test
-    void equalsShouldReturnFalseOnSubClass() {
-        assertThat(new GroupA()).isNotEqualTo(new GroupC());
-    }
-
-    @Test
-    void equalsShouldReturnFalseOnParentClass() {
-        assertThat(new GroupC()).isNotEqualTo(new GroupA());
-    }
-
-    @Test
-    void genericGroupShouldMatchBeanContract() {
-        EqualsVerifier.forClass(GenericGroup.class)
-            .withRedefinedSuperclass()
-            .verify();
-    }
-
-    @Test
-    void asStringShouldReturnFqdnByDefault() {
-        assertThat(new EventBusTestFixture.GroupA().asString()).isEqualTo("org.apache.james.mailbox.events.EventBusTestFixture$GroupA");
-    }
-
-    @Test
-    void asStringShouldReturnNameWhenGenericGroup() {
-        assertThat(new GenericGroup("abc").asString()).isEqualTo("org.apache.james.events.GenericGroup-abc");
-    }
-
-    @Test
-    void deserializeShouldReturnGroupWhenGenericGroup() throws Exception {
-        assertThat(Group.deserialize("org.apache.james.events.GenericGroup-abc"))
-            .isEqualTo(new GenericGroup("abc"));
-    }
-
-    @Test
-    void deserializeShouldReturnGroupWhenEmptyGenericGroup() throws Exception {
-        assertThat(Group.deserialize("org.apache.james.events.GenericGroup-"))
-            .isEqualTo(new GenericGroup(""));
-    }
-
-    @Test
-    void deserializeShouldReturnGroupWhenExtendsGroup() throws Exception {
-        assertThat(Group.deserialize("org.apache.james.mailbox.events.EventBusTestFixture$GroupA"))
-            .isEqualTo(new EventBusTestFixture.GroupA());
-    }
-
-    @Test
-    void deserializeShouldThrowWhenClassNotFound() {
-        assertThatThrownBy(() -> Group.deserialize("org.apache.james.mailbox.events.Noone"))
-            .isInstanceOf(Group.GroupDeserializationException.class);
-    }
-
-    @Test
-    void deserializeShouldThrowWhenNotAGroup() {
-        assertThatThrownBy(() -> Group.deserialize("java.lang.String"))
-            .isInstanceOf(Group.GroupDeserializationException.class);
-    }
-
-    @Test
-    void deserializeShouldThrowWhenConstructorArgumentsRequired() {
-        assertThatThrownBy(() -> Group.deserialize("org.apache.james.events.GenericGroup"))
-            .isInstanceOf(Group.GroupDeserializationException.class);
-    }
-
-    @Test
-    void deserializeShouldThrowWhenNull() {
-        assertThatThrownBy(() -> Group.deserialize(null))
-            .isInstanceOf(Group.GroupDeserializationException.class);
-    }
-
-    @Test
-    void deserializeShouldThrowWhenEmpty() {
-        assertThatThrownBy(() -> Group.deserialize(""))
-            .isInstanceOf(Group.GroupDeserializationException.class);
-    }
-}
\ No newline at end of file
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/InsertionIdTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/InsertionIdTest.java
deleted file mode 100644
index c951edd..0000000
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/InsertionIdTest.java
+++ /dev/null
@@ -1,57 +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.mailbox.events;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import java.util.UUID;
-
-import org.apache.james.events.EventDeadLetters;
-import org.junit.jupiter.api.Test;
-
-import nl.jqno.equalsverifier.EqualsVerifier;
-
-class InsertionIdTest {
-    private static final UUID UUID_1 = UUID.fromString("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
-
-    @Test
-    void eventIdShouldMatchBeanContract() {
-        EqualsVerifier.forClass(EventDeadLetters.InsertionId.class).verify();
-    }
-
-    @Test
-    void ofShouldDeserializeUUIDs() {
-        assertThat(EventDeadLetters.InsertionId.of(UUID_1.toString()))
-            .isEqualTo(EventDeadLetters.InsertionId.of(UUID_1));
-    }
-
-    @Test
-    void ofStringShouldThrowOnNullValue() {
-        assertThatThrownBy(() -> EventDeadLetters.InsertionId.of((String) null))
-            .isInstanceOf(NullPointerException.class);
-    }
-
-    @Test
-    void ofUuidShouldThrowOnNullValue() {
-        assertThatThrownBy(() -> EventDeadLetters.InsertionId.of((UUID) null))
-            .isInstanceOf(NullPointerException.class);
-    }
-}
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/KeyContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/KeyContract.java
deleted file mode 100644
index 4c22d4b..0000000
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/KeyContract.java
+++ /dev/null
@@ -1,458 +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.mailbox.events;
-
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT;
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT_2;
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT_UNSUPPORTED_BY_LISTENER;
-import static org.apache.james.mailbox.events.EventBusTestFixture.FIVE_HUNDRED_MS;
-import static org.apache.james.mailbox.events.EventBusTestFixture.KEY_1;
-import static org.apache.james.mailbox.events.EventBusTestFixture.KEY_2;
-import static org.apache.james.mailbox.events.EventBusTestFixture.NO_KEYS;
-import static org.apache.james.mailbox.events.EventBusTestFixture.ONE_SECOND;
-import static org.apache.james.mailbox.events.EventBusTestFixture.newListener;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.junit.jupiter.api.Assertions.assertTimeout;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.after;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.time.Duration;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.IntStream;
-
-import org.apache.james.core.Username;
-import org.apache.james.events.Event;
-import org.apache.james.events.EventBus;
-import org.apache.james.events.EventListener;
-import org.apache.james.events.Registration;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.events.MailboxEvents.Added;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.TestId;
-import org.junit.jupiter.api.Test;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedMap;
-
-import reactor.core.publisher.Mono;
-import reactor.core.scheduler.Schedulers;
-
-public interface KeyContract extends EventBusContract {
-
-    interface SingleEventBusKeyContract extends EventBusContract {
-        @Test
-        default void notificationShouldNotExceedRate() {
-            int eventCount = 50;
-            AtomicInteger nbCalls = new AtomicInteger(0);
-            AtomicInteger finishedExecutions = new AtomicInteger(0);
-            AtomicBoolean rateExceeded = new AtomicBoolean(false);
-
-            Mono.from(eventBus().register(event -> {
-                if (nbCalls.get() - finishedExecutions.get() > EventBus.EXECUTION_RATE) {
-                    rateExceeded.set(true);
-                }
-                nbCalls.incrementAndGet();
-                Thread.sleep(Duration.ofMillis(20).toMillis());
-                finishedExecutions.incrementAndGet();
-
-            }, KEY_1)).block();
-
-            IntStream.range(0, eventCount)
-                .forEach(i -> eventBus().dispatch(EVENT, KEY_1).block());
-
-            getSpeedProfile().shortWaitCondition().atMost(org.awaitility.Duration.TEN_MINUTES)
-                .untilAsserted(() -> assertThat(finishedExecutions.get()).isEqualTo(eventCount));
-            assertThat(rateExceeded).isFalse();
-        }
-
-        @Test
-        default void notificationShouldDeliverASingleEventToAllListenersAtTheSameTime() {
-            CountDownLatch countDownLatch = new CountDownLatch(1);
-            try {
-                ConcurrentLinkedQueue<String> threads = new ConcurrentLinkedQueue<>();
-                Mono.from(eventBus().register(event -> {
-                    threads.add(Thread.currentThread().getName());
-                    countDownLatch.await();
-                }, KEY_1)).block();
-                Mono.from(eventBus().register(event -> {
-                    threads.add(Thread.currentThread().getName());
-                    countDownLatch.await();
-                }, KEY_1)).block();
-                Mono.from(eventBus().register(event -> {
-                    threads.add(Thread.currentThread().getName());
-                    countDownLatch.await();
-                }, KEY_1)).block();
-
-                eventBus().dispatch(EVENT, KEY_1).subscribeOn(Schedulers.elastic()).subscribe();
-
-
-                getSpeedProfile().shortWaitCondition().atMost(org.awaitility.Duration.TEN_SECONDS)
-                    .untilAsserted(() -> assertThat(threads).hasSize(3));
-                assertThat(threads).doesNotHaveDuplicates();
-            } finally {
-                countDownLatch.countDown();
-            }
-        }
-
-
-        @Test
-        default void registeredListenersShouldNotReceiveNoopEvents() throws Exception {
-            EventListener listener = newListener();
-
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-
-            Username bob = Username.of("bob");
-            Added noopEvent = new Added(MailboxSession.SessionId.of(18), bob, MailboxPath.forUser(bob, "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
-            eventBus().dispatch(noopEvent, KEY_1).block();
-
-            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
-                .event(any());
-        }
-
-       @Test
-        default void registeredListenersShouldReceiveOnlyHandledEvents() throws Exception {
-            EventListener listener = newListener();
-
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-
-            eventBus().dispatch(EVENT_UNSUPPORTED_BY_LISTENER, KEY_1).block();
-
-            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
-                .event(any());
-        }
-
-        @Test
-        default void dispatchShouldNotThrowWhenARegisteredListenerFails() throws Exception {
-            EventListener listener = newListener();
-            doThrow(new RuntimeException()).when(listener).event(any());
-
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-
-            assertThatCode(() -> eventBus().dispatch(EVENT, NO_KEYS).block())
-                .doesNotThrowAnyException();
-        }
-
-        @Test
-        default void dispatchShouldNotNotifyRegisteredListenerWhenEmptyKeySet() throws Exception {
-            EventListener listener = newListener();
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-
-            eventBus().dispatch(EVENT, NO_KEYS).block();
-
-            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
-                .event(any());
-        }
-
-        @Test
-        default void dispatchShouldNotNotifyListenerRegisteredOnOtherKeys() throws Exception {
-            EventListener listener = newListener();
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-
-            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_2)).block();
-
-            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
-                .event(any());
-        }
-
-        @Test
-        default void dispatchShouldNotifyRegisteredListeners() throws Exception {
-            EventListener listener = newListener();
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-
-            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
-            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void dispatchShouldNotifyLocalRegisteredListenerWithoutDelay() throws Exception {
-            EventListener listener = newListener();
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-
-            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
-            verify(listener, times(1)).event(any());
-        }
-
-        @Test
-        default void dispatchShouldNotifyOnlyRegisteredListener() throws Exception {
-            EventListener listener = newListener();
-            EventListener listener2 = newListener();
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-            Mono.from(eventBus().register(listener2, KEY_2)).block();
-
-            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
-            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-            verify(listener2, after(FIVE_HUNDRED_MS.toMillis()).never())
-                .event(any());
-        }
-
-        @Test
-        default void dispatchShouldNotifyAllListenersRegisteredOnAKey() throws Exception {
-            EventListener listener = newListener();
-            EventListener listener2 = newListener();
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-            Mono.from(eventBus().register(listener2, KEY_1)).block();
-
-            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
-            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-            verify(listener2, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void registerShouldAllowDuplicatedRegistration() throws Exception {
-            EventListener listener = newListener();
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-
-            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
-            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void unregisterShouldRemoveDoubleRegisteredListener() throws Exception {
-            EventListener listener = newListener();
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-            Mono.from(eventBus().register(listener, KEY_1)).block().unregister();
-
-            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
-            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
-                .event(any());
-        }
-
-        @Test
-        default void registerShouldNotDispatchPastEvents() throws Exception {
-            EventListener listener = newListener();
-
-            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-
-            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
-                .event(any());
-        }
-
-        @Test
-        default void callingAllUnregisterMethodShouldUnregisterTheListener() throws Exception {
-            EventListener listener = newListener();
-            Registration registration = Mono.from(eventBus().register(listener, KEY_1)).block();
-            Mono.from(eventBus().register(listener, KEY_1)).block().unregister();
-            registration.unregister();
-
-            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
-            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
-                .event(any());
-        }
-
-        @Test
-        default void unregisterShouldHaveNotNotifyWhenCalledOnDifferentKeys() throws Exception {
-            EventListener listener = newListener();
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-            Mono.from(eventBus().register(listener, KEY_2)).block().unregister();
-
-            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
-            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void unregisterShouldBeIdempotentForKeyRegistrations() {
-            EventListener listener = newListener();
-
-            Registration registration = Mono.from(eventBus().register(listener, KEY_1)).block();
-            registration.unregister();
-
-            assertThatCode(registration::unregister)
-                .doesNotThrowAnyException();
-        }
-
-        @Test
-        default void dispatchShouldAcceptSeveralKeys() throws Exception {
-            EventListener listener = newListener();
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-
-            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1, KEY_2)).block();
-
-            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void dispatchShouldCallListenerOnceWhenSeveralKeysMatching() throws Exception {
-            EventListener listener = newListener();
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-            Mono.from(eventBus().register(listener, KEY_2)).block();
-
-            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1, KEY_2)).block();
-
-            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void dispatchShouldNotNotifyUnregisteredListener() throws Exception {
-            EventListener listener = newListener();
-            Mono.from(eventBus().register(listener, KEY_1)).block().unregister();
-
-            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
-            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
-                .event(any());
-        }
-
-
-        @Test
-        default void dispatchShouldNotifyAsynchronousListener() throws Exception {
-            EventListener listener = newListener();
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-
-            eventBus().dispatch(EVENT, KEY_1).block();
-
-            verify(listener, after(FIVE_HUNDRED_MS.toMillis())).event(EVENT);
-        }
-
-        @Test
-        default void dispatchShouldNotBlockAsynchronousListener() throws Exception {
-            EventListener listener = newListener();
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
-            CountDownLatch latch = new CountDownLatch(1);
-            doAnswer(invocation -> {
-                latch.await();
-                return null;
-            }).when(listener).event(EVENT);
-
-            assertTimeout(Duration.ofSeconds(2),
-                () -> {
-                    eventBus().dispatch(EVENT, NO_KEYS).block();
-                    latch.countDown();
-                });
-        }
-
-        @Test
-        default void failingRegisteredListenersShouldNotAbortRegisteredDelivery() {
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution listener = new EventBusTestFixture.EventMatcherThrowingListener(ImmutableSet.of(EVENT));
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-
-            eventBus().dispatch(EVENT, KEY_1).block();
-            eventBus().dispatch(EVENT_2, KEY_1).block();
-
-            getSpeedProfile().shortWaitCondition()
-                .untilAsserted(() -> assertThat(listener.numberOfEventCalls()).isEqualTo(1));
-        }
-
-        @Test
-        default void allRegisteredListenersShouldBeExecutedWhenARegisteredListenerFails() throws Exception {
-            EventListener listener = newListener();
-
-            EventListener failingListener = mock(EventListener.class);
-            when(failingListener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
-            doThrow(new RuntimeException()).when(failingListener).event(any());
-
-            Mono.from(eventBus().register(failingListener, KEY_1)).block();
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-
-            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
-            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-    }
-
-    interface MultipleEventBusKeyContract extends MultipleEventBusContract {
-
-        @Test
-        default void crossEventBusRegistrationShouldBeAllowed() throws Exception {
-            EventListener mailboxListener = newListener();
-
-            Mono.from(eventBus().register(mailboxListener, KEY_1)).block();
-
-            eventBus2().dispatch(EVENT, KEY_1).block();
-
-            verify(mailboxListener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void unregisteredDistantListenersShouldNotBeNotified() throws Exception {
-            EventListener eventListener = newListener();
-
-            Mono.from(eventBus().register(eventListener, KEY_1)).block().unregister();
-
-            eventBus2().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
-            verify(eventListener, after(FIVE_HUNDRED_MS.toMillis()).never())
-                .event(any());
-        }
-
-        @Test
-        default void allRegisteredListenersShouldBeDispatched() throws Exception {
-            EventListener mailboxListener1 = newListener();
-            EventListener mailboxListener2 = newListener();
-
-            Mono.from(eventBus().register(mailboxListener1, KEY_1)).block();
-            Mono.from(eventBus2().register(mailboxListener2, KEY_1)).block();
-
-            eventBus2().dispatch(EVENT, KEY_1).block();
-
-            verify(mailboxListener1, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-            verify(mailboxListener2, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-        @Test
-        default void registerShouldNotDispatchPastEventsInDistributedContext() throws Exception {
-            EventListener listener = newListener();
-
-            eventBus2().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
-            Mono.from(eventBus().register(listener, KEY_1)).block();
-
-            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
-                .event(any());
-        }
-
-        @Test
-        default void localDispatchedListenersShouldBeDispatchedWithoutDelay() throws Exception {
-            EventListener mailboxListener1 = newListener();
-            EventListener mailboxListener2 = newListener();
-
-            Mono.from(eventBus().register(mailboxListener1, KEY_1)).block();
-            Mono.from(eventBus2().register(mailboxListener2, KEY_1)).block();
-
-            eventBus2().dispatch(EVENT, KEY_1).block();
-
-            verify(mailboxListener2, times(1)).event(any());
-            verify(mailboxListener1, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-        }
-
-    }
-}
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/MailboxIdRegistrationKeyTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/MailboxIdRegistrationKeyTest.java
deleted file mode 100644
index 0a361b6..0000000
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/MailboxIdRegistrationKeyTest.java
+++ /dev/null
@@ -1,60 +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.mailbox.events;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import org.apache.james.mailbox.model.TestId;
-import org.junit.jupiter.api.Test;
-
-import nl.jqno.equalsverifier.EqualsVerifier;
-
-class MailboxIdRegistrationKeyTest {
-    private static final String ID = "42";
-
-    private static final MailboxIdRegistrationKey.Factory FACTORY = new MailboxIdRegistrationKey.Factory(new TestId.Factory());
-
-    private static final MailboxIdRegistrationKey MAILBOX_ID_REGISTRATION_KEY = new MailboxIdRegistrationKey((TestId.of(42)));
-
-    @Test
-    void shouldRespectBeanContract() {
-        EqualsVerifier.forClass(MailboxIdRegistrationKey.class)
-            .verify();
-    }
-
-    @Test
-    void asStringShouldReturnSerializedMailboxId() {
-        assertThat(MAILBOX_ID_REGISTRATION_KEY.asString())
-            .isEqualTo(ID);
-    }
-
-    @Test
-    void fromStringShouldReturnCorrespondingRegistrationKey() {
-        assertThat(FACTORY.fromString(ID))
-            .isEqualTo(MAILBOX_ID_REGISTRATION_KEY);
-    }
-
-    @Test
-    void fromStringShouldThrowOnInvalidValues() {
-        assertThatThrownBy(() -> FACTORY.fromString("invalid"))
-            .isInstanceOf(IllegalArgumentException.class);
-    }
-}
\ No newline at end of file
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/RetryBackoffConfigurationTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/RetryBackoffConfigurationTest.java
deleted file mode 100644
index 0788da9..0000000
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/RetryBackoffConfigurationTest.java
+++ /dev/null
@@ -1,141 +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.mailbox.events;
-
-import static org.apache.james.mailbox.events.RetryBackoffConfiguration.DEFAULT_FIRST_BACKOFF;
-import static org.apache.james.mailbox.events.RetryBackoffConfiguration.DEFAULT_JITTER_FACTOR;
-import static org.apache.james.mailbox.events.RetryBackoffConfiguration.DEFAULT_MAX_RETRIES;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import java.time.Duration;
-
-import org.assertj.core.api.SoftAssertions;
-import org.junit.jupiter.api.Test;
-
-import nl.jqno.equalsverifier.EqualsVerifier;
-
-class RetryBackoffConfigurationTest {
-
-    @Test
-    void shouldMatchBeanContract() {
-        EqualsVerifier.forClass(RetryBackoffConfiguration.class)
-            .verify();
-    }
-
-    @Test
-    void buildShouldThrowWhenNegativeFirstBackoff() {
-        assertThatThrownBy(() -> RetryBackoffConfiguration.builder()
-            .maxRetries(DEFAULT_MAX_RETRIES)
-            .firstBackoff(Duration.ofMillis(-1000L))
-            .jitterFactor(DEFAULT_JITTER_FACTOR)
-            .build())
-        .isInstanceOf(IllegalArgumentException.class)
-        .hasMessage("firstBackoff is not allowed to be negative");
-    }
-
-    @Test
-    void buildShouldThrowWhenNegativeMaxRetries() {
-        assertThatThrownBy(() -> RetryBackoffConfiguration.builder()
-            .maxRetries(-6)
-            .firstBackoff(DEFAULT_FIRST_BACKOFF)
-            .jitterFactor(DEFAULT_JITTER_FACTOR)
-            .build())
-        .isInstanceOf(IllegalArgumentException.class)
-        .hasMessage("maxRetries is not allowed to be negative");
-    }
-
-    @Test
-    void buildShouldThrowWhenNegativeJitterFactor() {
-        assertThatThrownBy(() -> RetryBackoffConfiguration.builder()
-            .maxRetries(DEFAULT_MAX_RETRIES)
-            .firstBackoff(DEFAULT_FIRST_BACKOFF)
-            .jitterFactor(-2.5)
-            .build())
-        .isInstanceOf(IllegalArgumentException.class)
-        .hasMessage("jitterFactor is not allowed to be negative or greater than 1");
-    }
-
-    @Test
-    void buildShouldThrowWhenGreaterThanOneJitterFactor() {
-        assertThatThrownBy(() -> RetryBackoffConfiguration.builder()
-            .maxRetries(DEFAULT_MAX_RETRIES)
-            .firstBackoff(DEFAULT_FIRST_BACKOFF)
-            .jitterFactor(1.000001)
-            .build())
-        .isInstanceOf(IllegalArgumentException.class)
-        .hasMessage("jitterFactor is not allowed to be negative or greater than 1");
-    }
-
-    @Test
-    void buildShouldSuccessWhenZeroFirstBackoff() {
-        RetryBackoffConfiguration retryBackoff = RetryBackoffConfiguration.builder()
-            .maxRetries(DEFAULT_MAX_RETRIES)
-            .firstBackoff(Duration.ZERO)
-            .jitterFactor(DEFAULT_JITTER_FACTOR)
-            .build();
-
-        assertThat(retryBackoff.getFirstBackoff().toMillis())
-            .isEqualTo(0L);
-    }
-
-    @Test
-    void buildShouldSuccessWhenZeroMaxRetries() {
-        RetryBackoffConfiguration retryBackoff = RetryBackoffConfiguration.builder()
-            .maxRetries(0)
-            .firstBackoff(DEFAULT_FIRST_BACKOFF)
-            .jitterFactor(DEFAULT_JITTER_FACTOR)
-            .build();
-
-        assertThat(retryBackoff.getMaxRetries())
-            .isEqualTo(0L);
-    }
-
-    @Test
-    void buildShouldSuccessWhenZeroJitterFactor() {
-        RetryBackoffConfiguration retryBackoff = RetryBackoffConfiguration.builder()
-            .maxRetries(DEFAULT_MAX_RETRIES)
-            .firstBackoff(DEFAULT_FIRST_BACKOFF)
-            .jitterFactor(0)
-            .build();
-
-        assertThat(retryBackoff.getJitterFactor())
-            .isEqualTo(0);
-    }
-
-    @Test
-    void buildShouldReturnCorrespondingValues() {
-        RetryBackoffConfiguration retryBackoff = RetryBackoffConfiguration.builder()
-            .maxRetries(5)
-            .firstBackoff(Duration.ofMillis(200))
-            .jitterFactor(0.6)
-            .build();
-
-        SoftAssertions.assertSoftly(softly -> {
-            softly.assertThat(retryBackoff.getJitterFactor())
-                .isEqualTo(0.6);
-            softly.assertThat(retryBackoff.getMaxRetries())
-                .isEqualTo(5);
-            softly.assertThat(retryBackoff.getFirstBackoff())
-                .isEqualTo(Duration.ofMillis(200));
-        });
-    }
-
-}
\ No newline at end of file
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageMovesTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageMovesTest.java
index 8787db5..1710ceb 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageMovesTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageMovesTest.java
@@ -19,7 +19,7 @@
 
 package org.apache.james.mailbox.model;
 
-import org.apache.james.mailbox.events.MessageMoveEvent;
+import org.apache.james.events.MessageMoveEvent;
 import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
diff --git a/mailbox/cassandra/pom.xml b/mailbox/cassandra/pom.xml
index 385f0b6..f596178 100644
--- a/mailbox/cassandra/pom.xml
+++ b/mailbox/cassandra/pom.xml
@@ -54,11 +54,6 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>apache-james-mailbox-event-memory</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
             <artifactId>apache-james-mailbox-store</artifactId>
         </dependency>
         <dependency>
@@ -89,6 +84,11 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-in-vm</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-sourcing-core</artifactId>
         </dependency>
         <dependency>
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java
index 728bd81..4b2f084 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java
@@ -31,6 +31,8 @@ import org.apache.james.blob.api.BlobStore;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventListener;
 import org.apache.james.events.Group;
+import org.apache.james.events.MailboxEvents.Expunged;
+import org.apache.james.events.MailboxEvents.MailboxDeletion;
 import org.apache.james.mailbox.acl.ACLDiff;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
@@ -50,8 +52,6 @@ import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraUserMailboxRightsDAO;
 import org.apache.james.mailbox.cassandra.mail.MessageAttachmentRepresentation;
 import org.apache.james.mailbox.cassandra.mail.MessageRepresentation;
-import org.apache.james.mailbox.events.MailboxEvents.Expunged;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
 import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MessageMetaData;
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListener.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListener.java
index dcfd070..b48508f 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListener.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListener.java
@@ -26,9 +26,9 @@ import static org.apache.james.mailbox.cassandra.GhostMailbox.TYPE;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventListener;
 import org.apache.james.events.Group;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxRenamed;
+import org.apache.james.events.MailboxEvents.MailboxAdded;
+import org.apache.james.events.MailboxEvents.MailboxDeletion;
+import org.apache.james.events.MailboxEvents.MailboxRenamed;
 
 /**
  * See https://issues.apache.org/jira/browse/MAILBOX-322 for reading about the Ghost mailbox bug.
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraCombinationManagerTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraCombinationManagerTest.java
index 88ef7a5..dfd49c7 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraCombinationManagerTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraCombinationManagerTest.java
@@ -20,11 +20,11 @@
 package org.apache.james.mailbox.cassandra;
 
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import org.apache.james.events.EventBusTestFixture;
+import org.apache.james.events.InVMEventBus;
+import org.apache.james.events.MemoryEventDeadLetters;
+import org.apache.james.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.cassandra.mail.MailboxAggregateModule;
-import org.apache.james.mailbox.events.EventBusTestFixture;
-import org.apache.james.mailbox.events.InVMEventBus;
-import org.apache.james.mailbox.events.MemoryEventDeadLetters;
-import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.store.AbstractCombinationManagerTest;
 import org.apache.james.mailbox.store.CombinationManagerTestSystem;
 import org.apache.james.mailbox.store.quota.NoQuotaManager;
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerProvider.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerProvider.java
index e497c3f..3d2226c 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerProvider.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerProvider.java
@@ -21,6 +21,10 @@ package org.apache.james.mailbox.cassandra;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.init.configuration.CassandraConfiguration;
+import org.apache.james.events.EventBusTestFixture;
+import org.apache.james.events.InVMEventBus;
+import org.apache.james.events.MemoryEventDeadLetters;
+import org.apache.james.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.Authenticator;
 import org.apache.james.mailbox.Authorizator;
@@ -34,10 +38,6 @@ import org.apache.james.mailbox.cassandra.quota.CassandraGlobalMaxQuotaDao;
 import org.apache.james.mailbox.cassandra.quota.CassandraPerDomainMaxQuotaDao;
 import org.apache.james.mailbox.cassandra.quota.CassandraPerUserMaxQuotaDao;
 import org.apache.james.mailbox.cassandra.quota.CassandraPerUserMaxQuotaManager;
-import org.apache.james.mailbox.events.EventBusTestFixture;
-import org.apache.james.mailbox.events.InVMEventBus;
-import org.apache.james.mailbox.events.MemoryEventDeadLetters;
-import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
 import org.apache.james.mailbox.store.MailboxManagerConfiguration;
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerStorageTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerStorageTest.java
index d536fd4..2d9179c 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerStorageTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerStorageTest.java
@@ -20,11 +20,11 @@
 package org.apache.james.mailbox.cassandra;
 
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import org.apache.james.events.EventBusTestFixture;
+import org.apache.james.events.InVMEventBus;
+import org.apache.james.events.MemoryEventDeadLetters;
+import org.apache.james.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.cassandra.mail.MailboxAggregateModule;
-import org.apache.james.mailbox.events.EventBusTestFixture;
-import org.apache.james.mailbox.events.InVMEventBus;
-import org.apache.james.mailbox.events.MemoryEventDeadLetters;
-import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.extension.PreDeletionHook;
 import org.apache.james.mailbox.store.AbstractMessageIdManagerStorageTest;
 import org.apache.james.mailbox.store.MessageIdManagerTestSystem;
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraTestSystemFixture.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraTestSystemFixture.java
index 1b4f270..12c1553 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraTestSystemFixture.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraTestSystemFixture.java
@@ -23,6 +23,10 @@ import static org.mockito.Mockito.mock;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.events.EventBus;
+import org.apache.james.events.EventBusTestFixture;
+import org.apache.james.events.InVMEventBus;
+import org.apache.james.events.MemoryEventDeadLetters;
+import org.apache.james.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.Authenticator;
 import org.apache.james.mailbox.Authorizator;
@@ -34,10 +38,6 @@ import org.apache.james.mailbox.cassandra.quota.CassandraGlobalMaxQuotaDao;
 import org.apache.james.mailbox.cassandra.quota.CassandraPerDomainMaxQuotaDao;
 import org.apache.james.mailbox.cassandra.quota.CassandraPerUserMaxQuotaDao;
 import org.apache.james.mailbox.cassandra.quota.CassandraPerUserMaxQuotaManager;
-import org.apache.james.mailbox.events.EventBusTestFixture;
-import org.apache.james.mailbox.events.InVMEventBus;
-import org.apache.james.mailbox.events.MemoryEventDeadLetters;
-import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.quota.CurrentQuotaManager;
 import org.apache.james.mailbox.quota.MaxQuotaManager;
 import org.apache.james.mailbox.quota.QuotaManager;
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java
index d0e2910..05624f3 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java
@@ -23,6 +23,10 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import org.apache.james.events.EventBusTestFixture;
+import org.apache.james.events.InVMEventBus;
+import org.apache.james.events.MemoryEventDeadLetters;
+import org.apache.james.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.Authenticator;
 import org.apache.james.mailbox.Authorizator;
@@ -33,10 +37,6 @@ import org.apache.james.mailbox.cassandra.CassandraMailboxManager;
 import org.apache.james.mailbox.cassandra.CassandraMailboxSessionMapperFactory;
 import org.apache.james.mailbox.cassandra.TestCassandraMailboxSessionMapperFactory;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
-import org.apache.james.mailbox.events.EventBusTestFixture;
-import org.apache.james.mailbox.events.InVMEventBus;
-import org.apache.james.mailbox.events.MemoryEventDeadLetters;
-import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.store.AbstractMailboxManagerAttachmentTest;
 import org.apache.james.mailbox.store.MailboxManagerConfiguration;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
diff --git a/mailbox/elasticsearch/pom.xml b/mailbox/elasticsearch/pom.xml
index 607e814..f4b06b7 100644
--- a/mailbox/elasticsearch/pom.xml
+++ b/mailbox/elasticsearch/pom.xml
@@ -54,11 +54,6 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>apache-james-mailbox-event-memory</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
             <artifactId>apache-james-mailbox-memory</artifactId>
             <scope>test</scope>
         </dependency>
@@ -91,6 +86,11 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-in-vm</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-server-testing</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLetters.java b/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLetters.java
deleted file mode 100644
index 77a1c5e..0000000
--- a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLetters.java
+++ /dev/null
@@ -1,89 +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.mailbox.events;
-
-import javax.inject.Inject;
-
-import org.apache.james.events.Event;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.events.Group;
-
-import com.google.common.base.Preconditions;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-public class CassandraEventDeadLetters implements EventDeadLetters {
-
-    private final CassandraEventDeadLettersDAO cassandraEventDeadLettersDAO;
-    private final CassandraEventDeadLettersGroupDAO cassandraEventDeadLettersGroupDAO;
-
-
-    @Inject
-    CassandraEventDeadLetters(CassandraEventDeadLettersDAO cassandraEventDeadLettersDAO,
-                              CassandraEventDeadLettersGroupDAO cassandraEventDeadLettersGroupDAO) {
-        this.cassandraEventDeadLettersDAO = cassandraEventDeadLettersDAO;
-        this.cassandraEventDeadLettersGroupDAO = cassandraEventDeadLettersGroupDAO;
-    }
-
-    @Override
-    public Mono<InsertionId> store(Group registeredGroup, Event failDeliveredEvent) {
-        Preconditions.checkArgument(registeredGroup != null, REGISTERED_GROUP_CANNOT_BE_NULL);
-        Preconditions.checkArgument(failDeliveredEvent != null, FAIL_DELIVERED_EVENT_CANNOT_BE_NULL);
-
-        InsertionId insertionId = InsertionId.random();
-        return cassandraEventDeadLettersDAO.store(registeredGroup, failDeliveredEvent, insertionId)
-            .then(cassandraEventDeadLettersGroupDAO.storeGroup(registeredGroup))
-            .thenReturn(insertionId);
-    }
-
-    @Override
-    public Mono<Void> remove(Group registeredGroup, InsertionId failDeliveredInsertionId) {
-        Preconditions.checkArgument(registeredGroup != null, REGISTERED_GROUP_CANNOT_BE_NULL);
-        Preconditions.checkArgument(failDeliveredInsertionId != null, FAIL_DELIVERED_ID_INSERTION_CANNOT_BE_NULL);
-
-        return cassandraEventDeadLettersDAO.removeEvent(registeredGroup, failDeliveredInsertionId);
-    }
-
-    @Override
-    public Mono<Event> failedEvent(Group registeredGroup, InsertionId failDeliveredInsertionId) {
-        Preconditions.checkArgument(registeredGroup != null, REGISTERED_GROUP_CANNOT_BE_NULL);
-        Preconditions.checkArgument(failDeliveredInsertionId != null, FAIL_DELIVERED_ID_INSERTION_CANNOT_BE_NULL);
-
-        return cassandraEventDeadLettersDAO.retrieveFailedEvent(registeredGroup, failDeliveredInsertionId);
-    }
-
-    @Override
-    public Flux<InsertionId> failedIds(Group registeredGroup) {
-        Preconditions.checkArgument(registeredGroup != null, REGISTERED_GROUP_CANNOT_BE_NULL);
-
-        return cassandraEventDeadLettersDAO.retrieveInsertionIdsWithGroup(registeredGroup);
-    }
-
-    @Override
-    public Flux<Group> groupsWithFailedEvents() {
-        return cassandraEventDeadLettersGroupDAO.retrieveAllGroups();
-    }
-
-    @Override
-    public Mono<Boolean> containEvents() {
-        return cassandraEventDeadLettersDAO.containEvents();
-    }
-}
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersDAO.java b/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersDAO.java
deleted file mode 100644
index 0d20d43..0000000
--- a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersDAO.java
+++ /dev/null
@@ -1,132 +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.mailbox.events;
-
-import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
-import static com.datastax.driver.core.querybuilder.QueryBuilder.delete;
-import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
-import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
-import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
-import static org.apache.james.mailbox.events.tables.CassandraEventDeadLettersTable.EVENT;
-import static org.apache.james.mailbox.events.tables.CassandraEventDeadLettersTable.GROUP;
-import static org.apache.james.mailbox.events.tables.CassandraEventDeadLettersTable.INSERTION_ID;
-import static org.apache.james.mailbox.events.tables.CassandraEventDeadLettersTable.TABLE_NAME;
-
-import javax.inject.Inject;
-
-import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
-import org.apache.james.event.json.EventSerializer;
-import org.apache.james.events.Event;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.events.Group;
-
-import com.datastax.driver.core.PreparedStatement;
-import com.datastax.driver.core.Session;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-public class CassandraEventDeadLettersDAO {
-    private final CassandraAsyncExecutor executor;
-    private final EventSerializer eventSerializer;
-    private final PreparedStatement insertStatement;
-    private final PreparedStatement deleteStatement;
-    private final PreparedStatement selectEventStatement;
-    private final PreparedStatement selectEventIdsWithGroupStatement;
-    private final PreparedStatement containEventsStatement;
-
-    @Inject
-    CassandraEventDeadLettersDAO(Session session, EventSerializer eventSerializer) {
-        this.executor = new CassandraAsyncExecutor(session);
-        this.eventSerializer = eventSerializer;
-        this.insertStatement = prepareInsertStatement(session);
-        this.deleteStatement = prepareDeleteStatement(session);
-        this.selectEventStatement = prepareSelectEventStatement(session);
-        this.selectEventIdsWithGroupStatement = prepareSelectInsertionIdsWithGroupStatement(session);
-        this.containEventsStatement = prepareContainEventStatement(session);
-    }
-
-    private PreparedStatement prepareInsertStatement(Session session) {
-        return session.prepare(insertInto(TABLE_NAME)
-            .value(GROUP, bindMarker(GROUP))
-            .value(INSERTION_ID, bindMarker(INSERTION_ID))
-            .value(EVENT, bindMarker(EVENT)));
-    }
-
-    private PreparedStatement prepareDeleteStatement(Session session) {
-        return session.prepare(delete()
-            .from(TABLE_NAME)
-            .where(eq(GROUP, bindMarker(GROUP)))
-            .and(eq(INSERTION_ID, bindMarker(INSERTION_ID))));
-    }
-
-    private PreparedStatement prepareSelectEventStatement(Session session) {
-        return session.prepare(select(EVENT)
-            .from(TABLE_NAME)
-            .where(eq(GROUP, bindMarker(GROUP)))
-            .and(eq(INSERTION_ID, bindMarker(INSERTION_ID))));
-    }
-
-    private PreparedStatement prepareSelectInsertionIdsWithGroupStatement(Session session) {
-        return session.prepare(select(INSERTION_ID)
-            .from(TABLE_NAME)
-            .where(eq(GROUP, bindMarker(GROUP))));
-    }
-
-    private PreparedStatement prepareContainEventStatement(Session session) {
-        return session.prepare(select(EVENT)
-            .from(TABLE_NAME)
-            .limit(1));
-    }
-
-    Mono<Void> store(Group group, Event failedEvent, EventDeadLetters.InsertionId insertionId) {
-        return executor.executeVoid(insertStatement.bind()
-                .setString(GROUP, group.asString())
-                .setUUID(INSERTION_ID, insertionId.getId())
-                .setString(EVENT, eventSerializer.toJson(failedEvent)));
-    }
-
-    Mono<Void> removeEvent(Group group, EventDeadLetters.InsertionId failedInsertionId) {
-        return executor.executeVoid(deleteStatement.bind()
-                .setString(GROUP, group.asString())
-                .setUUID(INSERTION_ID, failedInsertionId.getId()));
-    }
-
-    Mono<Event> retrieveFailedEvent(Group group, EventDeadLetters.InsertionId insertionId) {
-        return executor.executeSingleRow(selectEventStatement.bind()
-                .setString(GROUP, group.asString())
-                .setUUID(INSERTION_ID, insertionId.getId()))
-            .map(row -> deserializeEvent(row.getString(EVENT)));
-    }
-
-    Flux<EventDeadLetters.InsertionId> retrieveInsertionIdsWithGroup(Group group) {
-        return executor.executeRows(selectEventIdsWithGroupStatement.bind()
-                .setString(GROUP, group.asString()))
-            .map(row -> EventDeadLetters.InsertionId.of(row.getUUID(INSERTION_ID)));
-    }
-
-    Mono<Boolean> containEvents() {
-        return executor.executeReturnExists(containEventsStatement.bind());
-    }
-
-    private Event deserializeEvent(String serializedEvent) {
-        return eventSerializer.fromJson(serializedEvent).get();
-    }
-}
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersGroupDAO.java b/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersGroupDAO.java
deleted file mode 100644
index 20b283e..0000000
--- a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersGroupDAO.java
+++ /dev/null
@@ -1,71 +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.mailbox.events;
-
-import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
-import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
-import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
-import static org.apache.james.mailbox.events.tables.CassandraEventDeadLettersGroupTable.GROUP;
-import static org.apache.james.mailbox.events.tables.CassandraEventDeadLettersGroupTable.TABLE_NAME;
-
-import javax.inject.Inject;
-
-import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
-import org.apache.james.events.Group;
-
-import com.datastax.driver.core.PreparedStatement;
-import com.datastax.driver.core.Session;
-import com.github.fge.lambdas.Throwing;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-public class CassandraEventDeadLettersGroupDAO {
-    private final CassandraAsyncExecutor executor;
-    private final PreparedStatement insertStatement;
-    private final PreparedStatement selectAllStatement;
-
-    @Inject
-    CassandraEventDeadLettersGroupDAO(Session session) {
-        this.executor = new CassandraAsyncExecutor(session);
-        this.insertStatement = prepareInsertStatement(session);
-        this.selectAllStatement = prepareSelectStatement(session);
-    }
-
-    private PreparedStatement prepareInsertStatement(Session session) {
-        return session.prepare(insertInto(TABLE_NAME)
-            .value(GROUP, bindMarker(GROUP)));
-    }
-
-    private PreparedStatement prepareSelectStatement(Session session) {
-        return session.prepare(select(GROUP)
-            .from(TABLE_NAME));
-    }
-
-    Mono<Void> storeGroup(Group group) {
-        return executor.executeVoid(insertStatement.bind()
-                .setString(GROUP, group.asString()));
-    }
-
-    Flux<Group> retrieveAllGroups() {
-        return executor.executeRows(selectAllStatement.bind())
-            .map(Throwing.function(row -> Group.deserialize(row.getString(GROUP))));
-    }
-}
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersModule.java b/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersModule.java
deleted file mode 100644
index 6c4095c..0000000
--- a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersModule.java
+++ /dev/null
@@ -1,46 +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.mailbox.events;
-
-import org.apache.james.backends.cassandra.components.CassandraModule;
-import org.apache.james.backends.cassandra.utils.CassandraConstants;
-import org.apache.james.mailbox.events.tables.CassandraEventDeadLettersGroupTable;
-import org.apache.james.mailbox.events.tables.CassandraEventDeadLettersTable;
-
-import com.datastax.driver.core.DataType;
-import com.datastax.driver.core.schemabuilder.SchemaBuilder;
-
-public interface CassandraEventDeadLettersModule {
-    CassandraModule MODULE = CassandraModule.builder()
-        .table(CassandraEventDeadLettersTable.TABLE_NAME)
-        .comment("Holds event dead letter")
-        .options(options -> options
-            .caching(SchemaBuilder.KeyCaching.ALL,
-                SchemaBuilder.rows(CassandraConstants.DEFAULT_CACHED_ROW_PER_PARTITION)))
-        .statement(statement -> statement
-            .addPartitionKey(CassandraEventDeadLettersTable.GROUP, DataType.text())
-            .addClusteringColumn(CassandraEventDeadLettersTable.INSERTION_ID, DataType.uuid())
-            .addColumn(CassandraEventDeadLettersTable.EVENT, DataType.text()))
-        .table(CassandraEventDeadLettersGroupTable.TABLE_NAME)
-        .comment("Projection table for retrieving groups for all failed events")
-        .statement(statement -> statement
-            .addPartitionKey(CassandraEventDeadLettersGroupTable.GROUP, DataType.text()))
-        .build();
-}
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/tables/CassandraEventDeadLettersGroupTable.java b/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/tables/CassandraEventDeadLettersGroupTable.java
deleted file mode 100644
index b1d6219..0000000
--- a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/tables/CassandraEventDeadLettersGroupTable.java
+++ /dev/null
@@ -1,27 +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.mailbox.events.tables;
-
-public interface CassandraEventDeadLettersGroupTable {
-
-    String TABLE_NAME = "group_table";
-
-    String GROUP = "group";
-}
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/tables/CassandraEventDeadLettersTable.java b/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/tables/CassandraEventDeadLettersTable.java
deleted file mode 100644
index cbf272c..0000000
--- a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/tables/CassandraEventDeadLettersTable.java
+++ /dev/null
@@ -1,29 +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.mailbox.events.tables;
-
-public interface CassandraEventDeadLettersTable {
-
-    String TABLE_NAME = "event_dead_letters";
-
-    String GROUP = "group";
-    String INSERTION_ID = "insertionId";
-    String EVENT = "event";
-}
diff --git a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersDAOTest.java b/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersDAOTest.java
deleted file mode 100644
index 35ab39f..0000000
--- a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersDAOTest.java
+++ /dev/null
@@ -1,145 +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.mailbox.events;
-
-import static org.apache.james.mailbox.events.EventDeadLettersContract.EVENT_1;
-import static org.apache.james.mailbox.events.EventDeadLettersContract.EVENT_2;
-import static org.apache.james.mailbox.events.EventDeadLettersContract.EVENT_3;
-import static org.apache.james.mailbox.events.EventDeadLettersContract.GROUP_A;
-import static org.apache.james.mailbox.events.EventDeadLettersContract.GROUP_B;
-import static org.apache.james.mailbox.events.EventDeadLettersContract.INSERTION_ID_1;
-import static org.apache.james.mailbox.events.EventDeadLettersContract.INSERTION_ID_2;
-import static org.apache.james.mailbox.events.EventDeadLettersContract.INSERTION_ID_3;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.apache.james.backends.cassandra.CassandraCluster;
-import org.apache.james.backends.cassandra.CassandraClusterExtension;
-import org.apache.james.event.json.EventSerializer;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.mailbox.model.TestMessageId;
-import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class CassandraEventDeadLettersDAOTest {
-
-    @RegisterExtension
-    static CassandraClusterExtension cassandraClusterExtension = new CassandraClusterExtension(CassandraEventDeadLettersModule.MODULE);
-
-    private CassandraEventDeadLettersDAO cassandraEventDeadLettersDAO;
-
-    @BeforeEach
-    void setUp(CassandraCluster cassandraCluster) {
-        EventSerializer eventSerializer = new EventSerializer(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
-        cassandraEventDeadLettersDAO = new CassandraEventDeadLettersDAO(cassandraCluster.getConf(), eventSerializer);
-    }
-
-    @Test
-    void removeEventShouldSucceededWhenRemoveStoredEvent() {
-        cassandraEventDeadLettersDAO.store(GROUP_A, EVENT_1, INSERTION_ID_1).block();
-
-        cassandraEventDeadLettersDAO.removeEvent(GROUP_A, INSERTION_ID_1).block();
-
-        assertThat(cassandraEventDeadLettersDAO
-                .retrieveInsertionIdsWithGroup(GROUP_A)
-                .collectList().block())
-            .isEmpty();
-    }
-
-    @Test
-    void retrieveFailedEventShouldReturnEmptyWhenDefault() {
-        assertThat(cassandraEventDeadLettersDAO
-                .retrieveFailedEvent(GROUP_A, INSERTION_ID_1)
-                .blockOptional().isPresent())
-            .isFalse();
-    }
-
-    @Test
-    void retrieveFailedEventShouldReturnStoredEvent() {
-        cassandraEventDeadLettersDAO.store(GROUP_A, EVENT_1, INSERTION_ID_1).block();
-        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_2, INSERTION_ID_2).block();
-
-        assertThat(cassandraEventDeadLettersDAO
-                .retrieveFailedEvent(GROUP_B, INSERTION_ID_2)
-                .blockOptional().get())
-            .isEqualTo(EVENT_2);
-    }
-
-    @Test
-    void retrieveInsertionIdsWithGroupShouldReturnEmptyWhenDefault() {
-        assertThat(cassandraEventDeadLettersDAO
-                .retrieveInsertionIdsWithGroup(GROUP_A)
-                .collectList().block())
-            .isEmpty();
-    }
-
-    @Test
-    void retrieveInsertionIdsWithGroupShouldReturnStoredInsertionId() {
-        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_1, INSERTION_ID_1).block();
-        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_2, INSERTION_ID_2).block();
-        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_3, INSERTION_ID_3).block();
-
-        assertThat(cassandraEventDeadLettersDAO
-                .retrieveInsertionIdsWithGroup(GROUP_B)
-                .collectList().block())
-            .containsOnly(INSERTION_ID_1, INSERTION_ID_2, INSERTION_ID_3);
-    }
-
-    @Test
-    void shouldReturnTrueWhenEventStored() {
-        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_1, INSERTION_ID_1).block();
-        assertThat(cassandraEventDeadLettersDAO.containEvents().block()).isTrue();
-    }
-
-    @Test
-    void shouldReturnTrueWhenNoEventStored() {
-        assertThat(cassandraEventDeadLettersDAO.containEvents().block()).isFalse();
-    }
-
-    @Test
-    void shouldReturnTrueWhenEventsStoredAndRemovedSome() {
-        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_1, INSERTION_ID_1).block();
-        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_1, INSERTION_ID_2).block();
-        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_1, INSERTION_ID_3).block();
-
-        assertThat(cassandraEventDeadLettersDAO.containEvents().block()).isTrue();
-
-        cassandraEventDeadLettersDAO.removeEvent(GROUP_B, INSERTION_ID_3).block();
-
-        assertThat(cassandraEventDeadLettersDAO.containEvents().block()).isTrue();
-    }
-
-    @Test
-    void shouldReturnFalseWhenRemovedAllEventsStored() {
-        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_1, INSERTION_ID_1).block();
-        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_1, INSERTION_ID_2).block();
-        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_1, INSERTION_ID_3).block();
-
-        assertThat(cassandraEventDeadLettersDAO.containEvents().block()).isTrue();
-
-        cassandraEventDeadLettersDAO.removeEvent(GROUP_B, INSERTION_ID_3).block();
-        cassandraEventDeadLettersDAO.removeEvent(GROUP_B, INSERTION_ID_2).block();
-        cassandraEventDeadLettersDAO.removeEvent(GROUP_B, INSERTION_ID_1).block();
-
-        assertThat(cassandraEventDeadLettersDAO.containEvents().block()).isFalse();
-    }
-
-}
diff --git a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersGroupDAOTest.java b/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersGroupDAOTest.java
deleted file mode 100644
index c5bc092..0000000
--- a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersGroupDAOTest.java
+++ /dev/null
@@ -1,60 +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.mailbox.events;
-
-import static org.apache.james.mailbox.events.EventDeadLettersContract.GROUP_A;
-import static org.apache.james.mailbox.events.EventDeadLettersContract.GROUP_B;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.apache.james.backends.cassandra.CassandraCluster;
-import org.apache.james.backends.cassandra.CassandraClusterExtension;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-public class CassandraEventDeadLettersGroupDAOTest {
-
-    @RegisterExtension
-    static CassandraClusterExtension cassandraClusterExtension = new CassandraClusterExtension(CassandraEventDeadLettersModule.MODULE);
-
-    private static CassandraEventDeadLettersGroupDAO GROUP_DAO;
-
-    @BeforeAll
-    static void setUp(CassandraCluster cassandraCluster) {
-        GROUP_DAO = new CassandraEventDeadLettersGroupDAO(cassandraCluster.getConf());
-    }
-
-    @Test
-    void retrieveAllGroupsShouldReturnEmptyWhenDefault() {
-        assertThat(GROUP_DAO.retrieveAllGroups()
-                .collectList().block())
-            .isEmpty();
-    }
-
-    @Test
-    void retrieveAllGroupsShouldReturnStoredGroups() {
-        GROUP_DAO.storeGroup(GROUP_A).block();
-        GROUP_DAO.storeGroup(GROUP_B).block();
-
-        assertThat(GROUP_DAO.retrieveAllGroups()
-                .collectList().block())
-            .containsOnly(GROUP_A, GROUP_B);
-    }
-}
diff --git a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersHealthCheckTest.java b/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersHealthCheckTest.java
deleted file mode 100644
index 027ad73..0000000
--- a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersHealthCheckTest.java
+++ /dev/null
@@ -1,70 +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.mailbox.events;
-
-import org.apache.james.backends.cassandra.CassandraCluster;
-import org.apache.james.backends.cassandra.CassandraClusterExtension;
-import org.apache.james.backends.cassandra.DockerCassandra;
-import org.apache.james.event.json.EventSerializer;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.events.EventDeadLettersHealthCheck;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.mailbox.model.TestMessageId;
-import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-
-class CassandraEventDeadLettersHealthCheckTest implements EventDeadLettersHealthCheckContract {
-    @RegisterExtension
-    static CassandraClusterExtension cassandraClusterExtension = new CassandraClusterExtension(CassandraEventDeadLettersModule.MODULE);
-    private EventDeadLettersHealthCheck testee;
-    private CassandraEventDeadLetters eventDeadLetters;
-    private DockerCassandra dockerCassandra;
-
-    @BeforeEach
-    void setUp(CassandraCluster cassandraCluster, DockerCassandra dockerCassandra) {
-        EventSerializer eventSerializer = new EventSerializer(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
-        eventDeadLetters = new CassandraEventDeadLetters(new CassandraEventDeadLettersDAO(cassandraCluster.getConf(), eventSerializer),
-                                                         new CassandraEventDeadLettersGroupDAO(cassandraCluster.getConf()));
-        testee = new EventDeadLettersHealthCheck(eventDeadLetters);
-        this.dockerCassandra = dockerCassandra;
-    }
-
-    @Override
-    public EventDeadLettersHealthCheck testee() {
-        return testee;
-    }
-
-    @Override
-    public EventDeadLetters eventDeadLetters() {
-        return eventDeadLetters;
-    }
-
-    @Override
-    public void createErrorWhenDoingHealthCheck() {
-        dockerCassandra.pause();
-    }
-
-    @Override
-    public void resolveErrorWhenDoingHealthCheck() {
-        dockerCassandra.unpause();
-    }
-}
diff --git a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersTest.java b/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersTest.java
deleted file mode 100644
index 7d81bcd..0000000
--- a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersTest.java
+++ /dev/null
@@ -1,50 +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.mailbox.events;
-
-import org.apache.james.backends.cassandra.CassandraCluster;
-import org.apache.james.backends.cassandra.CassandraClusterExtension;
-import org.apache.james.event.json.EventSerializer;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.mailbox.model.TestMessageId;
-import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class CassandraEventDeadLettersTest implements EventDeadLettersContract.AllContracts {
-
-    @RegisterExtension
-    static CassandraClusterExtension cassandraClusterExtension = new CassandraClusterExtension(CassandraEventDeadLettersModule.MODULE);
-
-    private CassandraEventDeadLetters eventDeadLetters;
-
-    @BeforeEach
-    void setUp(CassandraCluster cassandraCluster) {
-        EventSerializer eventSerializer = new EventSerializer(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
-        eventDeadLetters = new CassandraEventDeadLetters(new CassandraEventDeadLettersDAO(cassandraCluster.getConf(), eventSerializer),
-                                                         new CassandraEventDeadLettersGroupDAO(cassandraCluster.getConf()));
-    }
-
-    @Override
-    public EventDeadLetters eventDeadLetters() {
-        return eventDeadLetters;
-    }
-}
diff --git a/mailbox/event/event-memory/pom.xml b/mailbox/event/event-memory/pom.xml
deleted file mode 100644
index e421778..0000000
--- a/mailbox/event/event-memory/pom.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-    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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.james</groupId>
-        <artifactId>apache-james-mailbox</artifactId>
-        <version>3.6.0-SNAPSHOT</version>
-        <relativePath>../../pom.xml</relativePath>
-    </parent>
-
-    <artifactId>apache-james-mailbox-event-memory</artifactId>
-    <name>Apache James :: Mailbox :: Event :: In VM implementation</name>
-    <description>In VM implementation for the eventbus API</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
-            <artifactId>metrics-tests</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
-            <artifactId>testing-base</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-mailbox-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-mailbox-api</artifactId>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>james-server-util</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>metrics-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.projectreactor</groupId>
-            <artifactId>reactor-core</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.awaitility</groupId>
-            <artifactId>awaitility</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.mockito</groupId>
-            <artifactId>mockito-core</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-</project>
diff --git a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/InVMEventBus.java b/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/InVMEventBus.java
deleted file mode 100644
index 1e92333..0000000
--- a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/InVMEventBus.java
+++ /dev/null
@@ -1,134 +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.mailbox.events;
-
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.inject.Inject;
-
-import org.apache.james.events.Event;
-import org.apache.james.events.EventBus;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.events.EventListener;
-import org.apache.james.events.Group;
-import org.apache.james.events.GroupAlreadyRegistered;
-import org.apache.james.events.GroupRegistrationNotFound;
-import org.apache.james.events.Registration;
-import org.apache.james.events.RegistrationKey;
-import org.apache.james.mailbox.events.delivery.EventDelivery;
-import org.apache.james.mailbox.events.delivery.EventDelivery.PermanentFailureHandler.StoreToDeadLetters;
-import org.apache.james.mailbox.events.delivery.EventDelivery.Retryer.BackoffRetryer;
-
-import com.github.steveash.guavate.Guavate;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multimaps;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-public class InVMEventBus implements EventBus {
-
-    private final Multimap<RegistrationKey, EventListener.ReactiveEventListener> registrations;
-    private final ConcurrentHashMap<Group, EventListener.ReactiveEventListener> groups;
-    private final EventDelivery eventDelivery;
-    private final RetryBackoffConfiguration retryBackoff;
-    private final EventDeadLetters eventDeadLetters;
-
-    @Inject
-    public InVMEventBus(EventDelivery eventDelivery, RetryBackoffConfiguration retryBackoff, EventDeadLetters eventDeadLetters) {
-        this.eventDelivery = eventDelivery;
-        this.retryBackoff = retryBackoff;
-        this.eventDeadLetters = eventDeadLetters;
-        this.registrations = Multimaps.synchronizedSetMultimap(HashMultimap.create());
-        this.groups = new ConcurrentHashMap<>();
-    }
-
-    @Override
-    public Mono<Registration> register(EventListener.ReactiveEventListener listener, RegistrationKey key) {
-        registrations.put(key, listener);
-        return Mono.just(() -> registrations.remove(key, listener));
-    }
-
-    @Override
-    public Registration register(EventListener.ReactiveEventListener listener, Group group) {
-        EventListener previous = groups.putIfAbsent(group, listener);
-        if (previous == null) {
-            return () -> groups.remove(group, listener);
-        }
-        throw new GroupAlreadyRegistered(group);
-    }
-
-    @Override
-    public Mono<Void> dispatch(Event event, Set<RegistrationKey> keys) {
-        if (!event.isNoop()) {
-            return Flux.merge(groupDeliveries(event), keyDeliveries(event, keys))
-                .then()
-                .onErrorResume(throwable -> Mono.empty());
-        }
-        return Mono.empty();
-    }
-
-    @Override
-    public Mono<Void> reDeliver(Group group, Event event) {
-        if (!event.isNoop()) {
-            return groupDelivery(event, retrieveListenerFromGroup(group), group);
-        }
-        return Mono.empty();
-    }
-
-    private EventListener.ReactiveEventListener retrieveListenerFromGroup(Group group) {
-        return Optional.ofNullable(groups.get(group))
-            .orElseThrow(() -> new GroupRegistrationNotFound(group));
-    }
-
-    private Mono<Void> keyDeliveries(Event event, Set<RegistrationKey> keys) {
-        return Flux.fromIterable(registeredListenersByKeys(keys))
-            .flatMap(listener -> eventDelivery.deliver(listener, event, EventDelivery.DeliveryOption.none()), EventBus.EXECUTION_RATE)
-            .then();
-    }
-
-    private Mono<Void> groupDeliveries(Event event) {
-        return Flux.fromIterable(groups.entrySet())
-            .flatMap(entry -> groupDelivery(event, entry.getValue(), entry.getKey()), EventBus.EXECUTION_RATE)
-            .then();
-    }
-
-    private Mono<Void> groupDelivery(Event event, EventListener.ReactiveEventListener mailboxListener, Group group) {
-        return eventDelivery.deliver(
-            mailboxListener,
-            event,
-            EventDelivery.DeliveryOption.of(
-                BackoffRetryer.of(retryBackoff, mailboxListener),
-                StoreToDeadLetters.of(group, eventDeadLetters)));
-    }
-
-    public Set<Group> registeredGroups() {
-        return groups.keySet();
-    }
-
-    private Set<EventListener.ReactiveEventListener> registeredListenersByKeys(Set<RegistrationKey> keys) {
-        return keys.stream()
-            .flatMap(registrationKey -> registrations.get(registrationKey).stream())
-            .collect(Guavate.toImmutableSet());
-    }
-}
diff --git a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/MemoryEventDeadLetters.java b/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/MemoryEventDeadLetters.java
deleted file mode 100644
index b11e26f..0000000
--- a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/MemoryEventDeadLetters.java
+++ /dev/null
@@ -1,95 +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.mailbox.events;
-
-import org.apache.james.events.Event;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.events.Group;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Table;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-public class MemoryEventDeadLetters implements EventDeadLetters {
-
-    private final Table<Group, InsertionId, Event> deadLetters;
-
-    public MemoryEventDeadLetters() {
-        this.deadLetters = HashBasedTable.create();
-    }
-
-    @Override
-    public Mono<InsertionId> store(Group registeredGroup, Event failDeliveredEvent) {
-        Preconditions.checkArgument(registeredGroup != null, REGISTERED_GROUP_CANNOT_BE_NULL);
-        Preconditions.checkArgument(failDeliveredEvent != null, FAIL_DELIVERED_EVENT_CANNOT_BE_NULL);
-
-        InsertionId insertionId = InsertionId.random();
-        synchronized (deadLetters) {
-            deadLetters.put(registeredGroup, insertionId, failDeliveredEvent);
-            return Mono.just(insertionId);
-        }
-    }
-
-    @Override
-    public Mono<Void> remove(Group registeredGroup, InsertionId failDeliveredInsertionId) {
-        Preconditions.checkArgument(registeredGroup != null, REGISTERED_GROUP_CANNOT_BE_NULL);
-        Preconditions.checkArgument(failDeliveredInsertionId != null, FAIL_DELIVERED_ID_INSERTION_CANNOT_BE_NULL);
-
-        synchronized (deadLetters) {
-            deadLetters.remove(registeredGroup, failDeliveredInsertionId);
-            return Mono.empty();
-        }
-    }
-
-    @Override
-    public Mono<Event> failedEvent(Group registeredGroup, InsertionId failDeliveredInsertionId) {
-        Preconditions.checkArgument(registeredGroup != null, REGISTERED_GROUP_CANNOT_BE_NULL);
-        Preconditions.checkArgument(failDeliveredInsertionId != null, FAIL_DELIVERED_ID_INSERTION_CANNOT_BE_NULL);
-
-        synchronized (deadLetters) {
-            return Mono.justOrEmpty(deadLetters.get(registeredGroup, failDeliveredInsertionId));
-        }
-    }
-
-    @Override
-    public Flux<InsertionId> failedIds(Group registeredGroup) {
-        Preconditions.checkArgument(registeredGroup != null, REGISTERED_GROUP_CANNOT_BE_NULL);
-
-        synchronized (deadLetters) {
-            return Flux.fromIterable(ImmutableList.copyOf(deadLetters.row(registeredGroup).keySet()));
-        }
-    }
-
-    @Override
-    public Flux<Group> groupsWithFailedEvents() {
-        synchronized (deadLetters) {
-            return Flux.fromIterable(ImmutableList.copyOf(deadLetters.rowKeySet()));
-        }
-    }
-
-    @Override
-    public Mono<Boolean> containEvents() {
-        return Mono.just(!deadLetters.isEmpty());
-    }
-}
diff --git a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/EventDelivery.java b/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/EventDelivery.java
deleted file mode 100644
index c0038ca..0000000
--- a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/EventDelivery.java
+++ /dev/null
@@ -1,134 +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.mailbox.events.delivery;
-
-import static org.apache.james.mailbox.events.delivery.EventDelivery.PermanentFailureHandler.NO_HANDLER;
-import static org.apache.james.mailbox.events.delivery.EventDelivery.Retryer.NO_RETRYER;
-
-import org.apache.james.events.Event;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.events.EventListener;
-import org.apache.james.events.Group;
-import org.apache.james.mailbox.events.RetryBackoffConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import reactor.core.publisher.Mono;
-import reactor.core.scheduler.Schedulers;
-import reactor.util.retry.Retry;
-
-public interface EventDelivery {
-
-    class DeliveryOption {
-        public static DeliveryOption of(Retryer retrier, PermanentFailureHandler permanentFailureHandler) {
-            return new DeliveryOption(retrier, permanentFailureHandler);
-        }
-
-        public static DeliveryOption none() {
-            return new DeliveryOption(NO_RETRYER, NO_HANDLER);
-        }
-
-        private final Retryer retrier;
-        private final PermanentFailureHandler permanentFailureHandler;
-
-        private DeliveryOption(Retryer retrier, PermanentFailureHandler permanentFailureHandler) {
-            this.retrier = retrier;
-            this.permanentFailureHandler = permanentFailureHandler;
-        }
-
-        Retryer getRetrier() {
-            return retrier;
-        }
-
-        PermanentFailureHandler getPermanentFailureHandler() {
-            return permanentFailureHandler;
-        }
-    }
-
-
-    interface Retryer {
-
-        Retryer NO_RETRYER = (executionResult, event) -> executionResult;
-
-        class BackoffRetryer implements EventDelivery.Retryer {
-
-            public static BackoffRetryer of(RetryBackoffConfiguration retryBackoff, EventListener mailboxListener) {
-                return new BackoffRetryer(retryBackoff, mailboxListener);
-            }
-
-            private static final Logger LOGGER = LoggerFactory.getLogger(BackoffRetryer.class);
-
-            private final RetryBackoffConfiguration retryBackoff;
-            private final EventListener mailboxListener;
-
-            public BackoffRetryer(RetryBackoffConfiguration retryBackoff, EventListener mailboxListener) {
-                this.retryBackoff = retryBackoff;
-                this.mailboxListener = mailboxListener;
-            }
-
-            @Override
-            public Mono<Void> doRetry(Mono<Void> executionResult, Event event) {
-                return executionResult
-                    .retryWhen(Retry.backoff(retryBackoff.getMaxRetries(), retryBackoff.getFirstBackoff()).jitter(retryBackoff.getJitterFactor()).scheduler(Schedulers.elastic()))
-                    .doOnError(throwable -> LOGGER.error("listener {} exceeded maximum retry({}) to handle event {}",
-                        mailboxListener.getClass().getCanonicalName(),
-                        retryBackoff.getMaxRetries(),
-                        event.getClass().getCanonicalName(),
-                        throwable))
-                    .then();
-            }
-        }
-
-        Mono<Void> doRetry(Mono<Void> executionResult, Event event);
-    }
-
-    interface PermanentFailureHandler {
-
-        PermanentFailureHandler NO_HANDLER = event -> Mono.error(new UnsupportedOperationException("doesn't handle error"));
-
-        class StoreToDeadLetters implements EventDelivery.PermanentFailureHandler {
-
-            public static StoreToDeadLetters of(Group group, EventDeadLetters eventDeadLetters) {
-                return new StoreToDeadLetters(group, eventDeadLetters);
-            }
-
-            private final Group group;
-            private final EventDeadLetters eventDeadLetters;
-
-            private StoreToDeadLetters(Group group, EventDeadLetters eventDeadLetters) {
-                this.group = group;
-                this.eventDeadLetters = eventDeadLetters;
-            }
-
-            @Override
-            public Mono<Void> handle(Event event) {
-                return eventDeadLetters.store(group, event).then();
-            }
-        }
-
-        Mono<Void> handle(Event event);
-    }
-
-    Mono<Void> deliver(EventListener.ReactiveEventListener listener, Event event, DeliveryOption option);
-
-    default Mono<Void> deliver(EventListener listener, Event event, DeliveryOption option) {
-        return deliver(EventListener.wrapReactive(listener), event, option);
-    }
-}
diff --git a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/InVmEventDelivery.java b/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/InVmEventDelivery.java
deleted file mode 100644
index e8ed94c..0000000
--- a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/InVmEventDelivery.java
+++ /dev/null
@@ -1,104 +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.mailbox.events.delivery;
-
-import static org.apache.james.events.EventBus.Metrics.timerName;
-import static org.apache.james.util.ReactorUtils.context;
-
-import javax.inject.Inject;
-
-import org.apache.james.events.Event;
-import org.apache.james.events.EventBus;
-import org.apache.james.events.EventListener;
-import org.apache.james.metrics.api.MetricFactory;
-import org.apache.james.util.MDCBuilder;
-import org.apache.james.util.MDCStructuredLogger;
-import org.apache.james.util.StructuredLogger;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.VisibleForTesting;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-public class InVmEventDelivery implements EventDelivery {
-    private static final Logger LOGGER = LoggerFactory.getLogger(InVmEventDelivery.class);
-
-    private final MetricFactory metricFactory;
-
-    @Inject
-    @VisibleForTesting
-    public InVmEventDelivery(MetricFactory metricFactory) {
-        this.metricFactory = metricFactory;
-    }
-
-    @Override
-    public Mono<Void> deliver(EventListener.ReactiveEventListener listener, Event event, DeliveryOption option) {
-        Mono<Void> executionResult = deliverByOption(listener, event, option);
-
-        return waitForResultIfNeeded(listener.getExecutionMode(), executionResult);
-    }
-
-    private Mono<Void> waitForResultIfNeeded(EventListener.ExecutionMode executionMode, Mono<Void> executionResult) {
-        if (executionMode.equals(EventListener.ExecutionMode.SYNCHRONOUS)) {
-            return executionResult;
-        }
-        return Flux.merge(executionResult, Mono.empty())
-            .publishNext()
-            .onErrorResume(throwable -> Mono.empty());
-    }
-
-    private Mono<Void> deliverByOption(EventListener.ReactiveEventListener listener, Event event, DeliveryOption deliveryOption) {
-        Mono<Void> deliveryToListener = doDeliverToListener(listener, event)
-            .doOnError(throwable -> structuredLogger(event, listener)
-                .log(logger -> logger.error("Error while processing listener", throwable)))
-            .then();
-
-        return deliveryOption.getRetrier().doRetry(deliveryToListener, event)
-            .onErrorResume(throwable -> deliveryOption.getPermanentFailureHandler().handle(event))
-            .then();
-    }
-
-    private Mono<Void> doDeliverToListener(EventListener.ReactiveEventListener mailboxListener, Event event) {
-        if (mailboxListener.isHandling(event)) {
-            return Mono.defer(() -> Mono.from(metricFactory.decoratePublisherWithTimerMetric(timerName(mailboxListener),
-                    mailboxListener.reactiveEvent(event))))
-                .subscriberContext(context("deliver", buildMDC(mailboxListener, event)));
-        }
-        return Mono.empty();
-    }
-
-    private MDCBuilder buildMDC(EventListener mailboxListener, Event event) {
-        return MDCBuilder.create()
-            .addContext(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
-            .addContext(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
-            .addContext(EventBus.StructuredLoggingFields.USER, event.getUsername())
-            .addContext(EventBus.StructuredLoggingFields.LISTENER_CLASS, mailboxListener.getClass());
-    }
-
-    private StructuredLogger structuredLogger(Event event, EventListener mailboxListener) {
-        return MDCStructuredLogger.forLogger(LOGGER)
-            .addField(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
-            .addField(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
-            .addField(EventBus.StructuredLoggingFields.USER, event.getUsername())
-            .addField(EventBus.StructuredLoggingFields.LISTENER_CLASS, mailboxListener.getClass());
-    }
-}
diff --git a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/InVMEventBusTest.java b/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/InVMEventBusTest.java
deleted file mode 100644
index c12963f..0000000
--- a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/InVMEventBusTest.java
+++ /dev/null
@@ -1,55 +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.mailbox.events;
-
-import org.apache.james.events.EventBus;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
-import org.apache.james.metrics.tests.RecordingMetricFactory;
-import org.junit.jupiter.api.BeforeEach;
-
-public class InVMEventBusTest implements KeyContract.SingleEventBusKeyContract, GroupContract.SingleEventBusGroupContract,
-    ErrorHandlingContract {
-
-    private InVMEventBus eventBus;
-    private MemoryEventDeadLetters deadLetters;
-
-    @BeforeEach
-    void setUp() {
-        deadLetters = new MemoryEventDeadLetters();
-        eventBus = new InVMEventBus(
-            new InVmEventDelivery(new RecordingMetricFactory()), EventBusTestFixture.RETRY_BACKOFF_CONFIGURATION, deadLetters);
-    }
-
-    @Override
-    public EnvironmentSpeedProfile getSpeedProfile() {
-        return EnvironmentSpeedProfile.FAST;
-    }
-
-    @Override
-    public EventBus eventBus() {
-        return eventBus;
-    }
-
-    @Override
-    public EventDeadLetters deadLetter() {
-        return deadLetters;
-    }
-}
\ No newline at end of file
diff --git a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersHealthCheckTest.java b/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersHealthCheckTest.java
deleted file mode 100644
index 58c4e7e..0000000
--- a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersHealthCheckTest.java
+++ /dev/null
@@ -1,59 +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.mailbox.events;
-
-import org.apache.commons.lang3.NotImplementedException;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.events.EventDeadLettersHealthCheck;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-
-public class MemoryEventDeadLettersHealthCheckTest implements EventDeadLettersHealthCheckContract {
-
-    private MemoryEventDeadLetters eventDeadLetters = new MemoryEventDeadLetters();
-    private EventDeadLettersHealthCheck testee = new EventDeadLettersHealthCheck(eventDeadLetters);
-
-    @Override
-    public EventDeadLettersHealthCheck testee() {
-        return testee;
-    }
-
-    @Override
-    public EventDeadLetters eventDeadLetters() {
-        return eventDeadLetters;
-    }
-
-    @Override
-    public void createErrorWhenDoingHealthCheck() {
-        throw new NotImplementedException("We can not instrument implementation this test case.");
-    }
-
-    @Override
-    public void resolveErrorWhenDoingHealthCheck() {
-        throw new NotImplementedException("We can not instrument implementation this test case.");
-    }
-
-    @Override
-    @Test
-    @Disabled("Unable to trigger the EventDeadLetter error with memory version")
-    public void checkShouldReturnUnHealthyWhenEventDeadLetterError() {
-
-    }
-}
diff --git a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersTest.java b/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersTest.java
deleted file mode 100644
index 43ae3df..0000000
--- a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersTest.java
+++ /dev/null
@@ -1,38 +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.mailbox.events;
-
-import org.apache.james.events.EventDeadLetters;
-import org.junit.jupiter.api.BeforeEach;
-
-class MemoryEventDeadLettersTest implements EventDeadLettersContract.AllContracts {
-
-    private MemoryEventDeadLetters eventDeadLetters;
-
-    @BeforeEach
-    void setUp() {
-        eventDeadLetters = new MemoryEventDeadLetters();
-    }
-
-    @Override
-    public EventDeadLetters eventDeadLetters() {
-        return eventDeadLetters;
-    }
-}
\ No newline at end of file
diff --git a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/delivery/InVmEventDeliveryTest.java b/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/delivery/InVmEventDeliveryTest.java
deleted file mode 100644
index 72f779a..0000000
--- a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/delivery/InVmEventDeliveryTest.java
+++ /dev/null
@@ -1,253 +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.mailbox.events.delivery;
-
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT;
-import static org.apache.james.mailbox.events.EventBusTestFixture.EventListenerCountingSuccessfulExecution;
-import static org.apache.james.mailbox.events.EventBusTestFixture.GROUP_A;
-import static org.apache.james.mailbox.events.delivery.EventDelivery.Retryer;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import java.time.Duration;
-
-import org.apache.james.events.EventListener;
-import org.apache.james.mailbox.events.MemoryEventDeadLetters;
-import org.apache.james.mailbox.events.RetryBackoffConfiguration;
-import org.apache.james.mailbox.events.delivery.EventDelivery.DeliveryOption;
-import org.apache.james.mailbox.events.delivery.EventDelivery.PermanentFailureHandler;
-import org.apache.james.mailbox.events.delivery.EventDelivery.Retryer.BackoffRetryer;
-import org.apache.james.metrics.tests.RecordingMetricFactory;
-import org.assertj.core.api.SoftAssertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-
-class InVmEventDeliveryTest {
-    private InVmEventDelivery inVmEventDelivery;
-    private EventListenerCountingSuccessfulExecution listener;
-
-    @BeforeEach
-    void setUp() {
-        listener = newListener();
-        inVmEventDelivery = new InVmEventDelivery(new RecordingMetricFactory());
-    }
-
-    EventListenerCountingSuccessfulExecution newListener() {
-        return spy(new EventListenerCountingSuccessfulExecution());
-    }
-
-    @Nested
-    class SynchronousListener {
-
-        @Test
-        void deliverShouldDeliverEvent() {
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
-            inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
-                .block();
-
-            assertThat(listener.numberOfEventCalls())
-                .isEqualTo(1);
-        }
-
-        @Test
-        void deliverShouldReturnSuccessSynchronousMono() {
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
-            assertThatCode(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
-                    .block())
-                .doesNotThrowAnyException();
-        }
-
-        @Test
-        void deliverShouldNotDeliverWhenListenerGetException() {
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
-            doThrow(new RuntimeException())
-                .when(listener).event(EVENT);
-
-            assertThatThrownBy(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
-                .block())
-            .isInstanceOf(RuntimeException.class);
-
-            assertThat(listener.numberOfEventCalls())
-                .isEqualTo(0);
-        }
-
-        @Test
-        void deliverShouldReturnAnErrorMonoWhenListenerGetException() {
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
-            doThrow(new RuntimeException())
-                .when(listener).event(EVENT);
-
-            assertThatThrownBy(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
-                .block())
-            .isInstanceOf(RuntimeException.class);
-        }
-    }
-
-    @Nested
-    class AsynchronousListener {
-
-        @Test
-        void deliverShouldDeliverEvent() {
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
-            inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
-                .block();
-
-            assertThat(listener.numberOfEventCalls())
-                .isEqualTo(1);
-        }
-
-        @Test
-        void deliverShouldReturnSuccessSynchronousMono() {
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
-            assertThatCode(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
-                    .block())
-                .doesNotThrowAnyException();
-        }
-
-        @Test
-        void deliverShouldNotFailWhenListenerGetException() {
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
-            doThrow(new RuntimeException())
-                .when(listener).event(EVENT);
-
-            assertThatCode(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
-                .block())
-            .doesNotThrowAnyException();
-        }
-
-        @Test
-        void deliverShouldReturnAnSuccessSyncMonoWhenListenerGetException() {
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
-            doThrow(new RuntimeException())
-                .when(listener).event(EVENT);
-
-            assertThatCode(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
-                .block())
-            .doesNotThrowAnyException();
-        }
-    }
-
-    @Nested
-    class WithOptions {
-
-        @Test
-        void retryShouldWorkWhenDeliverWithRetry() {
-            EventListenerCountingSuccessfulExecution listener = newListener();
-            doThrow(new RuntimeException())
-                .doThrow(new RuntimeException())
-                .doThrow(new RuntimeException())
-                .doCallRealMethod()
-                .when(listener).event(EVENT);
-
-            inVmEventDelivery.deliver(listener, EVENT,
-                DeliveryOption.of(
-                    BackoffRetryer.of(RetryBackoffConfiguration.DEFAULT, listener),
-                    PermanentFailureHandler.NO_HANDLER))
-                .block();
-
-            assertThat(listener.numberOfEventCalls())
-                .isEqualTo(1);
-        }
-
-        @Test
-        void failureHandlerShouldWorkWhenDeliverWithFailureHandler() {
-            EventListenerCountingSuccessfulExecution listener = newListener();
-            doThrow(new RuntimeException())
-                .when(listener).event(EVENT);
-
-            MemoryEventDeadLetters deadLetter = new MemoryEventDeadLetters();
-
-            inVmEventDelivery.deliver(listener, EVENT,
-                DeliveryOption.of(
-                    Retryer.NO_RETRYER,
-                    PermanentFailureHandler.StoreToDeadLetters.of(GROUP_A, deadLetter)))
-                .block();
-
-            assertThat(deadLetter.groupsWithFailedEvents().toStream())
-                .containsOnly(GROUP_A);
-        }
-
-        @Test
-        void failureHandlerShouldNotWorkWhenRetrySuccess() {
-            EventListenerCountingSuccessfulExecution listener = newListener();
-            doThrow(new RuntimeException())
-                .doThrow(new RuntimeException())
-                .doCallRealMethod()
-                .when(listener).event(EVENT);
-
-            MemoryEventDeadLetters deadLetter = new MemoryEventDeadLetters();
-
-            inVmEventDelivery.deliver(listener, EVENT,
-                DeliveryOption.of(
-                    BackoffRetryer.of(RetryBackoffConfiguration.DEFAULT, listener),
-                    PermanentFailureHandler.StoreToDeadLetters.of(GROUP_A, deadLetter)))
-                .block();
-
-            SoftAssertions.assertSoftly(softy -> {
-                softy.assertThat(listener.numberOfEventCalls())
-                    .isEqualTo(1);
-                softy.assertThat(deadLetter.groupsWithFailedEvents().toStream())
-                    .isEmpty();
-            });
-        }
-
-
-        @Test
-        void failureHandlerShouldWorkWhenRetryFails() {
-            EventListenerCountingSuccessfulExecution listener = newListener();
-            //do throw  RetryBackoffConfiguration.DEFAULT.DEFAULT_MAX_RETRIES + 1 times
-            doThrow(new RuntimeException())
-                .doThrow(new RuntimeException())
-                .doThrow(new RuntimeException())
-                .doThrow(new RuntimeException())
-                .doThrow(new RuntimeException())
-                .doThrow(new RuntimeException())
-                .doThrow(new RuntimeException())
-                .doThrow(new RuntimeException())
-                .doThrow(new RuntimeException())
-                .doCallRealMethod()
-                .when(listener).event(EVENT);
-
-            MemoryEventDeadLetters deadLetter = new MemoryEventDeadLetters();
-
-            inVmEventDelivery.deliver(listener, EVENT,
-                DeliveryOption.of(
-                    BackoffRetryer.of(RetryBackoffConfiguration.builder()
-                            .maxRetries(8)
-                            .firstBackoff(Duration.ofMillis(1))
-                            .jitterFactor(0.2)
-                            .build(), listener),
-                    PermanentFailureHandler.StoreToDeadLetters.of(GROUP_A, deadLetter)))
-                .block();
-
-            SoftAssertions.assertSoftly(softy -> {
-                softy.assertThat(listener.numberOfEventCalls())
-                    .isEqualTo(0);
-                assertThat(deadLetter.groupsWithFailedEvents().toStream())
-                    .containsOnly(GROUP_A);
-            });
-        }
-    }
-}
diff --git a/mailbox/event/event-rabbitmq/pom.xml b/mailbox/event/event-rabbitmq/pom.xml
index 693abc4..cdb79b3 100644
--- a/mailbox/event/event-rabbitmq/pom.xml
+++ b/mailbox/event/event-rabbitmq/pom.xml
@@ -34,11 +34,6 @@
     <dependencies>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>apache-james-mailbox-event-memory</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
             <artifactId>apache-james-mailbox-store</artifactId>
             <scope>test</scope>
         </dependency>
@@ -86,6 +81,11 @@
             <artifactId>apache-james-mailbox-event-json</artifactId>
         </dependency>
         <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-in-vm</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>metrics-api</artifactId>
         </dependency>
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/EventBusId.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/EventBusId.java
deleted file mode 100644
index eb6c812..0000000
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/EventBusId.java
+++ /dev/null
@@ -1,72 +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.mailbox.events;
-
-import java.util.Objects;
-import java.util.UUID;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Preconditions;
-
-public class EventBusId {
-    public static EventBusId of(UUID uuid) {
-        return new EventBusId(uuid);
-    }
-
-    public static EventBusId random() {
-        return new EventBusId(UUID.randomUUID());
-    }
-
-    public static EventBusId of(String serialized) {
-        return new EventBusId(UUID.fromString(serialized));
-    }
-
-    private final UUID id;
-
-    private EventBusId(UUID id) {
-        Preconditions.checkNotNull(id);
-        this.id = id;
-    }
-
-    @Override
-    public final boolean equals(Object o) {
-        if (o instanceof EventBusId) {
-            EventBusId eventBusId = (EventBusId) o;
-            return Objects.equals(this.id, eventBusId.id);
-        }
-        return false;
-    }
-
-    public String asString() {
-        return id.toString();
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(id);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(this)
-            .add("id", id)
-            .toString();
-    }
-}
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/EventDispatcher.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/EventDispatcher.java
deleted file mode 100644
index e7d1e62..0000000
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/EventDispatcher.java
+++ /dev/null
@@ -1,201 +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.mailbox.events;
-
-import static com.rabbitmq.client.MessageProperties.PERSISTENT_TEXT_PLAIN;
-import static org.apache.james.backends.rabbitmq.Constants.AUTO_DELETE;
-import static org.apache.james.backends.rabbitmq.Constants.DIRECT_EXCHANGE;
-import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
-import static org.apache.james.backends.rabbitmq.Constants.EMPTY_ROUTING_KEY;
-import static org.apache.james.backends.rabbitmq.Constants.EXCLUSIVE;
-import static org.apache.james.backends.rabbitmq.Constants.NO_ARGUMENTS;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.EVENT_BUS_ID;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT_DEAD_LETTER_EXCHANGE_NAME;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT_DEAD_LETTER_QUEUE;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Set;
-
-import org.apache.james.event.json.EventSerializer;
-import org.apache.james.events.Event;
-import org.apache.james.events.EventBus;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.events.EventListener;
-import org.apache.james.events.Group;
-import org.apache.james.events.RegistrationKey;
-import org.apache.james.mailbox.events.RoutingKeyConverter.RoutingKey;
-import org.apache.james.util.MDCBuilder;
-import org.apache.james.util.MDCStructuredLogger;
-import org.apache.james.util.StructuredLogger;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.github.steveash.guavate.Guavate;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.rabbitmq.client.AMQP;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-import reactor.core.publisher.MonoProcessor;
-import reactor.rabbitmq.BindingSpecification;
-import reactor.rabbitmq.ExchangeSpecification;
-import reactor.rabbitmq.OutboundMessage;
-import reactor.rabbitmq.QueueSpecification;
-import reactor.rabbitmq.Sender;
-import reactor.util.function.Tuples;
-
-public class EventDispatcher {
-    public static class DispatchingFailureGroup extends Group {
-        public static DispatchingFailureGroup INSTANCE = new DispatchingFailureGroup();
-    }
-
-    private static final Logger LOGGER = LoggerFactory.getLogger(EventDispatcher.class);
-
-    private final EventSerializer eventSerializer;
-    private final Sender sender;
-    private final LocalListenerRegistry localListenerRegistry;
-    private final AMQP.BasicProperties basicProperties;
-    private final MailboxListenerExecutor mailboxListenerExecutor;
-    private final EventDeadLetters deadLetters;
-
-    EventDispatcher(EventBusId eventBusId, EventSerializer eventSerializer, Sender sender,
-                    LocalListenerRegistry localListenerRegistry,
-                    MailboxListenerExecutor mailboxListenerExecutor,
-                    EventDeadLetters deadLetters) {
-        this.eventSerializer = eventSerializer;
-        this.sender = sender;
-        this.localListenerRegistry = localListenerRegistry;
-        this.basicProperties = new AMQP.BasicProperties.Builder()
-            .headers(ImmutableMap.of(EVENT_BUS_ID, eventBusId.asString()))
-            .deliveryMode(PERSISTENT_TEXT_PLAIN.getDeliveryMode())
-            .priority(PERSISTENT_TEXT_PLAIN.getPriority())
-            .contentType(PERSISTENT_TEXT_PLAIN.getContentType())
-            .build();
-        this.mailboxListenerExecutor = mailboxListenerExecutor;
-        this.deadLetters = deadLetters;
-    }
-
-    void start() {
-        Flux.concat(
-            sender.declareExchange(ExchangeSpecification.exchange(MAILBOX_EVENT_EXCHANGE_NAME)
-                .durable(DURABLE)
-                .type(DIRECT_EXCHANGE)),
-            sender.declareExchange(ExchangeSpecification.exchange(MAILBOX_EVENT_DEAD_LETTER_EXCHANGE_NAME)
-                .durable(DURABLE)
-                .type(DIRECT_EXCHANGE)),
-            sender.declareQueue(QueueSpecification.queue(MAILBOX_EVENT_DEAD_LETTER_QUEUE)
-                .durable(DURABLE)
-                .exclusive(!EXCLUSIVE)
-                .autoDelete(!AUTO_DELETE)
-                .arguments(NO_ARGUMENTS)),
-            sender.bind(BindingSpecification.binding()
-                .exchange(MAILBOX_EVENT_DEAD_LETTER_EXCHANGE_NAME)
-                .queue(MAILBOX_EVENT_DEAD_LETTER_QUEUE)
-                .routingKey(EMPTY_ROUTING_KEY)))
-            .then()
-            .block();
-    }
-
-    Mono<Void> dispatch(Event event, Set<RegistrationKey> keys) {
-        return Flux
-            .concat(
-                dispatchToLocalListeners(event, keys),
-                dispatchToRemoteListeners(event, keys))
-            .doOnError(throwable -> LOGGER.error("error while dispatching event", throwable))
-            .then()
-            .subscribeWith(MonoProcessor.create());
-    }
-
-    private Mono<Void> dispatchToLocalListeners(Event event, Set<RegistrationKey> keys) {
-        return Flux.fromIterable(keys)
-            .flatMap(key -> localListenerRegistry.getLocalMailboxListeners(key)
-                .map(listener -> Tuples.of(key, listener)), EventBus.EXECUTION_RATE)
-            .filter(pair -> pair.getT2().getExecutionMode() == EventListener.ExecutionMode.SYNCHRONOUS)
-            .flatMap(pair -> executeListener(event, pair.getT2(), pair.getT1()), EventBus.EXECUTION_RATE)
-            .then();
-    }
-
-    private Mono<Void> executeListener(Event event, EventListener.ReactiveEventListener mailboxListener, RegistrationKey registrationKey) {
-        return mailboxListenerExecutor.execute(mailboxListener,
-                    MDCBuilder.create()
-                        .addContext(EventBus.StructuredLoggingFields.REGISTRATION_KEY, registrationKey),
-                    event)
-            .onErrorResume(e -> {
-                structuredLogger(event, ImmutableSet.of(registrationKey))
-                    .log(logger -> logger.error("Exception happens when dispatching event", e));
-                return Mono.empty();
-            });
-    }
-
-    private StructuredLogger structuredLogger(Event event, Set<RegistrationKey> keys) {
-        return MDCStructuredLogger.forLogger(LOGGER)
-            .addField(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
-            .addField(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
-            .addField(EventBus.StructuredLoggingFields.USER, event.getUsername())
-            .addField(EventBus.StructuredLoggingFields.REGISTRATION_KEYS, keys);
-    }
-
-    private Mono<Void> dispatchToRemoteListeners(Event event, Set<RegistrationKey> keys) {
-        return Mono.fromCallable(() -> serializeEvent(event))
-            .flatMap(serializedEvent -> Mono.zipDelayError(
-                remoteGroupsDispatch(serializedEvent, event),
-                remoteKeysDispatch(serializedEvent, keys)))
-            .then();
-    }
-
-    private Mono<Void> remoteGroupsDispatch(byte[] serializedEvent, Event event) {
-        return remoteDispatch(serializedEvent, Collections.singletonList(RoutingKey.empty()))
-            .doOnError(ex -> LOGGER.error(
-                "cannot dispatch event of type '{}' belonging '{}' with id '{}' to remote groups, store it into dead letter",
-                event.getClass().getSimpleName(),
-                event.getUsername().asString(),
-                event.getEventId().getId(),
-                ex))
-            .onErrorResume(ex -> deadLetters.store(DispatchingFailureGroup.INSTANCE, event)
-                .then(Mono.error(ex)));
-    }
-
-    private Mono<Void> remoteKeysDispatch(byte[] serializedEvent, Set<RegistrationKey> keys) {
-        return remoteDispatch(serializedEvent,
-            keys.stream()
-                .map(RoutingKey::of)
-                .collect(Guavate.toImmutableList()));
-    }
-
-    private Mono<Void> remoteDispatch(byte[] serializedEvent, Collection<RoutingKey> routingKeys) {
-        if (routingKeys.isEmpty()) {
-            return Mono.empty();
-        }
-        return sender.send(toMessages(serializedEvent, routingKeys));
-    }
-
-    private Flux<OutboundMessage> toMessages(byte[] serializedEvent, Collection<RoutingKey> routingKeys) {
-        return Flux.fromIterable(routingKeys)
-                .map(routingKey -> new OutboundMessage(MAILBOX_EVENT_EXCHANGE_NAME, routingKey.asString(), basicProperties, serializedEvent));
-    }
-
-    private byte[] serializeEvent(Event event) {
-        return eventSerializer.toJson(event).getBytes(StandardCharsets.UTF_8);
-    }
-}
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupConsumerRetry.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupConsumerRetry.java
deleted file mode 100644
index d74cc64..0000000
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupConsumerRetry.java
+++ /dev/null
@@ -1,145 +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.mailbox.events;
-
-import static com.rabbitmq.client.MessageProperties.PERSISTENT_TEXT_PLAIN;
-import static org.apache.james.backends.rabbitmq.Constants.DIRECT_EXCHANGE;
-import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
-import static org.apache.james.backends.rabbitmq.Constants.EMPTY_ROUTING_KEY;
-import static org.apache.james.mailbox.events.GroupRegistration.RETRY_COUNT;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT;
-
-import java.nio.charset.StandardCharsets;
-
-import org.apache.james.event.json.EventSerializer;
-import org.apache.james.events.Event;
-import org.apache.james.events.EventBus;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.events.Group;
-import org.apache.james.util.MDCStructuredLogger;
-import org.apache.james.util.StructuredLogger;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableMap;
-import com.rabbitmq.client.AMQP;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-import reactor.rabbitmq.BindingSpecification;
-import reactor.rabbitmq.ExchangeSpecification;
-import reactor.rabbitmq.OutboundMessage;
-import reactor.rabbitmq.Sender;
-
-class GroupConsumerRetry {
-
-    static class RetryExchangeName {
-        static RetryExchangeName of(Group group) {
-            return new RetryExchangeName(group.asString());
-        }
-
-        static final String MAILBOX_EVENT_RETRY_EXCHANGE_PREFIX = MAILBOX_EVENT + "-retryExchange-";
-
-        private final String name;
-
-        private RetryExchangeName(String name) {
-            Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "Exchange name must be specified");
-            this.name = name;
-        }
-
-        String asString() {
-            return MAILBOX_EVENT_RETRY_EXCHANGE_PREFIX + name;
-        }
-    }
-
-    private static final Logger LOGGER = LoggerFactory.getLogger(GroupConsumerRetry.class);
-
-    private final Sender sender;
-    private final RetryExchangeName retryExchangeName;
-    private final RetryBackoffConfiguration retryBackoff;
-    private final EventDeadLetters eventDeadLetters;
-    private final Group group;
-    private final EventSerializer eventSerializer;
-
-    GroupConsumerRetry(Sender sender, Group group, RetryBackoffConfiguration retryBackoff,
-                       EventDeadLetters eventDeadLetters, EventSerializer eventSerializer) {
-        this.sender = sender;
-        this.retryExchangeName = RetryExchangeName.of(group);
-        this.retryBackoff = retryBackoff;
-        this.eventDeadLetters = eventDeadLetters;
-        this.group = group;
-        this.eventSerializer = eventSerializer;
-    }
-
-    Mono<Void> createRetryExchange(GroupRegistration.WorkQueueName queueName) {
-        return Flux.concat(
-            sender.declareExchange(ExchangeSpecification.exchange(retryExchangeName.asString())
-                .durable(DURABLE)
-                .type(DIRECT_EXCHANGE)),
-            sender.bind(BindingSpecification.binding()
-                .exchange(retryExchangeName.asString())
-                .queue(queueName.asString())
-                .routingKey(EMPTY_ROUTING_KEY)))
-            .then();
-    }
-
-    Mono<Void> handleRetry(Event event, int currentRetryCount, Throwable throwable) {
-        createStructuredLogger(event).log(logger -> logger.error("Exception happens when handling event after {} retries", currentRetryCount, throwable));
-
-        return retryOrStoreToDeadLetter(event, currentRetryCount);
-    }
-
-    Mono<Void> retryOrStoreToDeadLetter(Event event, int currentRetryCount) {
-        if (currentRetryCount >= retryBackoff.getMaxRetries()) {
-            return eventDeadLetters.store(group, event).then();
-        }
-        return sendRetryMessage(event, currentRetryCount);
-    }
-
-    private Mono<Void> sendRetryMessage(Event event, int currentRetryCount) {
-        byte[] eventAsBytes = eventSerializer.toJson(event).getBytes(StandardCharsets.UTF_8);
-
-        Mono<OutboundMessage> retryMessage = Mono.just(new OutboundMessage(
-            retryExchangeName.asString(),
-            EMPTY_ROUTING_KEY,
-            new AMQP.BasicProperties.Builder()
-                .headers(ImmutableMap.of(RETRY_COUNT, currentRetryCount + 1))
-                .deliveryMode(PERSISTENT_TEXT_PLAIN.getDeliveryMode())
-                .priority(PERSISTENT_TEXT_PLAIN.getPriority())
-                .contentType(PERSISTENT_TEXT_PLAIN.getContentType())
-                .build(),
-            eventAsBytes));
-
-        return sender.send(retryMessage)
-            .doOnError(throwable -> createStructuredLogger(event)
-                .log(logger -> logger.error("Exception happens when publishing event to retry exchange, this event will be stored in deadLetter", throwable)))
-            .onErrorResume(e -> eventDeadLetters.store(group, event).then());
-    }
-
-    private StructuredLogger createStructuredLogger(Event event) {
-        return MDCStructuredLogger.forLogger(LOGGER)
-            .addField(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
-            .addField(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
-            .addField(EventBus.StructuredLoggingFields.USER, event.getUsername())
-            .addField(EventBus.StructuredLoggingFields.GROUP, group.asString());
-    }
-}
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistration.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistration.java
deleted file mode 100644
index e07d6a7..0000000
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistration.java
+++ /dev/null
@@ -1,198 +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.mailbox.events;
-
-import static org.apache.james.backends.rabbitmq.Constants.AUTO_DELETE;
-import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
-import static org.apache.james.backends.rabbitmq.Constants.EMPTY_ROUTING_KEY;
-import static org.apache.james.backends.rabbitmq.Constants.EXCLUSIVE;
-import static org.apache.james.backends.rabbitmq.Constants.REQUEUE;
-import static org.apache.james.backends.rabbitmq.Constants.deadLetterQueue;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT_DEAD_LETTER_EXCHANGE_NAME;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.function.Predicate;
-
-import org.apache.james.backends.rabbitmq.ReactorRabbitMQChannelPool;
-import org.apache.james.backends.rabbitmq.ReceiverProvider;
-import org.apache.james.event.json.EventSerializer;
-import org.apache.james.events.Event;
-import org.apache.james.events.EventBus;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.events.EventListener;
-import org.apache.james.events.Group;
-import org.apache.james.events.Registration;
-import org.apache.james.util.MDCBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-import reactor.core.Disposable;
-import reactor.core.publisher.Mono;
-import reactor.core.scheduler.Schedulers;
-import reactor.rabbitmq.AcknowledgableDelivery;
-import reactor.rabbitmq.BindingSpecification;
-import reactor.rabbitmq.ConsumeOptions;
-import reactor.rabbitmq.QueueSpecification;
-import reactor.rabbitmq.Receiver;
-import reactor.rabbitmq.Sender;
-import reactor.util.retry.Retry;
-
-class GroupRegistration implements Registration {
-    static class WorkQueueName {
-        static WorkQueueName of(Group group) {
-            return new WorkQueueName(group);
-        }
-
-        static final String MAILBOX_EVENT_WORK_QUEUE_PREFIX = MAILBOX_EVENT + "-workQueue-";
-
-        private final Group group;
-
-        private WorkQueueName(Group group) {
-            Preconditions.checkNotNull(group, "Group must be specified");
-            this.group = group;
-        }
-
-        String asString() {
-            return MAILBOX_EVENT_WORK_QUEUE_PREFIX + group.asString();
-        }
-    }
-
-    private static final Logger LOGGER = LoggerFactory.getLogger(GroupRegistration.class);
-    static final String RETRY_COUNT = "retry-count";
-    static final int DEFAULT_RETRY_COUNT = 0;
-
-    private final ReactorRabbitMQChannelPool channelPool;
-    private final EventListener.ReactiveEventListener mailboxListener;
-    private final WorkQueueName queueName;
-    private final Receiver receiver;
-    private final Runnable unregisterGroup;
-    private final Sender sender;
-    private final EventSerializer eventSerializer;
-    private final GroupConsumerRetry retryHandler;
-    private final WaitDelayGenerator delayGenerator;
-    private final Group group;
-    private final RetryBackoffConfiguration retryBackoff;
-    private final MailboxListenerExecutor mailboxListenerExecutor;
-    private Optional<Disposable> receiverSubscriber;
-
-    GroupRegistration(ReactorRabbitMQChannelPool channelPool, Sender sender, ReceiverProvider receiverProvider, EventSerializer eventSerializer,
-                      EventListener.ReactiveEventListener mailboxListener, Group group, RetryBackoffConfiguration retryBackoff,
-                      EventDeadLetters eventDeadLetters,
-                      Runnable unregisterGroup, MailboxListenerExecutor mailboxListenerExecutor) {
-        this.channelPool = channelPool;
-        this.eventSerializer = eventSerializer;
-        this.mailboxListener = mailboxListener;
-        this.queueName = WorkQueueName.of(group);
-        this.sender = sender;
-        this.receiver = receiverProvider.createReceiver();
-        this.retryBackoff = retryBackoff;
-        this.mailboxListenerExecutor = mailboxListenerExecutor;
-        this.receiverSubscriber = Optional.empty();
-        this.unregisterGroup = unregisterGroup;
-        this.retryHandler = new GroupConsumerRetry(sender, group, retryBackoff, eventDeadLetters, eventSerializer);
-        this.delayGenerator = WaitDelayGenerator.of(retryBackoff);
-        this.group = group;
-    }
-
-    GroupRegistration start() {
-        receiverSubscriber = Optional
-            .of(createGroupWorkQueue()
-                .then(retryHandler.createRetryExchange(queueName))
-                .then(Mono.fromCallable(() -> this.consumeWorkQueue()))
-                .retryWhen(Retry.backoff(retryBackoff.getMaxRetries(), retryBackoff.getFirstBackoff()).jitter(retryBackoff.getJitterFactor()).scheduler(Schedulers.elastic()))
-                .block());
-        return this;
-    }
-
-    private Mono<Void> createGroupWorkQueue() {
-        return channelPool.createWorkQueue(
-            QueueSpecification.queue(queueName.asString())
-                .durable(DURABLE)
-                .exclusive(!EXCLUSIVE)
-                .autoDelete(!AUTO_DELETE)
-                .arguments(deadLetterQueue(MAILBOX_EVENT_DEAD_LETTER_EXCHANGE_NAME)),
-            BindingSpecification.binding()
-                .exchange(MAILBOX_EVENT_EXCHANGE_NAME)
-                .queue(queueName.asString())
-                .routingKey(EMPTY_ROUTING_KEY));
-    }
-
-    private Disposable consumeWorkQueue() {
-        return receiver.consumeManualAck(queueName.asString(), new ConsumeOptions().qos(EventBus.EXECUTION_RATE))
-            .publishOn(Schedulers.parallel())
-            .filter(delivery -> Objects.nonNull(delivery.getBody()))
-            .flatMap(this::deliver, EventBus.EXECUTION_RATE)
-            .subscribe();
-    }
-
-    private Mono<Void> deliver(AcknowledgableDelivery acknowledgableDelivery) {
-        byte[] eventAsBytes = acknowledgableDelivery.getBody();
-        int currentRetryCount = getRetryCount(acknowledgableDelivery);
-
-        return deserializeEvent(eventAsBytes)
-            .flatMap(event -> delayGenerator.delayIfHaveTo(currentRetryCount)
-                .flatMap(any -> runListener(event))
-                .onErrorResume(throwable -> retryHandler.handleRetry(event, currentRetryCount, throwable))
-                .then(Mono.<Void>fromRunnable(acknowledgableDelivery::ack)))
-            .onErrorResume(e -> {
-                LOGGER.error("Unable to process delivery for group {}", group, e);
-                return Mono.fromRunnable(() -> acknowledgableDelivery.nack(!REQUEUE));
-            });
-    }
-
-    private Mono<Event> deserializeEvent(byte[] eventAsBytes) {
-        return Mono.fromCallable(() -> eventSerializer.fromJson(new String(eventAsBytes, StandardCharsets.UTF_8)).get())
-            .subscribeOn(Schedulers.parallel());
-    }
-
-    Mono<Void> reDeliver(Event event) {
-        return retryHandler.retryOrStoreToDeadLetter(event, DEFAULT_RETRY_COUNT);
-    }
-
-    private Mono<Void> runListener(Event event) {
-        return mailboxListenerExecutor.execute(
-            mailboxListener,
-            MDCBuilder.create()
-                .addContext(EventBus.StructuredLoggingFields.GROUP, group),
-            event);
-    }
-
-    private int getRetryCount(AcknowledgableDelivery acknowledgableDelivery) {
-        return Optional.ofNullable(acknowledgableDelivery.getProperties().getHeaders())
-            .flatMap(headers -> Optional.ofNullable(headers.get(RETRY_COUNT)))
-            .filter(object -> object instanceof Integer)
-            .map(Integer.class::cast)
-            .orElse(DEFAULT_RETRY_COUNT);
-    }
-
-    @Override
-    public void unregister() {
-        receiverSubscriber.filter(Predicate.not(Disposable::isDisposed))
-            .ifPresent(Disposable::dispose);
-        receiver.close();
-        unregisterGroup.run();
-    }
-}
\ No newline at end of file
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistrationHandler.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistrationHandler.java
deleted file mode 100644
index 950ac44..0000000
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistrationHandler.java
+++ /dev/null
@@ -1,93 +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.mailbox.events;
-
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.james.backends.rabbitmq.ReactorRabbitMQChannelPool;
-import org.apache.james.backends.rabbitmq.ReceiverProvider;
-import org.apache.james.event.json.EventSerializer;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.events.EventListener;
-import org.apache.james.events.Group;
-import org.apache.james.events.GroupAlreadyRegistered;
-import org.apache.james.events.GroupRegistrationNotFound;
-import org.apache.james.events.Registration;
-
-import reactor.rabbitmq.Sender;
-
-class GroupRegistrationHandler {
-    private final Map<Group, GroupRegistration> groupRegistrations;
-    private final EventSerializer eventSerializer;
-    private final ReactorRabbitMQChannelPool channelPool;
-    private final Sender sender;
-    private final ReceiverProvider receiverProvider;
-    private final RetryBackoffConfiguration retryBackoff;
-    private final EventDeadLetters eventDeadLetters;
-    private final MailboxListenerExecutor mailboxListenerExecutor;
-
-    GroupRegistrationHandler(EventSerializer eventSerializer, ReactorRabbitMQChannelPool channelPool, Sender sender, ReceiverProvider receiverProvider,
-                             RetryBackoffConfiguration retryBackoff,
-                             EventDeadLetters eventDeadLetters, MailboxListenerExecutor mailboxListenerExecutor) {
-        this.eventSerializer = eventSerializer;
-        this.channelPool = channelPool;
-        this.sender = sender;
-        this.receiverProvider = receiverProvider;
-        this.retryBackoff = retryBackoff;
-        this.eventDeadLetters = eventDeadLetters;
-        this.mailboxListenerExecutor = mailboxListenerExecutor;
-        this.groupRegistrations = new ConcurrentHashMap<>();
-    }
-
-    GroupRegistration retrieveGroupRegistration(Group group) {
-        return Optional.ofNullable(groupRegistrations.get(group))
-            .orElseThrow(() -> new GroupRegistrationNotFound(group));
-    }
-
-    void stop() {
-        groupRegistrations.values().forEach(GroupRegistration::unregister);
-    }
-
-    Registration register(EventListener.ReactiveEventListener listener, Group group) {
-        return groupRegistrations
-            .compute(group, (groupToRegister, oldGroupRegistration) -> {
-                if (oldGroupRegistration != null) {
-                    throw new GroupAlreadyRegistered(group);
-                }
-                return newGroupRegistration(listener, groupToRegister);
-            })
-            .start();
-    }
-
-    private GroupRegistration newGroupRegistration(EventListener.ReactiveEventListener listener, Group group) {
-        return new GroupRegistration(
-            channelPool, sender,
-            receiverProvider,
-            eventSerializer,
-            listener,
-            group,
-            retryBackoff,
-            eventDeadLetters,
-            () -> groupRegistrations.remove(group),
-            mailboxListenerExecutor);
-    }
-}
\ No newline at end of file
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyReconnectionHandler.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyReconnectionHandler.java
deleted file mode 100644
index a8162d0..0000000
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyReconnectionHandler.java
+++ /dev/null
@@ -1,60 +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.mailbox.events;
-
-import static org.apache.james.backends.rabbitmq.Constants.AUTO_DELETE;
-import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
-import static org.apache.james.backends.rabbitmq.Constants.EXCLUSIVE;
-import static org.apache.james.mailbox.events.KeyRegistrationHandler.EVENTBUS_QUEUE_NAME_PREFIX;
-import static org.apache.james.mailbox.events.KeyRegistrationHandler.QUEUE_ARGUMENTS;
-
-import javax.inject.Inject;
-
-import org.apache.james.backends.rabbitmq.SimpleConnectionPool;
-import org.reactivestreams.Publisher;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.rabbitmq.client.Channel;
-import com.rabbitmq.client.Connection;
-
-import reactor.core.publisher.Mono;
-
-public class KeyReconnectionHandler implements SimpleConnectionPool.ReconnectionHandler {
-    private static final Logger LOGGER = LoggerFactory.getLogger(KeyReconnectionHandler.class);
-
-    private final EventBusId eventBusId;
-
-    @Inject
-    public KeyReconnectionHandler(EventBusId eventBusId) {
-        this.eventBusId = eventBusId;
-    }
-
-    @Override
-    public Publisher<Void> handleReconnection(Connection connection) {
-        return Mono.fromRunnable(() -> {
-            try (Channel channel = connection.createChannel()) {
-                channel.queueDeclare(EVENTBUS_QUEUE_NAME_PREFIX + eventBusId.asString(), DURABLE, !EXCLUSIVE, AUTO_DELETE, QUEUE_ARGUMENTS);
-            } catch (Exception e) {
-                LOGGER.error("Error recovering connection", e);
-            }
-        });
-    }
-}
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistration.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistration.java
deleted file mode 100644
index be1f399..0000000
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistration.java
+++ /dev/null
@@ -1,35 +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.mailbox.events;
-
-import org.apache.james.events.Registration;
-
-class KeyRegistration implements Registration {
-    private final Runnable unregister;
-
-    KeyRegistration(Runnable unregister) {
-        this.unregister = unregister;
-    }
-
-    @Override
-    public void unregister() {
-        unregister.run();
-    }
-}
\ No newline at end of file
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistrationHandler.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistrationHandler.java
deleted file mode 100644
index 0731ca8..0000000
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistrationHandler.java
+++ /dev/null
@@ -1,204 +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.mailbox.events;
-
-import static org.apache.james.backends.rabbitmq.Constants.AUTO_DELETE;
-import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
-import static org.apache.james.backends.rabbitmq.Constants.EXCLUSIVE;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.EVENT_BUS_ID;
-
-import java.nio.charset.StandardCharsets;
-import java.time.Duration;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Predicate;
-
-import org.apache.james.backends.rabbitmq.ReceiverProvider;
-import org.apache.james.event.json.EventSerializer;
-import org.apache.james.events.Event;
-import org.apache.james.events.EventBus;
-import org.apache.james.events.EventListener;
-import org.apache.james.events.Registration;
-import org.apache.james.events.RegistrationKey;
-import org.apache.james.util.MDCBuilder;
-import org.apache.james.util.MDCStructuredLogger;
-import org.apache.james.util.StructuredLogger;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableMap;
-import com.rabbitmq.client.AMQP;
-import com.rabbitmq.client.Delivery;
-
-import reactor.core.Disposable;
-import reactor.core.publisher.Mono;
-import reactor.core.scheduler.Schedulers;
-import reactor.rabbitmq.ConsumeOptions;
-import reactor.rabbitmq.QueueSpecification;
-import reactor.rabbitmq.Receiver;
-import reactor.rabbitmq.Sender;
-import reactor.util.retry.Retry;
-
-class KeyRegistrationHandler {
-    private static final Logger LOGGER = LoggerFactory.getLogger(KeyRegistrationHandler.class);
-    static final String EVENTBUS_QUEUE_NAME_PREFIX = "eventbus-";
-    private static final Duration EXPIRATION_TIMEOUT = Duration.ofMinutes(30);
-    static final Map<String, Object> QUEUE_ARGUMENTS = ImmutableMap.of("x-expires", EXPIRATION_TIMEOUT.toMillis());
-
-    private static final Duration TOPOLOGY_CHANGES_TIMEOUT = Duration.ofMinutes(1);
-
-    private final EventBusId eventBusId;
-    private final LocalListenerRegistry localListenerRegistry;
-    private final EventSerializer eventSerializer;
-    private final Sender sender;
-    private final RoutingKeyConverter routingKeyConverter;
-    private final Receiver receiver;
-    private final RegistrationQueueName registrationQueue;
-    private final RegistrationBinder registrationBinder;
-    private final MailboxListenerExecutor mailboxListenerExecutor;
-    private final RetryBackoffConfiguration retryBackoff;
-    private Optional<Disposable> receiverSubscriber;
-
-    KeyRegistrationHandler(EventBusId eventBusId, EventSerializer eventSerializer,
-                           Sender sender, ReceiverProvider receiverProvider,
-                           RoutingKeyConverter routingKeyConverter, LocalListenerRegistry localListenerRegistry,
-                           MailboxListenerExecutor mailboxListenerExecutor, RetryBackoffConfiguration retryBackoff) {
-        this.eventBusId = eventBusId;
-        this.eventSerializer = eventSerializer;
-        this.sender = sender;
-        this.routingKeyConverter = routingKeyConverter;
-        this.localListenerRegistry = localListenerRegistry;
-        this.receiver = receiverProvider.createReceiver();
-        this.mailboxListenerExecutor = mailboxListenerExecutor;
-        this.retryBackoff = retryBackoff;
-        this.registrationQueue = new RegistrationQueueName(EVENTBUS_QUEUE_NAME_PREFIX + eventBusId.asString());
-        this.registrationBinder = new RegistrationBinder(sender, registrationQueue);
-        this.receiverSubscriber = Optional.empty();
-
-    }
-
-    void start() {
-        declareQueue();
-
-        receiverSubscriber = Optional.of(receiver.consumeAutoAck(registrationQueue.asString(), new ConsumeOptions().qos(EventBus.EXECUTION_RATE))
-            .subscribeOn(Schedulers.parallel())
-            .flatMap(this::handleDelivery, EventBus.EXECUTION_RATE)
-            .subscribe());
-    }
-
-    @VisibleForTesting
-    void declareQueue() {
-        declareQueue(sender);
-    }
-
-    private void declareQueue(Sender sender) {
-        sender.declareQueue(
-            QueueSpecification.queue(EVENTBUS_QUEUE_NAME_PREFIX + eventBusId.asString())
-                .durable(DURABLE)
-                .exclusive(!EXCLUSIVE)
-                .autoDelete(AUTO_DELETE)
-                .arguments(QUEUE_ARGUMENTS))
-            .timeout(TOPOLOGY_CHANGES_TIMEOUT)
-            .map(AMQP.Queue.DeclareOk::getQueue)
-            .retryWhen(Retry.backoff(retryBackoff.getMaxRetries(), retryBackoff.getFirstBackoff()).jitter(retryBackoff.getJitterFactor()))
-            .block();
-    }
-
-    void stop() {
-        sender.delete(QueueSpecification.queue(registrationQueue.asString()))
-            .timeout(TOPOLOGY_CHANGES_TIMEOUT)
-            .retryWhen(Retry.backoff(retryBackoff.getMaxRetries(), retryBackoff.getFirstBackoff()).jitter(retryBackoff.getJitterFactor()).scheduler(Schedulers.elastic()))
-            .block();
-        receiverSubscriber.filter(Predicate.not(Disposable::isDisposed))
-                .ifPresent(Disposable::dispose);
-        receiver.close();
-    }
-
-    Mono<Registration> register(EventListener.ReactiveEventListener listener, RegistrationKey key) {
-        LocalListenerRegistry.LocalRegistration registration = localListenerRegistry.addListener(key, listener);
-
-        return registerIfNeeded(key, registration)
-            .thenReturn(new KeyRegistration(() -> {
-                if (registration.unregister().lastListenerRemoved()) {
-                    registrationBinder.unbind(key)
-                        .timeout(TOPOLOGY_CHANGES_TIMEOUT)
-                        .retryWhen(Retry.backoff(retryBackoff.getMaxRetries(), retryBackoff.getFirstBackoff()).jitter(retryBackoff.getJitterFactor()).scheduler(Schedulers.elastic()))
-                        .subscribeOn(Schedulers.elastic())
-                        .block();
-                }
-            }));
-    }
-
-    private Mono<Void> registerIfNeeded(RegistrationKey key, LocalListenerRegistry.LocalRegistration registration) {
-        if (registration.isFirstListener()) {
-            return registrationBinder.bind(key)
-                .timeout(TOPOLOGY_CHANGES_TIMEOUT)
-                .retryWhen(Retry.backoff(retryBackoff.getMaxRetries(), retryBackoff.getFirstBackoff()).jitter(retryBackoff.getJitterFactor()).scheduler(Schedulers.elastic()));
-        }
-        return Mono.empty();
-    }
-
-    private Mono<Void> handleDelivery(Delivery delivery) {
-        if (delivery.getBody() == null) {
-            return Mono.empty();
-        }
-
-        String serializedEventBusId = delivery.getProperties().getHeaders().get(EVENT_BUS_ID).toString();
-        EventBusId eventBusId = EventBusId.of(serializedEventBusId);
-
-        String routingKey = delivery.getEnvelope().getRoutingKey();
-        RegistrationKey registrationKey = routingKeyConverter.toRegistrationKey(routingKey);
-        Event event = toEvent(delivery);
-
-        return localListenerRegistry.getLocalMailboxListeners(registrationKey)
-            .filter(listener -> !isLocalSynchronousListeners(eventBusId, listener))
-            .flatMap(listener -> executeListener(listener, event, registrationKey), EventBus.EXECUTION_RATE)
-            .then();
-    }
-
-    private Mono<Void> executeListener(EventListener.ReactiveEventListener listener, Event event, RegistrationKey key) {
-        MDCBuilder mdcBuilder = MDCBuilder.create()
-            .addContext(EventBus.StructuredLoggingFields.REGISTRATION_KEY, key);
-
-        return mailboxListenerExecutor.execute(listener, mdcBuilder, event)
-            .doOnError(e -> structuredLogger(event, key)
-                .log(logger -> logger.error("Exception happens when handling event", e)))
-            .onErrorResume(e -> Mono.empty())
-            .then();
-    }
-
-    private boolean isLocalSynchronousListeners(EventBusId eventBusId, EventListener listener) {
-        return eventBusId.equals(this.eventBusId) &&
-            listener.getExecutionMode().equals(EventListener.ExecutionMode.SYNCHRONOUS);
-    }
-
-    private Event toEvent(Delivery delivery) {
-        return eventSerializer.fromJson(new String(delivery.getBody(), StandardCharsets.UTF_8)).get();
-    }
-
-    private StructuredLogger structuredLogger(Event event, RegistrationKey key) {
-        return MDCStructuredLogger.forLogger(LOGGER)
-            .addField(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
-            .addField(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
-            .addField(EventBus.StructuredLoggingFields.USER, event.getUsername())
-            .addField(EventBus.StructuredLoggingFields.REGISTRATION_KEY, key);
-    }
-}
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/LocalListenerRegistry.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/LocalListenerRegistry.java
deleted file mode 100644
index 468bde6..0000000
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/LocalListenerRegistry.java
+++ /dev/null
@@ -1,112 +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.mailbox.events;
-
-import static com.google.common.base.Predicates.not;
-
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Supplier;
-
-import org.apache.james.events.EventListener;
-import org.apache.james.events.RegistrationKey;
-
-import com.github.steveash.guavate.Guavate;
-import com.google.common.collect.ImmutableSet;
-
-import reactor.core.publisher.Flux;
-
-class LocalListenerRegistry {
-
-    interface RemovalStatus {
-        boolean lastListenerRemoved();
-    }
-
-    public static class LocalRegistration {
-        private final boolean firstListener;
-        private final Supplier<RemovalStatus> unregister;
-
-        public LocalRegistration(boolean firstListener, Supplier<RemovalStatus> unregister) {
-            this.firstListener = firstListener;
-            this.unregister = unregister;
-        }
-
-        public boolean isFirstListener() {
-            return firstListener;
-        }
-
-        public RemovalStatus unregister() {
-            return unregister.get();
-        }
-    }
-
-    private final ConcurrentHashMap<RegistrationKey, ImmutableSet<EventListener.ReactiveEventListener>> listenersByKey;
-
-    LocalListenerRegistry() {
-        this.listenersByKey = new ConcurrentHashMap<>();
-    }
-
-    LocalRegistration addListener(RegistrationKey registrationKey, EventListener.ReactiveEventListener listener) {
-        AtomicBoolean firstListener = new AtomicBoolean(false);
-        listenersByKey.compute(registrationKey, (key, listeners) ->
-            Optional.ofNullable(listeners)
-                .map(set -> ImmutableSet.<EventListener.ReactiveEventListener>builder().addAll(set).add(listener).build())
-                .orElseGet(() -> {
-                    firstListener.set(true);
-                    return ImmutableSet.of(listener);
-                })
-        );
-        return new LocalRegistration(firstListener.get(), () -> removeListener(registrationKey, listener));
-    }
-
-    LocalRegistration addListener(RegistrationKey registrationKey, EventListener listener) {
-        return addListener(registrationKey, EventListener.wrapReactive(listener));
-    }
-
-    private RemovalStatus removeListener(RegistrationKey registrationKey, EventListener.ReactiveEventListener listener) {
-        AtomicBoolean lastListenerRemoved = new AtomicBoolean(false);
-        listenersByKey.compute(registrationKey, (key, listeners) -> {
-            boolean listenersContainRequested = Optional.ofNullable(listeners).orElse(ImmutableSet.of()).contains(listener);
-            if (listenersContainRequested) {
-                ImmutableSet<EventListener.ReactiveEventListener> remainingListeners = removeListenerFromSet(listener, listeners);
-                if (remainingListeners.isEmpty()) {
-                    lastListenerRemoved.set(true);
-                    return null;
-                }
-                return remainingListeners;
-            }
-            return listeners;
-        });
-        return lastListenerRemoved::get;
-    }
-
-    private ImmutableSet<EventListener.ReactiveEventListener> removeListenerFromSet(EventListener listener, ImmutableSet<EventListener.ReactiveEventListener> listeners) {
-        ImmutableSet<EventListener.ReactiveEventListener> remainingListeners = listeners.stream().filter(not(listener::equals)).collect(Guavate.toImmutableSet());
-        if (remainingListeners.isEmpty()) {
-            return ImmutableSet.of();
-        }
-        return remainingListeners;
-    }
-
-    Flux<EventListener.ReactiveEventListener> getLocalMailboxListeners(RegistrationKey registrationKey) {
-        return Flux.fromIterable(listenersByKey.getOrDefault(registrationKey, ImmutableSet.of()));
-    }
-}
\ No newline at end of file
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/MailboxListenerExecutor.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/MailboxListenerExecutor.java
deleted file mode 100644
index f35dc77..0000000
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/MailboxListenerExecutor.java
+++ /dev/null
@@ -1,56 +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.mailbox.events;
-
-import static org.apache.james.events.EventBus.Metrics.timerName;
-
-import org.apache.james.events.Event;
-import org.apache.james.events.EventBus;
-import org.apache.james.events.EventListener;
-import org.apache.james.metrics.api.MetricFactory;
-import org.apache.james.util.MDCBuilder;
-import org.apache.james.util.ReactorUtils;
-
-import reactor.core.publisher.Mono;
-
-class MailboxListenerExecutor {
-    private final MetricFactory metricFactory;
-
-    MailboxListenerExecutor(MetricFactory metricFactory) {
-        this.metricFactory = metricFactory;
-    }
-
-    Mono<Void> execute(EventListener.ReactiveEventListener listener, MDCBuilder mdcBuilder, Event event) {
-        if (listener.isHandling(event)) {
-            return Mono.from(metricFactory.decoratePublisherWithTimerMetric(timerName(listener),
-                Mono.from(listener.reactiveEvent(event))
-                    .subscriberContext(ReactorUtils.context("MailboxListenerExecutor", mdc(listener, mdcBuilder, event)))));
-        }
-        return Mono.empty();
-    }
-
-    private MDCBuilder mdc(EventListener listener, MDCBuilder mdcBuilder, Event event) {
-        return mdcBuilder
-            .addContext(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
-            .addContext(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
-            .addContext(EventBus.StructuredLoggingFields.USER, event.getUsername())
-            .addContext(EventBus.StructuredLoggingFields.LISTENER_CLASS, listener.getClass());
-    }
-}
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RabbitMQEventBus.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RabbitMQEventBus.java
deleted file mode 100644
index 14c4804..0000000
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RabbitMQEventBus.java
+++ /dev/null
@@ -1,177 +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.mailbox.events;
-
-import java.util.Set;
-
-import javax.annotation.PreDestroy;
-import javax.inject.Inject;
-
-import org.apache.james.backends.rabbitmq.ReactorRabbitMQChannelPool;
-import org.apache.james.backends.rabbitmq.ReceiverProvider;
-import org.apache.james.event.json.EventSerializer;
-import org.apache.james.events.Event;
-import org.apache.james.events.EventBus;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.events.EventListener;
-import org.apache.james.events.Group;
-import org.apache.james.events.Registration;
-import org.apache.james.events.RegistrationKey;
-import org.apache.james.lifecycle.api.Startable;
-import org.apache.james.metrics.api.MetricFactory;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableSet;
-
-import reactor.core.publisher.Mono;
-import reactor.rabbitmq.Sender;
-
-public class RabbitMQEventBus implements EventBus, Startable {
-    private static final Set<RegistrationKey> NO_KEY = ImmutableSet.of();
-    private static final String NOT_RUNNING_ERROR_MESSAGE = "Event Bus is not running";
-    static final String MAILBOX_EVENT = "mailboxEvent";
-    static final String MAILBOX_EVENT_DEAD_LETTER_QUEUE = MAILBOX_EVENT + "-dead-letter-queue";
-    static final String MAILBOX_EVENT_EXCHANGE_NAME = MAILBOX_EVENT + "-exchange";
-    static final String MAILBOX_EVENT_DEAD_LETTER_EXCHANGE_NAME = MAILBOX_EVENT + "-dead-letter-exchange";
-    static final String EVENT_BUS_ID = "eventBusId";
-
-    private final EventSerializer eventSerializer;
-    private final RoutingKeyConverter routingKeyConverter;
-    private final RetryBackoffConfiguration retryBackoff;
-    private final EventBusId eventBusId;
-    private final EventDeadLetters eventDeadLetters;
-    private final MailboxListenerExecutor mailboxListenerExecutor;
-    private final Sender sender;
-    private final ReceiverProvider receiverProvider;
-    private final ReactorRabbitMQChannelPool channelPool;
-
-    private volatile boolean isRunning;
-    private volatile boolean isStopping;
-    private GroupRegistrationHandler groupRegistrationHandler;
-    private KeyRegistrationHandler keyRegistrationHandler;
-    private EventDispatcher eventDispatcher;
-
-    @Inject
-    public RabbitMQEventBus(Sender sender, ReceiverProvider receiverProvider, EventSerializer eventSerializer,
-                            RetryBackoffConfiguration retryBackoff,
-                            RoutingKeyConverter routingKeyConverter,
-                            EventDeadLetters eventDeadLetters, MetricFactory metricFactory, ReactorRabbitMQChannelPool channelPool,
-                            EventBusId eventBusId) {
-        this.sender = sender;
-        this.receiverProvider = receiverProvider;
-        this.mailboxListenerExecutor = new MailboxListenerExecutor(metricFactory);
-        this.channelPool = channelPool;
-        this.eventBusId = eventBusId;
-        this.eventSerializer = eventSerializer;
-        this.routingKeyConverter = routingKeyConverter;
-        this.retryBackoff = retryBackoff;
-        this.eventDeadLetters = eventDeadLetters;
-        this.isRunning = false;
-        this.isStopping = false;
-    }
-
-    public void start() {
-        if (!isRunning && !isStopping) {
-
-            LocalListenerRegistry localListenerRegistry = new LocalListenerRegistry();
-            keyRegistrationHandler = new KeyRegistrationHandler(eventBusId, eventSerializer, sender, receiverProvider, routingKeyConverter, localListenerRegistry, mailboxListenerExecutor, retryBackoff);
-            groupRegistrationHandler = new GroupRegistrationHandler(eventSerializer, channelPool, sender, receiverProvider, retryBackoff, eventDeadLetters, mailboxListenerExecutor);
-            eventDispatcher = new EventDispatcher(eventBusId, eventSerializer, sender, localListenerRegistry, mailboxListenerExecutor, eventDeadLetters);
-
-            eventDispatcher.start();
-            keyRegistrationHandler.start();
-            isRunning = true;
-        }
-    }
-
-    @VisibleForTesting
-    void startWithoutStartingKeyRegistrationHandler() {
-        if (!isRunning && !isStopping) {
-
-            LocalListenerRegistry localListenerRegistry = new LocalListenerRegistry();
-            keyRegistrationHandler = new KeyRegistrationHandler(eventBusId, eventSerializer, sender, receiverProvider, routingKeyConverter, localListenerRegistry, mailboxListenerExecutor, retryBackoff);
-            groupRegistrationHandler = new GroupRegistrationHandler(eventSerializer, channelPool, sender, receiverProvider, retryBackoff, eventDeadLetters, mailboxListenerExecutor);
-            eventDispatcher = new EventDispatcher(eventBusId, eventSerializer, sender, localListenerRegistry, mailboxListenerExecutor, eventDeadLetters);
-
-            keyRegistrationHandler.declareQueue();
-
-            eventDispatcher.start();
-            isRunning = true;
-        }
-    }
-
-    @VisibleForTesting
-    void startKeyRegistrationHandler() {
-        keyRegistrationHandler.start();
-    }
-
-    @PreDestroy
-    public void stop() {
-        if (isRunning && !isStopping) {
-            isStopping = true;
-            isRunning = false;
-            groupRegistrationHandler.stop();
-            keyRegistrationHandler.stop();
-        }
-    }
-
-    @Override
-    public Mono<Registration> register(EventListener.ReactiveEventListener listener, RegistrationKey key) {
-        Preconditions.checkState(isRunning, NOT_RUNNING_ERROR_MESSAGE);
-        return keyRegistrationHandler.register(listener, key);
-    }
-
-    @Override
-    public Registration register(EventListener.ReactiveEventListener listener, Group group) {
-        Preconditions.checkState(isRunning, NOT_RUNNING_ERROR_MESSAGE);
-        return groupRegistrationHandler.register(listener, group);
-    }
-
-    @Override
-    public Mono<Void> dispatch(Event event, Set<RegistrationKey> key) {
-        Preconditions.checkState(isRunning, NOT_RUNNING_ERROR_MESSAGE);
-        if (!event.isNoop()) {
-            return eventDispatcher.dispatch(event, key);
-        }
-        return Mono.empty();
-    }
-
-    @Override
-    public Mono<Void> reDeliver(Group group, Event event) {
-        Preconditions.checkState(isRunning, NOT_RUNNING_ERROR_MESSAGE);
-        if (!event.isNoop()) {
-            /*
-            if the eventBus.dispatch() gets error while dispatching an event (rabbitMQ network outage maybe),
-            which means all the group consumers will not be receiving that event.
-
-            We store the that event in the dead letter and expecting in the future, it will be dispatched
-            again not only for a specific consumer but all.
-
-            That's why it is special, and we need to check event type before processing further.
-            */
-            if (group instanceof EventDispatcher.DispatchingFailureGroup) {
-                return eventDispatcher.dispatch(event, NO_KEY);
-            }
-            return groupRegistrationHandler.retrieveGroupRegistration(group).reDeliver(event);
-        }
-        return Mono.empty();
-    }
-}
\ No newline at end of file
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RegistrationBinder.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RegistrationBinder.java
deleted file mode 100644
index 88fa692..0000000
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RegistrationBinder.java
+++ /dev/null
@@ -1,56 +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.mailbox.events;
-
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME;
-
-import org.apache.james.events.RegistrationKey;
-
-import reactor.core.publisher.Mono;
-import reactor.rabbitmq.BindingSpecification;
-import reactor.rabbitmq.Sender;
-
-class RegistrationBinder {
-    private final Sender sender;
-    private final RegistrationQueueName registrationQueue;
-
-    RegistrationBinder(Sender sender, RegistrationQueueName registrationQueue) {
-        this.sender = sender;
-        this.registrationQueue = registrationQueue;
-    }
-
-    Mono<Void> bind(RegistrationKey key) {
-        return sender.bind(bindingSpecification(key))
-            .then();
-    }
-
-    Mono<Void> unbind(RegistrationKey key) {
-        return sender.unbind(bindingSpecification(key))
-            .then();
-    }
-
-    private BindingSpecification bindingSpecification(RegistrationKey key) {
-        RoutingKeyConverter.RoutingKey routingKey = RoutingKeyConverter.RoutingKey.of(key);
-        return BindingSpecification.binding()
-            .exchange(MAILBOX_EVENT_EXCHANGE_NAME)
-            .queue(registrationQueue.asString())
-            .routingKey(routingKey.asString());
-    }
-}
\ No newline at end of file
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RegistrationQueueName.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RegistrationQueueName.java
deleted file mode 100644
index 33c837b..0000000
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RegistrationQueueName.java
+++ /dev/null
@@ -1,32 +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.mailbox.events;
-
-class RegistrationQueueName {
-    private final String queueName;
-
-    RegistrationQueueName(String queueName) {
-        this.queueName = queueName;
-    }
-
-    String asString() {
-        return queueName;
-    }
-}
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RoutingKeyConverter.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RoutingKeyConverter.java
deleted file mode 100644
index 755ef27..0000000
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RoutingKeyConverter.java
+++ /dev/null
@@ -1,92 +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.mailbox.events;
-
-import static org.apache.james.backends.rabbitmq.Constants.EMPTY_ROUTING_KEY;
-
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-
-import javax.inject.Inject;
-
-import org.apache.james.events.RegistrationKey;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-
-public class RoutingKeyConverter {
-    private static final String SEPARATOR = ":";
-
-    static class RoutingKey {
-
-        static RoutingKey empty() {
-            return new RoutingKey(Optional.empty());
-        }
-
-        static RoutingKey of(RegistrationKey key) {
-            return new RoutingKey(Optional.of(key));
-        }
-
-        private final Optional<RegistrationKey> registrationKey;
-
-        private RoutingKey(Optional<RegistrationKey> registrationKey) {
-            this.registrationKey = registrationKey;
-        }
-
-        String asString() {
-            return registrationKey.map(key -> key.getClass().getName() + SEPARATOR + key.asString())
-                .orElse(EMPTY_ROUTING_KEY);
-        }
-    }
-
-    @VisibleForTesting
-    static RoutingKeyConverter forFactories(RegistrationKey.Factory... factories) {
-        return new RoutingKeyConverter(ImmutableSet.copyOf(factories));
-    }
-
-    private final Set<RegistrationKey.Factory> factories;
-
-    @Inject
-    public RoutingKeyConverter(Set<RegistrationKey.Factory> factories) {
-        this.factories = factories;
-    }
-
-    RegistrationKey toRegistrationKey(String routingKey) {
-        return toRegistrationKey(Splitter.on(SEPARATOR).splitToList(routingKey));
-    }
-
-    private RegistrationKey toRegistrationKey(List<String> parts) {
-        Preconditions.checkArgument(parts.size() >= 2, "Routing key needs to match the 'classFQDN:value' pattern");
-
-        String registrationClass = parts.get(0);
-        String value = Joiner.on(SEPARATOR).join(Iterables.skip(parts, 1));
-
-        return factories.stream()
-            .filter(factory -> factory.forClass().getName().equals(registrationClass))
-            .findAny()
-            .orElseThrow(() -> new IllegalArgumentException("No factory for " + registrationClass))
-            .fromString(value);
-    }
-}
\ No newline at end of file
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/WaitDelayGenerator.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/WaitDelayGenerator.java
deleted file mode 100644
index 9f2c0fd..0000000
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/WaitDelayGenerator.java
+++ /dev/null
@@ -1,83 +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.mailbox.events;
-
-import java.security.SecureRandom;
-import java.time.Duration;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.primitives.Ints;
-
-import reactor.core.publisher.Mono;
-import reactor.core.scheduler.Schedulers;
-
-class WaitDelayGenerator {
-
-    static WaitDelayGenerator of(RetryBackoffConfiguration retryBackoff) {
-        return new WaitDelayGenerator(retryBackoff);
-    }
-
-    private static Duration randomBetween(Duration base, Duration jitter) {
-        Preconditions.checkArgument(!jitter.isNegative(), "jitter value should always be positive");
-        if (jitter.isZero()) {
-            return base;
-        }
-        long maxJitterAsMillis = jitter.toMillis();
-        long jitterAsMillis = SECURE_RANDOM.nextInt(Ints.checkedCast(maxJitterAsMillis * 2)) / 2;
-        return base.plusMillis(jitterAsMillis);
-    }
-
-    private static final SecureRandom SECURE_RANDOM = new SecureRandom();
-
-    private final RetryBackoffConfiguration retryBackoff;
-
-    private WaitDelayGenerator(RetryBackoffConfiguration retryBackoff) {
-        this.retryBackoff = retryBackoff;
-    }
-
-    Mono<Integer> delayIfHaveTo(int retryCount) {
-        Mono<Integer> countRetryMono = Mono.just(retryCount);
-        if (!shouldDelay(retryCount)) {
-            return countRetryMono;
-        }
-
-        return countRetryMono
-            .delayElement(generateDelay(retryCount), Schedulers.elastic());
-    }
-
-    @VisibleForTesting
-    Duration generateDelay(int retryCount) {
-        if (!shouldDelay(retryCount)) {
-            return Duration.ZERO;
-        }
-        long exponentialFactor = Double.valueOf(Math.pow(2, retryCount - 1)).longValue();
-        Duration minDelay = retryBackoff.getFirstBackoff().multipliedBy(exponentialFactor);
-        Duration jitterDelay = retryBackoff.getFirstBackoff()
-            .multipliedBy(Double.valueOf(retryBackoff.getJitterFactor() * 100).intValue())
-            .dividedBy(100);
-
-        return randomBetween(minDelay, jitterDelay);
-    }
-
-    private boolean shouldDelay(int retryCount) {
-        return retryCount >= 1 && retryCount <= retryBackoff.getMaxRetries();
-    }
-}
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/EventBusIdTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/EventBusIdTest.java
deleted file mode 100644
index 7c6920b..0000000
--- a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/EventBusIdTest.java
+++ /dev/null
@@ -1,50 +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.mailbox.events;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.util.UUID;
-
-import org.junit.jupiter.api.Test;
-
-import nl.jqno.equalsverifier.EqualsVerifier;
-
-class EventBusIdTest {
-
-    private static final UUID UUID_1 = UUID.fromString("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
-
-    @Test
-    void eventBusIdShouldMatchBeanContract() {
-        EqualsVerifier.forClass(EventBusId.class);
-    }
-
-    @Test
-    void ofShouldDeserializeUUIDs() {
-        assertThat(EventBusId.of(UUID_1.toString()))
-            .isEqualTo(EventBusId.of(UUID_1));
-    }
-
-    @Test
-    void asStringShouldReturnWrappedValue() {
-        assertThat(EventBusId.of(UUID_1).asString())
-            .isEqualTo("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
-    }
-}
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/LocalListenerRegistryTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/LocalListenerRegistryTest.java
deleted file mode 100644
index aa54521..0000000
--- a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/LocalListenerRegistryTest.java
+++ /dev/null
@@ -1,256 +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.mailbox.events;
-
-import static org.apache.james.events.EventListener.wrapReactive;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.time.Duration;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.james.events.EventListener;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.util.concurrency.ConcurrentTestRunner;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-
-import reactor.core.publisher.Mono;
-import reactor.core.scheduler.Schedulers;
-
-class LocalListenerRegistryTest {
-    private static final MailboxIdRegistrationKey KEY_1 = new MailboxIdRegistrationKey(TestId.of(42));
-
-    private LocalListenerRegistry testee;
-
-    @BeforeEach
-    void setUp() {
-        testee = new LocalListenerRegistry();
-    }
-
-    @Test
-    void getLocalMailboxListenersShouldReturnEmptyWhenNone() {
-        assertThat(testee.getLocalMailboxListeners(KEY_1).collectList().block())
-            .isEmpty();
-    }
-
-    @Test
-    void getLocalMailboxListenersShouldReturnPreviouslyAddedListener() {
-        EventListener listener = event -> { };
-        testee.addListener(KEY_1, listener);
-
-        assertThat(testee.getLocalMailboxListeners(KEY_1).collectList().block())
-            .containsOnly(wrapReactive(listener));
-    }
-
-    @Test
-    void getLocalMailboxListenersShouldReturnPreviouslyAddedListeners() {
-        EventListener listener1 = event -> { };
-        EventListener listener2 = event -> { };
-        testee.addListener(KEY_1, listener1);
-        testee.addListener(KEY_1, listener2);
-
-        assertThat(testee.getLocalMailboxListeners(KEY_1).collectList().block())
-            .containsOnly(wrapReactive(listener1), wrapReactive(listener2));
-    }
-
-    @Test
-    void getLocalMailboxListenersShouldNotReturnRemovedListeners() {
-        EventListener listener1 = event -> { };
-        EventListener listener2 = event -> { };
-        testee.addListener(KEY_1, listener1);
-        LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener2);
-
-        registration.unregister();
-
-        assertThat(testee.getLocalMailboxListeners(KEY_1).collectList().block())
-            .containsOnly(wrapReactive(listener1));
-    }
-
-    @Test
-    void addListenerShouldReturnFirstListenerWhenNoPreviouslyRegisteredListeners() {
-        EventListener listener = event -> { };
-
-        assertThat(testee.addListener(KEY_1, listener).isFirstListener()).isTrue();
-    }
-
-    @Test
-    void addListenerShouldNotReturnFirstListenerWhenPreviouslyRegisteredListeners() {
-        EventListener listener = event -> { };
-        EventListener listener2 = event -> { };
-
-        testee.addListener(KEY_1, listener);
-
-        assertThat(testee.addListener(KEY_1, listener2).isFirstListener()).isFalse();
-    }
-
-    @Test
-    void removeListenerShouldNotReturnLastListenerRemovedWhenSeveralListener() {
-        EventListener listener = event -> { };
-        EventListener listener2 = event -> { };
-
-        LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener);
-        testee.addListener(KEY_1, listener2);
-
-        assertThat(registration.unregister().lastListenerRemoved()).isFalse();
-    }
-
-    @Test
-    void removeListenerShouldReturnLastListenerRemovedWhenOneListener() {
-        EventListener listener = event -> { };
-
-
-        LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener);
-
-        assertThat(registration.unregister().lastListenerRemoved()).isTrue();
-    }
-
-    @Nested
-    class ConcurrentTest {
-        private final Duration oneSecond = Duration.ofSeconds(1);
-
-        @Test
-        void getLocalMailboxListenersShouldReturnPreviousAddedListener() throws Exception {
-            EventListener listener = event -> { };
-
-            ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> testee.addListener(KEY_1, listener))
-                .threadCount(10)
-                .operationCount(10)
-                .runSuccessfullyWithin(oneSecond);
-
-            assertThat(testee.getLocalMailboxListeners(KEY_1).collectList().block())
-                .containsOnly(wrapReactive(listener));
-        }
-
-        @Test
-        void getLocalMailboxListenersShouldReturnAllPreviousAddedListeners() throws Exception {
-            EventListener listener1 = event -> { };
-            EventListener listener2 = event -> { };
-            EventListener listener3 = event -> { };
-
-            ConcurrentTestRunner.builder()
-                .randomlyDistributedOperations(
-                    (threadNumber, operationNumber) -> testee.addListener(KEY_1, listener1),
-                    (threadNumber, operationNumber) -> testee.addListener(KEY_1, listener2),
-                    (threadNumber, operationNumber) -> testee.addListener(KEY_1, listener3))
-                .threadCount(6)
-                .operationCount(10)
-                .runSuccessfullyWithin(oneSecond);
-
-            assertThat(testee.getLocalMailboxListeners(KEY_1).collectList().block())
-                .containsOnly(wrapReactive(listener1), wrapReactive(listener2), wrapReactive(listener3));
-        }
-
-        @Test
-        void getLocalMailboxListenersShouldReturnEmptyWhenRemoveAddedListener() throws Exception {
-            EventListener listener1 = event -> { };
-
-            LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener1);
-
-            ConcurrentTestRunner.builder()
-                .operation(((threadNumber, operationNumber) -> registration.unregister()))
-                .threadCount(10)
-                .operationCount(10)
-                .runSuccessfullyWithin(oneSecond);
-
-            assertThat(testee.getLocalMailboxListeners(KEY_1).collectList().block())
-                .isEmpty();
-        }
-
-        @Test
-        void addListenerOnlyReturnIsFirstListenerForEmptyRegistry() throws Exception {
-            EventListener listener1 = event -> { };
-            EventListener listener2 = event -> { };
-            EventListener listener3 = event -> { };
-
-            AtomicInteger firstListenerCount = new AtomicInteger(0);
-
-            ConcurrentTestRunner.builder()
-                .randomlyDistributedOperations((threadNumber, operationNumber) -> {
-                        LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener1);
-                        if (registration.isFirstListener()) {
-                            firstListenerCount.incrementAndGet();
-                        }
-                    },
-                    (threadNumber, operationNumber) -> {
-                        LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener2);
-                        if (registration.isFirstListener()) {
-                            firstListenerCount.incrementAndGet();
-                        }
-                    },
-                    (threadNumber, operationNumber) -> {
-                        LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener3);
-                        if (registration.isFirstListener()) {
-                            firstListenerCount.incrementAndGet();
-                        }
-                    })
-                .threadCount(6)
-                .operationCount(10)
-                .runSuccessfullyWithin(oneSecond);
-
-            assertThat(firstListenerCount.get()).isEqualTo(1);
-        }
-
-        @Test
-        void removeListenerOnlyReturnLastListenerRemovedForEmptyRegistry() throws Exception {
-            EventListener listener1 = event -> { };
-            AtomicInteger lastListenerRemoved = new AtomicInteger(0);
-
-            LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener1);
-            ConcurrentTestRunner.builder()
-                .operation(((threadNumber, operationNumber) -> {
-                    if (registration.unregister().lastListenerRemoved()) {
-                        lastListenerRemoved.incrementAndGet();
-                    }
-                }))
-                .threadCount(10)
-                .operationCount(10)
-                .runSuccessfullyWithin(oneSecond);
-
-            assertThat(lastListenerRemoved.get()).isEqualTo(1);
-        }
-
-        @Test
-        void iterationShouldPerformOnASnapshotOfListenersSet() {
-            EventListener listener1 = event -> { };
-            EventListener listener2 = event -> { };
-            EventListener listener3 = event -> { };
-            EventListener listener4 = event -> { };
-            EventListener listener5 = event -> { };
-
-            testee.addListener(KEY_1, listener1);
-            testee.addListener(KEY_1, listener2);
-            testee.addListener(KEY_1, listener3);
-            testee.addListener(KEY_1, listener4);
-            LocalListenerRegistry.LocalRegistration registration5 = testee.addListener(KEY_1, listener5);
-
-            Mono<List<EventListener.ReactiveEventListener>> listeners = testee.getLocalMailboxListeners(KEY_1)
-                .publishOn(Schedulers.elastic())
-                .delayElements(Duration.ofMillis(100))
-                .collectList();
-
-            registration5.unregister();
-
-            assertThat(listeners.block(Duration.ofSeconds(10))).hasSize(5);
-        }
-    }
-}
\ No newline at end of file
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/NetworkErrorTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/NetworkErrorTest.java
deleted file mode 100644
index fd551ec..0000000
--- a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/NetworkErrorTest.java
+++ /dev/null
@@ -1,89 +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.mailbox.events;
-
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT;
-import static org.apache.james.mailbox.events.EventBusTestFixture.GROUP_A;
-import static org.apache.james.mailbox.events.EventBusTestFixture.NO_KEYS;
-import static org.apache.james.mailbox.events.EventBusTestFixture.RETRY_BACKOFF_CONFIGURATION;
-import static org.apache.james.mailbox.events.EventBusTestFixture.newListener;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.Mockito.verify;
-
-import org.apache.james.backends.rabbitmq.RabbitMQExtension;
-import org.apache.james.backends.rabbitmq.RabbitMQFixture;
-import org.apache.james.event.json.EventSerializer;
-import org.apache.james.events.EventListener;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.mailbox.model.TestMessageId;
-import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
-import org.apache.james.metrics.tests.RecordingMetricFactory;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class NetworkErrorTest {
-    @RegisterExtension
-    static RabbitMQExtension rabbitMQExtension = RabbitMQExtension.singletonRabbitMQ()
-        .isolationPolicy(RabbitMQExtension.IsolationPolicy.WEAK);
-
-    private RabbitMQEventBus eventBus;
-
-    @BeforeEach
-    void setUp() {
-        MemoryEventDeadLetters memoryEventDeadLetters = new MemoryEventDeadLetters();
-
-        TestId.Factory mailboxIdFactory = new TestId.Factory();
-        EventSerializer eventSerializer = new EventSerializer(mailboxIdFactory, new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
-        RoutingKeyConverter routingKeyConverter = RoutingKeyConverter.forFactories(new MailboxIdRegistrationKey.Factory(mailboxIdFactory));
-
-        eventBus = new RabbitMQEventBus(rabbitMQExtension.getSender(), rabbitMQExtension.getReceiverProvider(),
-            eventSerializer, RETRY_BACKOFF_CONFIGURATION, routingKeyConverter,
-            memoryEventDeadLetters, new RecordingMetricFactory(), rabbitMQExtension.getRabbitChannelPool(),
-            EventBusId.random());
-
-        eventBus.start();
-    }
-
-    @AfterEach
-    void tearDown() {
-        eventBus.stop();
-    }
-
-    @Test
-    void dispatchShouldWorkAfterNetworkIssuesForOldRegistration() {
-        EventListener listener = newListener();
-        eventBus.register(listener, GROUP_A);
-
-        rabbitMQExtension.getRabbitMQ().pause();
-
-        assertThatThrownBy(() -> eventBus.dispatch(EVENT, NO_KEYS).block())
-            .isInstanceOf(IllegalStateException.class)
-            .hasMessageContaining("Retries exhausted");
-
-        rabbitMQExtension.getRabbitMQ().unpause();
-
-        eventBus.dispatch(EVENT, NO_KEYS).block();
-        RabbitMQFixture.awaitAtMostThirtySeconds
-            .untilAsserted(() -> verify(listener).event(EVENT));
-    }
-
-}
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
deleted file mode 100644
index 9ed6dad..0000000
--- a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.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.mailbox.events;
-
-import static org.apache.james.backends.rabbitmq.Constants.AUTO_DELETE;
-import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
-import static org.apache.james.backends.rabbitmq.Constants.EXCLUSIVE;
-import static org.apache.james.mailbox.events.EventBusTestFixture.RETRY_BACKOFF_CONFIGURATION;
-import static org.assertj.core.api.Assertions.assertThatCode;
-
-import org.apache.james.backends.rabbitmq.RabbitMQExtension;
-import org.apache.james.event.json.EventSerializer;
-import org.apache.james.mailbox.events.EventBusTestFixture.GroupA;
-import org.apache.james.mailbox.events.GroupRegistration.WorkQueueName;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.mailbox.model.TestMessageId;
-import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
-import org.apache.james.mailbox.util.EventCollector;
-import org.apache.james.metrics.tests.RecordingMetricFactory;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-import reactor.rabbitmq.QueueSpecification;
-
-class RabbitMQEventBusDeadLetterQueueUpgradeTest {
-    @RegisterExtension
-    static RabbitMQExtension rabbitMQExtension = RabbitMQExtension.singletonRabbitMQ()
-        .isolationPolicy(RabbitMQExtension.IsolationPolicy.WEAK);
-
-    private RabbitMQEventBus eventBus;
-
-    @BeforeEach
-    void setUp() {
-        MemoryEventDeadLetters memoryEventDeadLetters = new MemoryEventDeadLetters();
-
-        TestId.Factory mailboxIdFactory = new TestId.Factory();
-        EventSerializer eventSerializer = new EventSerializer(mailboxIdFactory, new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
-        RoutingKeyConverter routingKeyConverter = RoutingKeyConverter.forFactories(new MailboxIdRegistrationKey.Factory(mailboxIdFactory));
-
-        eventBus = new RabbitMQEventBus(rabbitMQExtension.getSender(), rabbitMQExtension.getReceiverProvider(),
-            eventSerializer, RETRY_BACKOFF_CONFIGURATION, routingKeyConverter,
-            memoryEventDeadLetters, new RecordingMetricFactory(), rabbitMQExtension.getRabbitChannelPool(),
-            EventBusId.random());
-
-        eventBus.start();
-    }
-
-    @AfterEach
-    void tearDown() {
-        eventBus.stop();
-    }
-
-    @Test
-    void eventBusShouldStartWhenDeadLetterUpgradeWasNotPerformed() {
-        GroupA registeredGroup = new GroupA();
-        WorkQueueName workQueueName = WorkQueueName.of(registeredGroup);
-        
-        rabbitMQExtension.getSender()
-            .declareQueue(QueueSpecification.queue(workQueueName.asString())
-                .durable(DURABLE)
-                .exclusive(!EXCLUSIVE)
-                .autoDelete(!AUTO_DELETE))
-            .block();
-
-        assertThatCode(eventBus::start).doesNotThrowAnyException();
-        assertThatCode(() -> eventBus.register(new EventCollector(), registeredGroup)).doesNotThrowAnyException();
-    }
-
-}
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RabbitMQEventBusTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RabbitMQEventBusTest.java
deleted file mode 100644
index a167ca9..0000000
--- a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RabbitMQEventBusTest.java
+++ /dev/null
@@ -1,980 +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.mailbox.events;
-
-import static org.apache.james.backends.rabbitmq.Constants.AUTO_DELETE;
-import static org.apache.james.backends.rabbitmq.Constants.DIRECT_EXCHANGE;
-import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
-import static org.apache.james.backends.rabbitmq.Constants.EMPTY_ROUTING_KEY;
-import static org.apache.james.backends.rabbitmq.Constants.EXCLUSIVE;
-import static org.apache.james.backends.rabbitmq.Constants.NO_ARGUMENTS;
-import static org.apache.james.mailbox.events.EventBusConcurrentTestContract.newCountingListener;
-import static org.apache.james.mailbox.events.EventBusTestFixture.ALL_GROUPS;
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT;
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT_2;
-import static org.apache.james.mailbox.events.EventBusTestFixture.GROUP_A;
-import static org.apache.james.mailbox.events.EventBusTestFixture.GROUP_B;
-import static org.apache.james.mailbox.events.EventBusTestFixture.KEY_1;
-import static org.apache.james.mailbox.events.EventBusTestFixture.NO_KEYS;
-import static org.apache.james.mailbox.events.EventBusTestFixture.newAsyncListener;
-import static org.apache.james.mailbox.events.EventBusTestFixture.newListener;
-import static org.apache.james.mailbox.events.GroupRegistration.WorkQueueName.MAILBOX_EVENT_WORK_QUEUE_PREFIX;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT_DEAD_LETTER_QUEUE;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.awaitility.Awaitility.await;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.io.Closeable;
-import java.nio.charset.StandardCharsets;
-import java.time.Duration;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.IntStream;
-import java.util.stream.Stream;
-
-import org.apache.james.backends.rabbitmq.RabbitMQExtension;
-import org.apache.james.backends.rabbitmq.RabbitMQExtension.DockerRestartPolicy;
-import org.apache.james.backends.rabbitmq.RabbitMQFixture;
-import org.apache.james.backends.rabbitmq.RabbitMQManagementAPI;
-import org.apache.james.backends.rabbitmq.ReceiverProvider;
-import org.apache.james.event.json.EventSerializer;
-import org.apache.james.events.Event;
-import org.apache.james.events.EventBus;
-import org.apache.james.events.EventDeadLetters;
-import org.apache.james.events.EventListener;
-import org.apache.james.events.Group;
-import org.apache.james.events.GroupRegistrationNotFound;
-import org.apache.james.mailbox.events.EventBusTestFixture.EventListenerCountingSuccessfulExecution;
-import org.apache.james.mailbox.events.EventBusTestFixture.GroupA;
-import org.apache.james.mailbox.events.EventDispatcher.DispatchingFailureGroup;
-import org.apache.james.mailbox.events.RoutingKeyConverter.RoutingKey;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.mailbox.model.TestMessageId;
-import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
-import org.apache.james.mailbox.util.EventCollector;
-import org.apache.james.metrics.tests.RecordingMetricFactory;
-import org.apache.james.util.concurrency.ConcurrentTestRunner;
-import org.assertj.core.data.Percentage;
-import org.awaitility.Awaitility;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-import org.mockito.stubbing.Answer;
-
-import com.google.common.collect.ImmutableSet;
-
-import reactor.core.publisher.Mono;
-import reactor.core.scheduler.Schedulers;
-import reactor.rabbitmq.BindingSpecification;
-import reactor.rabbitmq.ExchangeSpecification;
-import reactor.rabbitmq.OutboundMessage;
-import reactor.rabbitmq.QueueSpecification;
-import reactor.rabbitmq.Receiver;
-import reactor.rabbitmq.Sender;
-
-class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract, GroupContract.MultipleEventBusGroupContract,
-    KeyContract.SingleEventBusKeyContract, KeyContract.MultipleEventBusKeyContract,
-    ErrorHandlingContract {
-
-    @RegisterExtension
-    static RabbitMQExtension rabbitMQExtension = RabbitMQExtension.singletonRabbitMQ()
-        .isolationPolicy(RabbitMQExtension.IsolationPolicy.WEAK);
-
-    private RabbitMQEventBus eventBus;
-    private RabbitMQEventBus eventBus2;
-    private RabbitMQEventBus eventBus3;
-    private RabbitMQEventBus eventBusWithKeyHandlerNotStarted;
-    private EventSerializer eventSerializer;
-    private RoutingKeyConverter routingKeyConverter;
-    private MemoryEventDeadLetters memoryEventDeadLetters;
-
-    @Override
-    public EnvironmentSpeedProfile getSpeedProfile() {
-        return EnvironmentSpeedProfile.SLOW;
-    }
-
-    @BeforeEach
-    void setUp() {
-        memoryEventDeadLetters = new MemoryEventDeadLetters();
-
-        TestId.Factory mailboxIdFactory = new TestId.Factory();
-        eventSerializer = new EventSerializer(mailboxIdFactory, new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
-        routingKeyConverter = RoutingKeyConverter.forFactories(new MailboxIdRegistrationKey.Factory(mailboxIdFactory));
-
-        eventBus = newEventBus();
-        eventBus2 = newEventBus();
-        eventBus3 = newEventBus();
-        eventBusWithKeyHandlerNotStarted = newEventBus();
-
-        eventBus.start();
-        eventBus2.start();
-        eventBus3.start();
-        eventBusWithKeyHandlerNotStarted.startWithoutStartingKeyRegistrationHandler();
-    }
-
-    @AfterEach
-    void tearDown() {
-        eventBus.stop();
-        eventBus2.stop();
-        eventBus3.stop();
-        eventBusWithKeyHandlerNotStarted.stop();
-        ALL_GROUPS.stream()
-            .map(GroupRegistration.WorkQueueName::of)
-            .forEach(queueName -> rabbitMQExtension.getSender().delete(QueueSpecification.queue(queueName.asString())).block());
-        rabbitMQExtension.getSender()
-            .delete(ExchangeSpecification.exchange(MAILBOX_EVENT_EXCHANGE_NAME))
-            .block();
-    }
-
-    private RabbitMQEventBus newEventBus() {
-        return newEventBus(rabbitMQExtension.getSender(), rabbitMQExtension.getReceiverProvider());
-    }
-
-    private RabbitMQEventBus newEventBus(Sender sender, ReceiverProvider receiverProvider) {
-        return new RabbitMQEventBus(sender, receiverProvider, eventSerializer,
-            EventBusTestFixture.RETRY_BACKOFF_CONFIGURATION, routingKeyConverter,
-            memoryEventDeadLetters, new RecordingMetricFactory(),
-            rabbitMQExtension.getRabbitChannelPool(), EventBusId.random());
-    }
-
-    @Override
-    public EventBus eventBus() {
-        return eventBus;
-    }
-
-    @Override
-    public EventBus eventBus2() {
-        return eventBus2;
-    }
-
-    @Override
-    public EventDeadLetters deadLetter() {
-        return memoryEventDeadLetters;
-    }
-
-    @Override
-    @Test
-    @Disabled("This test is failing by design as the different registration keys are handled by distinct messages")
-    public void dispatchShouldCallListenerOnceWhenSeveralKeysMatching() {
-
-    }
-
-    @Test
-    void eventProcessingShouldNotCrashOnInvalidMessage() {
-        EventCollector listener = new EventCollector();
-        EventBusTestFixture.GroupA registeredGroup = new EventBusTestFixture.GroupA();
-        eventBus.register(listener, registeredGroup);
-
-        String emptyRoutingKey = "";
-        rabbitMQExtension.getSender()
-            .send(Mono.just(new OutboundMessage(MAILBOX_EVENT_EXCHANGE_NAME,
-                emptyRoutingKey,
-                "BAD_PAYLOAD!".getBytes(StandardCharsets.UTF_8))))
-            .block();
-
-        eventBus.dispatch(EVENT, NO_KEYS).block();
-        await()
-            .timeout(org.awaitility.Duration.TEN_SECONDS).untilAsserted(() ->
-                assertThat(listener.getEvents()).containsOnly(EVENT));
-    }
-
-    @Test
-    void eventProcessingShouldNotCrashOnInvalidMessages() {
-        EventCollector listener = new EventCollector();
-        EventBusTestFixture.GroupA registeredGroup = new EventBusTestFixture.GroupA();
-        eventBus.register(listener, registeredGroup);
-
-        String emptyRoutingKey = "";
-        IntStream.range(0, 10).forEach(i -> rabbitMQExtension.getSender()
-            .send(Mono.just(new OutboundMessage(MAILBOX_EVENT_EXCHANGE_NAME,
-                emptyRoutingKey,
-                "BAD_PAYLOAD!".getBytes(StandardCharsets.UTF_8))))
-            .block());
-
-        eventBus.dispatch(EVENT, NO_KEYS).block();
-        await()
-            .timeout(org.awaitility.Duration.TEN_SECONDS).untilAsserted(() ->
-            assertThat(listener.getEvents()).containsOnly(EVENT));
-    }
-
-    @Test
-    void eventProcessingShouldStoreInvalidMessagesInDeadLetterQueue() {
-        EventCollector listener = new EventCollector();
-        EventBusTestFixture.GroupA registeredGroup = new EventBusTestFixture.GroupA();
-        eventBus.register(listener, registeredGroup);
-
-        String emptyRoutingKey = "";
-        rabbitMQExtension.getSender()
-            .send(Mono.just(new OutboundMessage(MAILBOX_EVENT_EXCHANGE_NAME,
-                emptyRoutingKey,
-                "BAD_PAYLOAD!".getBytes(StandardCharsets.UTF_8))))
-            .block();
-
-        AtomicInteger deadLetteredCount = new AtomicInteger();
-        rabbitMQExtension.getRabbitChannelPool()
-            .createReceiver()
-            .consumeAutoAck(MAILBOX_EVENT_DEAD_LETTER_QUEUE)
-            .doOnNext(next -> deadLetteredCount.incrementAndGet())
-            .subscribeOn(Schedulers.elastic())
-            .subscribe();
-
-        Awaitility.await().atMost(org.awaitility.Duration.TEN_SECONDS)
-            .untilAsserted(() -> assertThat(deadLetteredCount.get()).isEqualTo(1));
-    }
-
-    @Test
-    void registrationShouldNotCrashOnInvalidMessage() {
-        EventCollector listener = new EventCollector();
-        Mono.from(eventBus.register(listener, KEY_1)).block();
-
-        rabbitMQExtension.getSender()
-            .send(Mono.just(new OutboundMessage(MAILBOX_EVENT_EXCHANGE_NAME,
-                RoutingKey.of(KEY_1).asString(),
-                "BAD_PAYLOAD!".getBytes(StandardCharsets.UTF_8))))
-            .block();
-
-        eventBus.dispatch(EVENT, KEY_1).block();
-        await().timeout(org.awaitility.Duration.TEN_SECONDS)
-            .untilAsserted(() -> assertThat(listener.getEvents()).containsOnly(EVENT));
-    }
-
-    @Test
-    void registrationShouldNotCrashOnInvalidMessages() {
-        EventCollector listener = new EventCollector();
-        Mono.from(eventBus.register(listener, KEY_1)).block();
-
-        IntStream.range(0, 100)
-            .forEach(i -> rabbitMQExtension.getSender()
-                .send(Mono.just(new OutboundMessage(MAILBOX_EVENT_EXCHANGE_NAME,
-                    RoutingKey.of(KEY_1).asString(),
-                    "BAD_PAYLOAD!".getBytes(StandardCharsets.UTF_8))))
-                .block());
-
-        eventBus.dispatch(EVENT, KEY_1).block();
-        await().timeout(org.awaitility.Duration.TEN_SECONDS)
-            .untilAsserted(() -> assertThat(listener.getEvents()).containsOnly(EVENT));
-    }
-
-    @Test
-    void deserializeEventCollectorGroup() throws Exception {
-        assertThat(Group.deserialize("org.apache.james.mailbox.util.EventCollector$EventCollectorGroup"))
-            .isEqualTo(new EventCollector.EventCollectorGroup());
-    }
-
-    @Test
-    void registerGroupShouldCreateRetryExchange() throws Exception {
-        EventListener listener = newListener();
-        EventBusTestFixture.GroupA registeredGroup = new EventBusTestFixture.GroupA();
-        eventBus.register(listener, registeredGroup);
-
-        GroupConsumerRetry.RetryExchangeName retryExchangeName = GroupConsumerRetry.RetryExchangeName.of(registeredGroup);
-        assertThat(rabbitMQExtension.managementAPI().listExchanges())
-            .anyMatch(exchange -> exchange.getName().equals(retryExchangeName.asString()));
-    }
-
-    @Nested
-    class ConcurrentTest implements EventBusConcurrentTestContract.MultiEventBusConcurrentContract,
-        EventBusConcurrentTestContract.SingleEventBusConcurrentContract {
-
-        @Override
-        public EnvironmentSpeedProfile getSpeedProfile() {
-            return EnvironmentSpeedProfile.SLOW;
-        }
-
-        @Test
-        void rabbitMQEventBusShouldHandleBulksGracefully() throws Exception {
-            EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            eventBus().register(countingListener1, new EventBusTestFixture.GroupA());
-            int totalGlobalRegistrations = 1; // GroupA
-
-            int threadCount = 10;
-            int operationCount = 10000;
-            int totalDispatchOperations = threadCount * operationCount;
-            eventBus = (RabbitMQEventBus) eventBus();
-            ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus.dispatch(EVENT, NO_KEYS).block())
-                .threadCount(threadCount)
-                .operationCount(operationCount)
-                .runSuccessfullyWithin(Duration.ofMinutes(3));
-
-            await()
-                .pollInterval(org.awaitility.Duration.FIVE_SECONDS)
-                .timeout(org.awaitility.Duration.TEN_MINUTES).untilAsserted(() ->
-                    assertThat(countingListener1.numberOfEventCalls()).isEqualTo((totalGlobalRegistrations * totalDispatchOperations)));
-        }
-
-        @Override
-        public EventBus eventBus3() {
-            return eventBus3;
-        }
-
-        @Override
-        public EventBus eventBus2() {
-            return eventBus2;
-        }
-
-        @Override
-        public EventBus eventBus() {
-            return eventBus;
-        }
-    }
-
-    @Nested
-    class AtLeastOnceTest {
-
-        @Test
-        void inProcessingEventShouldBeReDispatchedToAnotherEventBusWhenOneIsDown() {
-            EventListenerCountingSuccessfulExecution eventBusListener = spy(new EventListenerCountingSuccessfulExecution());
-            EventListenerCountingSuccessfulExecution eventBus2Listener = spy(new EventListenerCountingSuccessfulExecution());
-            EventListenerCountingSuccessfulExecution eventBus3Listener = spy(new EventListenerCountingSuccessfulExecution());
-            Answer<?> callEventAndSleepForever = invocation -> {
-                invocation.callRealMethod();
-                TimeUnit.SECONDS.sleep(Long.MAX_VALUE);
-                return null;
-            };
-
-            doAnswer(callEventAndSleepForever).when(eventBusListener).event(any());
-            doAnswer(callEventAndSleepForever).when(eventBus2Listener).event(any());
-
-            eventBus.register(eventBusListener, GROUP_A);
-            eventBus2.register(eventBus2Listener, GROUP_A);
-            eventBus3.register(eventBus3Listener, GROUP_A);
-
-            eventBus.dispatch(EVENT, NO_KEYS).block();
-            getSpeedProfile().shortWaitCondition()
-                .untilAsserted(() -> assertThat(eventBusListener.numberOfEventCalls()).isEqualTo(1));
-            eventBus.stop();
-
-            getSpeedProfile().shortWaitCondition()
-                .untilAsserted(() -> assertThat(eventBus2Listener.numberOfEventCalls()).isEqualTo(1));
-            eventBus2.stop();
-
-            getSpeedProfile().shortWaitCondition()
-                .untilAsserted(() -> assertThat(eventBus3Listener.numberOfEventCalls()).isEqualTo(1));
-        }
-    }
-
-    @Nested
-    class PublishingTest {
-        private static final String MAILBOX_WORK_QUEUE_NAME = MAILBOX_EVENT + "-workQueue";
-
-        @BeforeEach
-        void setUp() {
-            Sender sender = rabbitMQExtension.getSender();
-
-            sender.declareQueue(QueueSpecification.queue(MAILBOX_WORK_QUEUE_NAME)
-                .durable(DURABLE)
-                .exclusive(!EXCLUSIVE)
-                .autoDelete(!AUTO_DELETE)
-                .arguments(NO_ARGUMENTS))
-                .block();
-            sender.bind(BindingSpecification.binding()
-                .exchange(MAILBOX_EVENT_EXCHANGE_NAME)
-                .queue(MAILBOX_WORK_QUEUE_NAME)
-                .routingKey(EMPTY_ROUTING_KEY))
-                .block();
-        }
-
-        @Test
-        void dispatchShouldPublishSerializedEventToRabbitMQ() {
-            eventBus.dispatch(EVENT, NO_KEYS).block();
-
-            assertThat(dequeueEvent()).isEqualTo(EVENT);
-        }
-
-        @Test
-        void dispatchShouldPublishSerializedEventToRabbitMQWhenNotBlocking() {
-            eventBus.dispatch(EVENT, NO_KEYS).block();
-
-            assertThat(dequeueEvent()).isEqualTo(EVENT);
-        }
-
-        private Event dequeueEvent() {
-            try (Receiver receiver = rabbitMQExtension.getReceiverProvider().createReceiver()) {
-                byte[] eventInBytes = receiver.consumeAutoAck(MAILBOX_WORK_QUEUE_NAME)
-                    .blockFirst()
-                    .getBody();
-
-                return eventSerializer.fromJson(new String(eventInBytes, StandardCharsets.UTF_8))
-                    .get();
-            }
-        }
-    }
-
-    @Nested
-    class LifeCycleTest {
-        private static final int THREAD_COUNT = 10;
-        private static final int OPERATION_COUNT = 100000;
-
-        private RabbitMQManagementAPI rabbitManagementAPI;
-
-        @BeforeEach
-        void setUp() throws Exception {
-            rabbitManagementAPI = rabbitMQExtension.managementAPI();
-        }
-
-        @AfterEach
-        void tearDown() {
-            rabbitMQExtension.getRabbitMQ().unpause();
-        }
-
-        @Nested
-        class SingleEventBus {
-
-            @Nested
-            class DispatchingWhenNetWorkIssue {
-
-                @RegisterExtension
-                RabbitMQExtension rabbitMQNetWorkIssueExtension = RabbitMQExtension.defaultRabbitMQ()
-                    .restartPolicy(DockerRestartPolicy.PER_TEST)
-                    .isolationPolicy(RabbitMQExtension.IsolationPolicy.WEAK);
-
-                private RabbitMQEventBus rabbitMQEventBusWithNetWorkIssue;
-
-                @BeforeEach
-                void beforeEach() {
-                    rabbitMQEventBusWithNetWorkIssue = newEventBus(rabbitMQNetWorkIssueExtension.getSender(), rabbitMQNetWorkIssueExtension.getReceiverProvider());
-                }
-
-                @Test
-                void dispatchShouldWorkAfterNetworkIssuesForOldRegistrationAndKey() {
-                    rabbitMQEventBusWithNetWorkIssue.start();
-                    EventListener listener = newListener();
-                    Mono.from(rabbitMQEventBusWithNetWorkIssue.register(listener, KEY_1)).block();
-
-                    rabbitMQNetWorkIssueExtension.getRabbitMQ().pause();
-
-                    assertThatThrownBy(() -> rabbitMQEventBusWithNetWorkIssue.dispatch(EVENT, NO_KEYS).block())
-                        .isInstanceOf(IllegalStateException.class)
-                        .hasMessageContaining("Retries exhausted");
-
-                    rabbitMQNetWorkIssueExtension.getRabbitMQ().unpause();
-
-                    rabbitMQEventBusWithNetWorkIssue.dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-                    assertThatListenerReceiveOneEvent(listener);
-                }
-            }
-
-            @Test
-            void startShouldCreateEventExchange() {
-                eventBus.start();
-                assertThat(rabbitManagementAPI.listExchanges())
-                    .filteredOn(exchange -> exchange.getName().equals(MAILBOX_EVENT_EXCHANGE_NAME))
-                    .hasOnlyOneElementSatisfying(exchange -> {
-                        assertThat(exchange.isDurable()).isTrue();
-                        assertThat(exchange.getType()).isEqualTo(DIRECT_EXCHANGE);
-                    });
-            }
-
-            @Test
-            void dispatchShouldWorkAfterRestartForOldRegistration() throws Exception {
-                eventBus.start();
-                EventListener listener = newListener();
-                eventBus.register(listener, GROUP_A);
-
-                rabbitMQExtension.getRabbitMQ().restart();
-
-                eventBus.dispatch(EVENT, NO_KEYS).block();
-                assertThatListenerReceiveOneEvent(listener);
-            }
-
-            @Test
-            void dispatchShouldWorkAfterRestartForNewRegistration() throws Exception {
-                eventBus.start();
-                EventListener listener = newListener();
-
-                rabbitMQExtension.getRabbitMQ().restart();
-
-                eventBus.register(listener, GROUP_A);
-
-                eventBus.dispatch(EVENT, NO_KEYS).block();
-
-                assertThatListenerReceiveOneEvent(listener);
-
-            }
-
-            @Test
-            void redeliverShouldWorkAfterRestartForOldRegistration() throws Exception {
-                eventBus.start();
-                EventListener listener = newListener();
-                eventBus.register(listener, GROUP_A);
-
-                rabbitMQExtension.getRabbitMQ().restart();
-
-                eventBus.reDeliver(GROUP_A, EVENT).block();
-                assertThatListenerReceiveOneEvent(listener);
-            }
-
-            @Test
-            void redeliverShouldWorkAfterRestartForNewRegistration() throws Exception {
-                eventBus.start();
-                EventListener listener = newListener();
-
-                rabbitMQExtension.getRabbitMQ().restart();
-
-                eventBus.register(listener, GROUP_A);
-
-                eventBus.reDeliver(GROUP_A, EVENT).block();
-                assertThatListenerReceiveOneEvent(listener);
-            }
-
-            @Test
-            void dispatchShouldWorkAfterRestartForOldKeyRegistration() throws Exception {
-                eventBus.start();
-                EventListener listener = newListener();
-                Mono.from(eventBus.register(listener, KEY_1)).block();
-
-                rabbitMQExtension.getRabbitMQ().restart();
-
-                eventBus.dispatch(EVENT, KEY_1).block();
-                assertThatListenerReceiveOneEvent(listener);
-            }
-
-            @Test
-            void dispatchedMessagesShouldSurviveARabbitMQRestart() throws Exception {
-                eventBusWithKeyHandlerNotStarted.startWithoutStartingKeyRegistrationHandler();
-                EventListener listener = newAsyncListener();
-                Mono.from(eventBusWithKeyHandlerNotStarted.register(listener, KEY_1)).block();
-                Mono<Void> dispatch = eventBusWithKeyHandlerNotStarted.dispatch(EVENT, KEY_1);
-                dispatch.block();
-
-                rabbitMQExtension.getRabbitMQ().restart();
-
-                eventBusWithKeyHandlerNotStarted.startKeyRegistrationHandler();
-
-                assertThatListenerReceiveOneEvent(listener);
-            }
-
-            @Disabled("JAMES-3083 Disable this unstable test")
-            @Test
-            void dispatchShouldWorkAfterRestartForNewKeyRegistration() throws Exception {
-                eventBus.start();
-                EventListener listener = newListener();
-
-                rabbitMQExtension.getRabbitMQ().restart();
-
-                Mono.from(eventBus.register(listener, KEY_1)).block();
-
-                eventBus.dispatch(EVENT, KEY_1).block();
-                assertThatListenerReceiveOneEvent(listener);
-            }
-
-            @Test
-            void dispatchShouldWorkAfterNetworkIssuesForNewRegistration() {
-                eventBus.start();
-                EventListener listener = newListener();
-
-                rabbitMQExtension.getRabbitMQ().pause();
-
-                assertThatThrownBy(() -> eventBus.dispatch(EVENT, NO_KEYS).block())
-                    .isInstanceOf(IllegalStateException.class)
-                    .hasMessageContaining("Retries exhausted");
-
-                rabbitMQExtension.getRabbitMQ().unpause();
-
-                eventBus.register(listener, GROUP_A);
-                eventBus.dispatch(EVENT, NO_KEYS).block();
-                assertThatListenerReceiveOneEvent(listener);
-            }
-
-            @Test
-            void redeliverShouldWorkAfterNetworkIssuesForNewRegistration() {
-                eventBus.start();
-                EventListener listener = newListener();
-
-                rabbitMQExtension.getRabbitMQ().pause();
-
-                assertThatThrownBy(() -> eventBus.reDeliver(GROUP_A, EVENT).block())
-                    .isInstanceOf(GroupRegistrationNotFound.class);
-
-                rabbitMQExtension.getRabbitMQ().unpause();
-
-                eventBus.register(listener, GROUP_A);
-                eventBus.reDeliver(GROUP_A, EVENT).block();
-                assertThatListenerReceiveOneEvent(listener);
-            }
-
-            @Test
-            void dispatchShouldWorkAfterNetworkIssuesForOldKeyRegistration() {
-                eventBus.start();
-                EventListener listener = newListener();
-                when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
-                Mono.from(eventBus.register(listener, KEY_1)).block();
-
-                rabbitMQExtension.getRabbitMQ().pause();
-
-                assertThatThrownBy(() -> eventBus.dispatch(EVENT, NO_KEYS).block())
-                    .isInstanceOf(IllegalStateException.class)
-                    .hasMessageContaining("Retries exhausted");
-
-                rabbitMQExtension.getRabbitMQ().unpause();
-
-                eventBus.dispatch(EVENT, KEY_1).block();
-                assertThatListenerReceiveOneEvent(listener);
-            }
-
-            @Test
-            void dispatchShouldWorkAfterNetworkIssuesForNewKeyRegistration() {
-                eventBus.start();
-                EventListener listener = newListener();
-                when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
-
-                rabbitMQExtension.getRabbitMQ().pause();
-
-                assertThatThrownBy(() -> eventBus.dispatch(EVENT, NO_KEYS).block())
-                    .isInstanceOf(IllegalStateException.class)
-                    .hasMessageContaining("Retries exhausted");
-
-                rabbitMQExtension.getRabbitMQ().unpause();
-
-                Mono.from(eventBus.register(listener, KEY_1)).block();
-                eventBus.dispatch(EVENT, KEY_1).block();
-                assertThatListenerReceiveOneEvent(listener);
-            }
-
-            @Test
-            void stopShouldNotDeleteEventBusExchange() {
-                eventBus.start();
-                eventBus.stop();
-
-                assertThat(rabbitManagementAPI.listExchanges())
-                    .anySatisfy(exchange -> assertThat(exchange.getName()).isEqualTo(MAILBOX_EVENT_EXCHANGE_NAME));
-            }
-
-            @Test
-            void stopShouldNotDeleteGroupRegistrationWorkQueue() {
-                eventBus.start();
-                eventBus.register(mock(EventListener.class), GROUP_A);
-                eventBus.stop();
-
-                assertThat(rabbitManagementAPI.listQueues())
-                    .anySatisfy(queue -> assertThat(queue.getName()).contains(GroupA.class.getName()));
-            }
-
-            @Test
-            void eventBusShouldNotThrowWhenContinuouslyStartAndStop() {
-                assertThatCode(() -> {
-                    eventBus.start();
-                    eventBus.stop();
-                    eventBus.stop();
-                    eventBus.start();
-                    eventBus.start();
-                    eventBus.start();
-                    eventBus.stop();
-                    eventBus.stop();
-                }).doesNotThrowAnyException();
-            }
-
-            @Test
-            void dispatchShouldStopDeliveringEventsShortlyAfterStopIsCalled() throws Exception {
-                eventBus.start();
-
-                EventListenerCountingSuccessfulExecution listener = new EventListenerCountingSuccessfulExecution();
-                eventBus.register(listener, GROUP_A);
-
-                try (Closeable closeable = ConcurrentTestRunner.builder()
-                    .operation((threadNumber, step) -> eventBus.dispatch(EVENT, KEY_1).block())
-                    .threadCount(THREAD_COUNT)
-                    .operationCount(OPERATION_COUNT)
-                    .noErrorLogs()
-                    .run()) {
-
-                    TimeUnit.SECONDS.sleep(2);
-
-                    eventBus.stop();
-                    eventBus2.stop();
-                    int callsAfterStop = listener.numberOfEventCalls();
-
-                    TimeUnit.SECONDS.sleep(1);
-                    assertThat(listener.numberOfEventCalls())
-                        .isCloseTo(callsAfterStop, Percentage.withPercentage(2));
-                }
-            }
-        }
-
-        @Nested
-        class MultiEventBus {
-
-            @Test
-            void multipleEventBusStartShouldCreateOnlyOneEventExchange() {
-                assertThat(rabbitManagementAPI.listExchanges())
-                    .filteredOn(exchange -> exchange.getName().equals(MAILBOX_EVENT_EXCHANGE_NAME))
-                    .hasSize(1);
-            }
-
-            @Test
-            void multipleEventBusShouldNotThrowWhenStartAndStopContinuously() {
-                assertThatCode(() -> {
-                    eventBus.start();
-                    eventBus.start();
-                    eventBus2.start();
-                    eventBus2.start();
-                    eventBus.stop();
-                    eventBus.stop();
-                    eventBus.stop();
-                    eventBus3.start();
-                    eventBus3.start();
-                    eventBus3.start();
-                    eventBus3.stop();
-                    eventBus.start();
-                    eventBus2.start();
-                    eventBus.stop();
-                    eventBus2.stop();
-                }).doesNotThrowAnyException();
-            }
-
-            @Test
-            void multipleEventBusStopShouldNotDeleteEventBusExchange() {
-                eventBus.stop();
-                eventBus2.stop();
-                eventBus3.stop();
-                eventBusWithKeyHandlerNotStarted.stop();
-
-                assertThat(rabbitManagementAPI.listExchanges())
-                    .anySatisfy(exchange -> assertThat(exchange.getName()).isEqualTo(MAILBOX_EVENT_EXCHANGE_NAME));
-            }
-
-            @Test
-            void multipleEventBusStopShouldNotDeleteGroupRegistrationWorkQueue() {
-                eventBus.register(mock(EventListener.class), GROUP_A);
-
-                eventBus.stop();
-                eventBus2.stop();
-                eventBus3.stop();
-                eventBusWithKeyHandlerNotStarted.stop();
-
-                assertThat(rabbitManagementAPI.listQueues())
-                    .anySatisfy(queue -> assertThat(queue.getName()).contains(GroupA.class.getName()));
-            }
-
-            @Test
-            void multipleEventBusStopShouldDeleteAllKeyRegistrationsWorkQueue() {
-                eventBus.stop();
-                eventBus2.stop();
-                eventBus3.stop();
-                eventBusWithKeyHandlerNotStarted.stop();
-
-                assertThat(rabbitManagementAPI.listQueues())
-                    .filteredOn(queue -> !queue.getName().startsWith(MAILBOX_EVENT_WORK_QUEUE_PREFIX)
-                        && !queue.getName().startsWith(MAILBOX_EVENT_DEAD_LETTER_QUEUE))
-                    .isEmpty();
-            }
-
-            @Test
-            void dispatchShouldStopDeliveringEventsShortlyAfterStopIsCalled() throws Exception {
-                eventBus.start();
-                eventBus2.start();
-
-                EventListenerCountingSuccessfulExecution listener = new EventListenerCountingSuccessfulExecution();
-                eventBus.register(listener, GROUP_A);
-                eventBus2.register(listener, GROUP_A);
-
-                try (Closeable closeable = ConcurrentTestRunner.builder()
-                    .operation((threadNumber, step) -> eventBus.dispatch(EVENT, KEY_1).block())
-                    .threadCount(THREAD_COUNT)
-                    .operationCount(OPERATION_COUNT)
-                    .noErrorLogs()
-                    .run()) {
-
-                    TimeUnit.SECONDS.sleep(2);
-
-                    eventBus.stop();
-                    eventBus2.stop();
-                    int callsAfterStop = listener.numberOfEventCalls();
-
-                    TimeUnit.SECONDS.sleep(1);
-                    assertThat(listener.numberOfEventCalls())
-                        .isCloseTo(callsAfterStop, Percentage.withPercentage(2));
-                }
-            }
-        }
-
-    }
-
-    @Nested
-    class ErrorDispatchingTest {
-
-        @AfterEach
-        void tearDown() {
-            rabbitMQExtension.getRabbitMQ().unpause();
-        }
-
-        @Test
-        void dispatchShouldNotSendToGroupListenerWhenError() {
-            EventCollector eventCollector = eventCollector();
-            eventBus().register(eventCollector, GROUP_A);
-
-            rabbitMQExtension.getRabbitMQ().pause();
-
-            doQuietly(() -> eventBus().dispatch(EVENT, NO_KEYS).block());
-
-            assertThat(eventCollector.getEvents()).isEmpty();
-        }
-
-        @Test
-        void dispatchShouldPersistEventWhenDispatchingNoKeyGetError() {
-            EventCollector eventCollector = eventCollector();
-            eventBus().register(eventCollector, GROUP_A);
-
-            rabbitMQExtension.getRabbitMQ().pause();
-
-            doQuietly(() -> eventBus().dispatch(EVENT, NO_KEYS).block());
-
-            assertThat(dispatchingFailureEvents()).containsOnly(EVENT);
-        }
-
-        @Test
-        void dispatchShouldPersistEventWhenDispatchingWithKeysGetError() {
-            EventCollector eventCollector = eventCollector();
-            eventBus().register(eventCollector, GROUP_A);
-            Mono.from(eventBus().register(eventCollector, KEY_1)).block();
-
-            rabbitMQExtension.getRabbitMQ().pause();
-
-            doQuietly(() -> eventBus().dispatch(EVENT, NO_KEYS).block());
-
-            assertThat(dispatchingFailureEvents()).containsOnly(EVENT);
-        }
-
-        @Test
-        void dispatchShouldPersistOnlyOneEventWhenDispatchingMultiGroupsGetError() {
-            EventCollector eventCollector = eventCollector();
-            eventBus().register(eventCollector, GROUP_A);
-            eventBus().register(eventCollector, GROUP_B);
-
-            rabbitMQExtension.getRabbitMQ().pause();
-
-            doQuietly(() -> eventBus().dispatch(EVENT, NO_KEYS).block());
-
-            assertThat(dispatchingFailureEvents()).containsOnly(EVENT);
-        }
-
-        @Test
-        void dispatchShouldPersistEventsWhenDispatchingGroupsGetErrorMultipleTimes() {
-            EventCollector eventCollector = eventCollector();
-            eventBus().register(eventCollector, GROUP_A);
-
-            rabbitMQExtension.getRabbitMQ().pause();
-            doQuietly(() -> eventBus().dispatch(EVENT, NO_KEYS).block());
-            doQuietly(() -> eventBus().dispatch(EVENT_2, NO_KEYS).block());
-
-            assertThat(dispatchingFailureEvents()).containsExactly(EVENT, EVENT_2);
-        }
-
-        @Test
-        void dispatchShouldPersistEventsWhenDispatchingTheSameEventGetErrorMultipleTimes() {
-            EventCollector eventCollector = eventCollector();
-            eventBus().register(eventCollector, GROUP_A);
-
-            rabbitMQExtension.getRabbitMQ().pause();
-            doQuietly(() -> eventBus().dispatch(EVENT, NO_KEYS).block());
-            doQuietly(() -> eventBus().dispatch(EVENT, NO_KEYS).block());
-
-            assertThat(dispatchingFailureEvents()).containsExactly(EVENT, EVENT);
-        }
-
-        @Test
-        void reDeliverShouldDeliverToAllGroupsWhenDispatchingFailure() {
-            EventCollector eventCollector = eventCollector();
-            eventBus().register(eventCollector, GROUP_A);
-
-            EventCollector eventCollector2 = eventCollector();
-            eventBus().register(eventCollector2, GROUP_B);
-
-            rabbitMQExtension.getRabbitMQ().pause();
-            doQuietly(() -> eventBus().dispatch(EVENT, NO_KEYS).block());
-            rabbitMQExtension.getRabbitMQ().unpause();
-            dispatchingFailureEvents()
-                .forEach(event -> eventBus().reDeliver(DispatchingFailureGroup.INSTANCE, event).block());
-
-            getSpeedProfile().shortWaitCondition()
-                .untilAsserted(() -> assertThat(eventCollector.getEvents())
-                    .hasSameElementsAs(eventCollector2.getEvents())
-                    .containsExactly(EVENT));
-        }
-
-        @Test
-        void reDeliverShouldAddEventInDeadLetterWhenGettingError() {
-            EventCollector eventCollector = eventCollector();
-            eventBus().register(eventCollector, GROUP_A);
-
-            rabbitMQExtension.getRabbitMQ().pause();
-            doQuietly(() -> eventBus().dispatch(EVENT, NO_KEYS).block());
-            getSpeedProfile().longWaitCondition()
-                .until(() -> deadLetter().containEvents().block());
-
-            doQuietly(() -> eventBus().reDeliver(DispatchingFailureGroup.INSTANCE, EVENT).block());
-            rabbitMQExtension.getRabbitMQ().unpause();
-
-            getSpeedProfile().shortWaitCondition()
-                .untilAsserted(() -> assertThat(dispatchingFailureEvents())
-                    .containsExactly(EVENT, EVENT));
-        }
-
-        @Test
-        void reDeliverShouldNotStoreEventInAnotherGroupWhenGettingError() {
-            EventCollector eventCollector = eventCollector();
-            eventBus().register(eventCollector, GROUP_A);
-
-            rabbitMQExtension.getRabbitMQ().pause();
-            doQuietly(() -> eventBus().dispatch(EVENT, NO_KEYS).block());
-            getSpeedProfile().longWaitCondition()
-                .until(() -> deadLetter().containEvents().block());
-
-            doQuietly(() -> eventBus().reDeliver(DispatchingFailureGroup.INSTANCE, EVENT).block());
-            rabbitMQExtension.getRabbitMQ().unpause();
-
-            getSpeedProfile().shortWaitCondition()
-                .untilAsserted(() -> assertThat(deadLetter().groupsWithFailedEvents().toStream())
-                    .hasOnlyElementsOfType(DispatchingFailureGroup.class));
-        }
-
-        private Stream<Event> dispatchingFailureEvents() {
-            return deadLetter().failedIds(DispatchingFailureGroup.INSTANCE)
-                .flatMap(insertionId -> deadLetter().failedEvent(DispatchingFailureGroup.INSTANCE, insertionId))
-                .toStream();
-        }
-
-        private void doQuietly(Runnable runnable) {
-            try {
-                runnable.run();
-            } catch (Exception e) {
-                // ignore
-            }
-        }
-    }
-
-    private void assertThatListenerReceiveOneEvent(EventListener listener) {
-        RabbitMQFixture.awaitAtMostThirtySeconds
-            .untilAsserted(() -> verify(listener).event(EVENT));
-    }
-}
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RoutingKeyConverterTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RoutingKeyConverterTest.java
deleted file mode 100644
index 9fb93dc..0000000
--- a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RoutingKeyConverterTest.java
+++ /dev/null
@@ -1,144 +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.mailbox.events;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import java.util.Objects;
-
-import org.apache.james.events.RegistrationKey;
-import org.apache.james.mailbox.model.TestId;
-import org.junit.jupiter.api.Test;
-
-class RoutingKeyConverterTest {
-    static class TestRegistrationKey implements RegistrationKey {
-        static class Factory implements RegistrationKey.Factory {
-            @Override
-            public Class<? extends RegistrationKey> forClass() {
-                return TestRegistrationKey.class;
-            }
-
-            @Override
-            public RegistrationKey fromString(String asString) {
-                return new TestRegistrationKey(asString);
-            }
-        }
-
-        private final String value;
-
-        TestRegistrationKey(String value) {
-            this.value = value;
-        }
-
-        @Override
-        public String asString() {
-            return value;
-        }
-
-        @Override
-        public final boolean equals(Object o) {
-            if (o instanceof TestRegistrationKey) {
-                TestRegistrationKey that = (TestRegistrationKey) o;
-
-                return Objects.equals(this.value, that.value);
-            }
-            return false;
-        }
-
-        @Override
-        public final int hashCode() {
-            return Objects.hash(value);
-        }
-    }
-
-    private static final RegistrationKey REGISTRATION_KEY_1 = new MailboxIdRegistrationKey(TestId.of(42));
-    private static final String ROUTING_KEY_1 = "org.apache.james.mailbox.events.MailboxIdRegistrationKey:42";
-
-    private RoutingKeyConverter testee = RoutingKeyConverter.forFactories(
-        new TestRegistrationKey.Factory(),
-        new MailboxIdRegistrationKey.Factory(new TestId.Factory()));
-
-    @Test
-    void toRoutingKeyShouldTransformAKeyIntoAString() {
-        assertThat(RoutingKeyConverter.RoutingKey.of(REGISTRATION_KEY_1).asString())
-            .isEqualTo(ROUTING_KEY_1);
-    }
-
-    @Test
-    void toRegistrationKeyShouldReturnCorrespondingRoutingKey() {
-        assertThat(testee.toRegistrationKey(ROUTING_KEY_1))
-            .isEqualTo(REGISTRATION_KEY_1);
-    }
-
-    @Test
-    void toRoutingKeyShouldAcceptSeparator() {
-        assertThat(RoutingKeyConverter.RoutingKey.of(new TestRegistrationKey("a:b")).asString())
-            .isEqualTo("org.apache.james.mailbox.events.RoutingKeyConverterTest$TestRegistrationKey:a:b");
-    }
-
-    @Test
-    void toRegistrationKeyShouldAcceptSeparator() {
-        assertThat(testee.toRegistrationKey("org.apache.james.mailbox.events.RoutingKeyConverterTest$TestRegistrationKey:a:b"))
-            .isEqualTo(new TestRegistrationKey("a:b"));
-    }
-
-    @Test
-    void toRoutingKeyShouldAcceptEmptyValue() {
-        assertThat(RoutingKeyConverter.RoutingKey.of(new TestRegistrationKey("")).asString())
-            .isEqualTo("org.apache.james.mailbox.events.RoutingKeyConverterTest$TestRegistrationKey:");
-    }
-
-    @Test
-    void toRegistrationKeyShouldAcceptEmptyValue() {
-        assertThat(testee.toRegistrationKey("org.apache.james.mailbox.events.RoutingKeyConverterTest$TestRegistrationKey:"))
-            .isEqualTo(new TestRegistrationKey(""));
-    }
-
-    @Test
-    void toRegistrationKeyShouldRejectNull() {
-        assertThatThrownBy(() -> testee.toRegistrationKey(null))
-            .isInstanceOf(NullPointerException.class);
-    }
-
-    @Test
-    void toRegistrationKeyShouldRejectEmptyString() {
-        assertThatThrownBy(() -> testee.toRegistrationKey(""))
-            .isInstanceOf(IllegalArgumentException.class);
-    }
-
-    @Test
-    void toRegistrationKeyShouldRejectNoSeparator() {
-        assertThatThrownBy(() -> testee.toRegistrationKey("noSeparator"))
-            .isInstanceOf(IllegalArgumentException.class);
-    }
-
-    @Test
-    void toRegistrationKeyShouldRejectUnknownRegistrationKeyClass() {
-        assertThatThrownBy(() -> testee.toRegistrationKey("unknown:"))
-            .isInstanceOf(IllegalArgumentException.class);
-    }
-
-    @Test
-    void toRegistrationKeyShouldRejectInvalidValue() {
-        assertThatThrownBy(() -> testee.toRegistrationKey("org.apache.james.mailbox.events.MailboxIdRegistrationKey:invalid"))
-            .isInstanceOf(IllegalArgumentException.class);
-    }
-}
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/WaitDelayGeneratorTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/WaitDelayGeneratorTest.java
deleted file mode 100644
index e7f1fb6..0000000
--- a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/WaitDelayGeneratorTest.java
+++ /dev/null
@@ -1,103 +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.mailbox.events;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.time.Duration;
-
-import org.assertj.core.api.SoftAssertions;
-import org.junit.jupiter.api.Test;
-
-class WaitDelayGeneratorTest {
-
-    @Test
-    void generateDelayShouldReturnZeroWhenZeroRetryCount() {
-        WaitDelayGenerator generator = WaitDelayGenerator.of(RetryBackoffConfiguration.DEFAULT);
-
-        assertThat(generator.generateDelay(0))
-            .isEqualTo(Duration.ofMillis(0));
-    }
-
-    @Test
-    void generateDelayShouldReturnByRandomInRangeOfExponentialGrowthOfRetryCount() {
-        WaitDelayGenerator generator = WaitDelayGenerator.of(RetryBackoffConfiguration.builder()
-            .maxRetries(4)
-            .firstBackoff(Duration.ofMillis(100))
-            .jitterFactor(0.5)
-            .build());
-
-        SoftAssertions.assertSoftly(softly -> {
-            softly.assertThat(generator.generateDelay(1).toMillis())
-                .isBetween(50L, 150L);
-            softly.assertThat(generator.generateDelay(2).toMillis())
-                .isBetween(100L, 300L);
-            softly.assertThat(generator.generateDelay(3).toMillis())
-                .isBetween(200L, 600L);
-            softly.assertThat(generator.generateDelay(4).toMillis())
-                .isBetween(300L, 1200L);
-        });
-    }
-
-    @Test
-    void generateDelayShouldReturnZeroWhenZeroMaxRetries() {
-        WaitDelayGenerator generator = WaitDelayGenerator.of(RetryBackoffConfiguration.builder()
-            .maxRetries(0)
-            .firstBackoff(Duration.ofMillis(1000))
-            .jitterFactor(0.5)
-            .build());
-
-        SoftAssertions.assertSoftly(softly -> {
-            softly.assertThat(generator.generateDelay(1)).isEqualTo(Duration.ZERO);
-            softly.assertThat(generator.generateDelay(2)).isEqualTo(Duration.ZERO);
-            softly.assertThat(generator.generateDelay(3)).isEqualTo(Duration.ZERO);
-        });
-    }
-
-    @Test
-    void generateDelayShouldReturnZeroWhenZeroFirstBackOff() {
-        WaitDelayGenerator generator = WaitDelayGenerator.of(RetryBackoffConfiguration.builder()
-            .maxRetries(3)
-            .firstBackoff(Duration.ZERO)
-            .jitterFactor(0.5)
-            .build());
-
-        SoftAssertions.assertSoftly(softly -> {
-            softly.assertThat(generator.generateDelay(1)).isEqualTo(Duration.ZERO);
-            softly.assertThat(generator.generateDelay(2)).isEqualTo(Duration.ZERO);
-            softly.assertThat(generator.generateDelay(3)).isEqualTo(Duration.ZERO);
-        });
-    }
-
-    @Test
-    void generateDelayShouldReturnFloorOfExponentialGrowthStepsWhenZeroJitterFactor() {
-        WaitDelayGenerator generator = WaitDelayGenerator.of(RetryBackoffConfiguration.builder()
-            .maxRetries(3)
-            .firstBackoff(Duration.ofMillis(100))
-            .jitterFactor(0.0)
-            .build());
-
-        SoftAssertions.assertSoftly(softly -> {
-            softly.assertThat(generator.generateDelay(1)).isEqualTo(Duration.ofMillis(100));
-            softly.assertThat(generator.generateDelay(2)).isEqualTo(Duration.ofMillis(200));
-            softly.assertThat(generator.generateDelay(3)).isEqualTo(Duration.ofMillis(400));
-        });
-    }
-}
\ No newline at end of file
diff --git a/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala b/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala
index fa7c110..6708055 100644
--- a/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala
+++ b/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala
@@ -30,9 +30,9 @@ import org.apache.james.event.json.DTOs.SystemFlag.SystemFlag
 import org.apache.james.event.json.DTOs._
 import org.apache.james.events
 import org.apache.james.events.Event.EventId
+import org.apache.james.events.MailboxEvents.{Added => JavaAdded, Expunged => JavaExpunged, FlagsUpdated => JavaFlagsUpdated, MailboxACLUpdated => JavaMailboxACLUpdated, MailboxAdded => JavaMailboxAdded, MailboxDeletion => JavaMailboxDeletion, MailboxRenamed => JavaMailboxRenamed, QuotaUsageUpdatedEvent => JavaQuotaUsageUpdatedEvent}
+import org.apache.james.events.MessageMoveEvent
 import org.apache.james.mailbox.MailboxSession.SessionId
-import org.apache.james.mailbox.events.MailboxEvents.{Added => JavaAdded, Expunged => JavaExpunged, FlagsUpdated => JavaFlagsUpdated, MailboxACLUpdated => JavaMailboxACLUpdated, MailboxAdded => JavaMailboxAdded, MailboxDeletion => JavaMailboxDeletion, MailboxRenamed => JavaMailboxRenamed, QuotaUsageUpdatedEvent => JavaQuotaUsageUpdatedEvent}
-import org.apache.james.mailbox.events.{MessageMoveEvent => JavaMessageMoveEvent}
 import org.apache.james.mailbox.model.{MailboxId, MessageId, MessageMoves, QuotaRoot, MailboxACL => JavaMailboxACL, MessageMetaData => JavaMessageMetaData, Quota => JavaQuota}
 import org.apache.james.mailbox.quota.QuotaRootDeserializer
 import org.apache.james.mailbox.{MessageUid, ModSeq}
@@ -174,7 +174,7 @@ private object ScalaConverter {
     mailboxId = event.getMailboxId,
     expunged = event.getExpunged.asScala.view.mapValues(DTOs.MessageMetaData.fromJava).toMap)
 
-  private def toScala(event: JavaMessageMoveEvent): DTO.MessageMoveEvent = DTO.MessageMoveEvent(
+  private def toScala(event: MessageMoveEvent): DTO.MessageMoveEvent = DTO.MessageMoveEvent(
     eventId = event.getEventId,
     user = event.getUsername,
     previousMailboxIds = event.getMessageMoves.getPreviousMailboxIds.asScala.toSet,
@@ -197,7 +197,7 @@ private object ScalaConverter {
     case e: JavaMailboxAdded => toScala(e)
     case e: JavaMailboxDeletion => toScala(e)
     case e: JavaMailboxRenamed => toScala(e)
-    case e: JavaMessageMoveEvent => toScala(e)
+    case e: MessageMoveEvent => toScala(e)
     case e: JavaQuotaUsageUpdatedEvent => toScala(e)
     case _ => throw new RuntimeException("no Scala conversion known")
   }
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
index 7477cad..2f9c48a 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
@@ -33,11 +33,11 @@ import java.util.SortedMap;
 import javax.mail.Flags;
 
 import org.apache.james.core.Username;
+import org.apache.james.events.MailboxEvents.Added;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
-import org.apache.james.mailbox.events.MailboxEvents.Added;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java
index 866f241..ab5bd33 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java
@@ -33,11 +33,11 @@ import java.util.NoSuchElementException;
 import javax.mail.Flags;
 
 import org.apache.james.core.Username;
+import org.apache.james.events.MailboxEvents.Expunged;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
-import org.apache.james.mailbox.events.MailboxEvents.Expunged;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java
index d90e7df..2e5fbf1 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java
@@ -31,11 +31,11 @@ import java.util.NoSuchElementException;
 import javax.mail.Flags;
 
 import org.apache.james.core.Username;
+import org.apache.james.events.MailboxEvents.FlagsUpdated;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
-import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java
index e957e53..20e1888 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java
@@ -28,9 +28,9 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import java.util.NoSuchElementException;
 
 import org.apache.james.core.Username;
+import org.apache.james.events.MailboxEvents.MailboxACLUpdated;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.acl.ACLDiff;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxACLUpdated;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxAddedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxAddedSerializationTest.java
index 1063d2f..6ebc085 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxAddedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxAddedSerializationTest.java
@@ -28,8 +28,8 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import java.util.NoSuchElementException;
 
 import org.apache.james.core.Username;
+import org.apache.james.events.MailboxEvents.MailboxAdded;
 import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.TestId;
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxDeletionSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxDeletionSerializationTest.java
index 99f7072..4ee6d75 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxDeletionSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxDeletionSerializationTest.java
@@ -34,8 +34,8 @@ import org.apache.james.core.Domain;
 import org.apache.james.core.Username;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeUsage;
+import org.apache.james.events.MailboxEvents.MailboxDeletion;
 import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxRenamedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxRenamedSerializationTest.java
index 18e55d4..9f48940 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxRenamedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxRenamedSerializationTest.java
@@ -29,8 +29,8 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import java.util.NoSuchElementException;
 
 import org.apache.james.core.Username;
+import org.apache.james.events.MailboxEvents.MailboxRenamed;
 import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.events.MailboxEvents.MailboxRenamed;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.TestId;
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageMoveEventSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageMoveEventSerializationTest.java
index b24bc93..9a74194 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageMoveEventSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageMoveEventSerializationTest.java
@@ -29,7 +29,7 @@ import java.util.NoSuchElementException;
 
 import org.apache.james.core.Username;
 import org.apache.james.events.Event;
-import org.apache.james.mailbox.events.MessageMoveEvent;
+import org.apache.james.events.MessageMoveEvent;
 import org.apache.james.mailbox.model.MessageMoves;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/QuotaUsageUpdatedEventSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/QuotaUsageUpdatedEventSerializationTest.java
index 7991349..0295738 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/QuotaUsageUpdatedEventSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/QuotaUsageUpdatedEventSerializationTest.java
@@ -34,7 +34,7 @@ import org.apache.james.core.quota.QuotaCountLimit;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
-import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
+import org.apache.james.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.mailbox.model.QuotaRoot;
 import org.junit.jupiter.api.Test;
diff --git a/mailbox/jpa/pom.xml b/mailbox/jpa/pom.xml
index 6183cc6..a063405 100644
--- a/mailbox/jpa/pom.xml
+++ b/mailbox/jpa/pom.xml
@@ -54,11 +54,6 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>apache-james-mailbox-event-memory</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
             <artifactId>apache-james-mailbox-store</artifactId>
         </dependency>
         <dependency>
@@ -80,6 +75,11 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-in-vm</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-server-data-jpa</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JpaMailboxManagerProvider.java b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JpaMailboxManagerProvider.java
index 79a6cb1..c7f5738 100644
--- a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JpaMailboxManagerProvider.java
+++ b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JpaMailboxManagerProvider.java
@@ -22,16 +22,16 @@ package org.apache.james.mailbox.jpa;
 import javax.persistence.EntityManagerFactory;
 
 import org.apache.james.backends.jpa.JpaTestCluster;
+import org.apache.james.events.EventBusTestFixture;
+import org.apache.james.events.InVMEventBus;
+import org.apache.james.events.MemoryEventDeadLetters;
+import org.apache.james.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.Authenticator;
 import org.apache.james.mailbox.Authorizator;
 import org.apache.james.mailbox.acl.GroupMembershipResolver;
 import org.apache.james.mailbox.acl.MailboxACLResolver;
 import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
 import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
-import org.apache.james.mailbox.events.EventBusTestFixture;
-import org.apache.james.mailbox.events.InVMEventBus;
-import org.apache.james.mailbox.events.MemoryEventDeadLetters;
-import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.jpa.mail.JPAModSeqProvider;
 import org.apache.james.mailbox.jpa.mail.JPAUidProvider;
 import org.apache.james.mailbox.jpa.openjpa.OpenJPAMailboxManager;
diff --git a/mailbox/lucene/pom.xml b/mailbox/lucene/pom.xml
index caeceb3..bc59f6a 100644
--- a/mailbox/lucene/pom.xml
+++ b/mailbox/lucene/pom.xml
@@ -44,11 +44,6 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>apache-james-mailbox-event-memory</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
             <artifactId>apache-james-mailbox-memory</artifactId>
             <scope>test</scope>
         </dependency>
@@ -70,6 +65,11 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-in-vm</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>metrics-tests</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mailbox/maildir/pom.xml b/mailbox/maildir/pom.xml
index 29cd01c..562dcca 100644
--- a/mailbox/maildir/pom.xml
+++ b/mailbox/maildir/pom.xml
@@ -44,12 +44,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>apache-james-mailbox-event-memory</artifactId>
-            <scope>test</scope>
+            <artifactId>apache-james-mailbox-store</artifactId>
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>apache-james-mailbox-store</artifactId>
+            <artifactId>event-bus-in-vm</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
diff --git a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirMailboxManagerProvider.java b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirMailboxManagerProvider.java
index c68f597..6a90c97 100644
--- a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirMailboxManagerProvider.java
+++ b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirMailboxManagerProvider.java
@@ -21,16 +21,16 @@ package org.apache.james.mailbox.maildir;
 
 import java.io.File;
 
+import org.apache.james.events.EventBusTestFixture;
+import org.apache.james.events.InVMEventBus;
+import org.apache.james.events.MemoryEventDeadLetters;
+import org.apache.james.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.Authenticator;
 import org.apache.james.mailbox.Authorizator;
 import org.apache.james.mailbox.acl.GroupMembershipResolver;
 import org.apache.james.mailbox.acl.MailboxACLResolver;
 import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
 import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
-import org.apache.james.mailbox.events.EventBusTestFixture;
-import org.apache.james.mailbox.events.InVMEventBus;
-import org.apache.james.mailbox.events.MemoryEventDeadLetters;
-import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.store.JVMMailboxPathLocker;
 import org.apache.james.mailbox.store.MailboxManagerConfiguration;
 import org.apache.james.mailbox.store.PreDeletionHooks;
diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryIntegrationResources.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryIntegrationResources.java
index bc172a8..10cf638 100644
--- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryIntegrationResources.java
+++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryIntegrationResources.java
@@ -24,7 +24,11 @@ import java.util.Optional;
 import java.util.function.Function;
 
 import org.apache.james.events.EventBus;
+import org.apache.james.events.EventBusTestFixture;
 import org.apache.james.events.EventListener;
+import org.apache.james.events.InVMEventBus;
+import org.apache.james.events.MemoryEventDeadLetters;
+import org.apache.james.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.AttachmentContentLoader;
... 1361 lines suppressed ...


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


[james-project] 16/18: JAMES-3498 Rename variable/classes to remove `mailbox` name component

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 206f1df7c0c9c00b4c72181ee4b6e26518876547
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Feb 1 14:46:49 2021 +0700

    JAMES-3498 Rename variable/classes to remove `mailbox` name component
    
    Before:
    
    ```
    $ grep -i mailbox * -R | wc -l
    212
    ```
    
    After:
    
    ```
    ~/Documents/james-project/event-bus$ grep -i mailbox * -R | wc -l
    57
    ```
    
    Remaining usages are mostly due to RabbitMQ queues/exchanges names
---
 .../java/org/apache/james/events/EventBus.java     | 12 ++++----
 .../james/events/EventDeadLettersHealthCheck.java  |  2 +-
 .../org/apache/james/events/EventListener.java     |  4 +--
 .../EventDeadLettersHealthCheckContract.java       |  2 +-
 .../org/apache/james/events/GroupContract.java     | 32 +++++++++++-----------
 .../java/org/apache/james/events/GroupTest.java    |  2 +-
 .../java/org/apache/james/events/KeyContract.java  | 30 ++++++++++----------
 .../org/apache/james/events/EventDispatcher.java   | 12 ++++----
 .../org/apache/james/events/GroupRegistration.java | 16 +++++------
 .../james/events/GroupRegistrationHandler.java     |  8 +++---
 .../james/events/KeyRegistrationHandler.java       | 10 +++----
 ...ListenerExecutor.java => ListenerExecutor.java} |  6 ++--
 .../apache/james/events/LocalListenerRegistry.java |  2 +-
 .../org/apache/james/events/RabbitMQEventBus.java  | 16 +++++------
 .../james/events/LocalListenerRegistryTest.java    | 30 ++++++++++----------
 .../java/org/apache/james/events/InVMEventBus.java |  6 ++--
 .../james/events/delivery/EventDelivery.java       | 12 ++++----
 .../james/events/delivery/InVmEventDelivery.java   | 18 ++++++------
 18 files changed, 110 insertions(+), 110 deletions(-)

diff --git a/event-bus/api/src/main/java/org/apache/james/events/EventBus.java b/event-bus/api/src/main/java/org/apache/james/events/EventBus.java
index 2429107..21246e0 100644
--- a/event-bus/api/src/main/java/org/apache/james/events/EventBus.java
+++ b/event-bus/api/src/main/java/org/apache/james/events/EventBus.java
@@ -41,8 +41,8 @@ public interface EventBus {
     }
 
     interface Metrics {
-        static String timerName(EventListener mailboxListener) {
-            return "mailbox-listener-" + mailboxListener.getClass().getSimpleName();
+        static String timerName(EventListener listener) {
+            return "mailbox-listener-" + listener.getClass().getSimpleName();
         }
     }
 
@@ -66,11 +66,11 @@ public interface EventBus {
         return dispatch(event, ImmutableSet.of(key));
     }
 
-    default Registration register(EventListener.GroupEventListener groupMailboxListener) {
-        return register(EventListener.wrapReactive(groupMailboxListener));
+    default Registration register(EventListener.GroupEventListener groupListener) {
+        return register(EventListener.wrapReactive(groupListener));
     }
 
-    default Registration register(EventListener.ReactiveGroupEventListener groupMailboxListener) {
-        return register(groupMailboxListener, groupMailboxListener.getDefaultGroup());
+    default Registration register(EventListener.ReactiveGroupEventListener groupListener) {
+        return register(groupListener, groupListener.getDefaultGroup());
     }
 }
diff --git a/event-bus/api/src/main/java/org/apache/james/events/EventDeadLettersHealthCheck.java b/event-bus/api/src/main/java/org/apache/james/events/EventDeadLettersHealthCheck.java
index 98ccc0f..b398a23 100644
--- a/event-bus/api/src/main/java/org/apache/james/events/EventDeadLettersHealthCheck.java
+++ b/event-bus/api/src/main/java/org/apache/james/events/EventDeadLettersHealthCheck.java
@@ -47,7 +47,7 @@ public class EventDeadLettersHealthCheck implements HealthCheck {
         return eventDeadLetters.containEvents()
             .map(containEvents -> {
                 if (containEvents) {
-                    return Result.degraded(COMPONENT_NAME, "EventDeadLetters contain events. This might indicate transient failure on mailbox event processing.");
+                    return Result.degraded(COMPONENT_NAME, "EventDeadLetters contain events. This might indicate transient failure on event processing.");
                 }
 
                 return Result.healthy(COMPONENT_NAME);
diff --git a/event-bus/api/src/main/java/org/apache/james/events/EventListener.java b/event-bus/api/src/main/java/org/apache/james/events/EventListener.java
index be50c12..e820283 100644
--- a/event-bus/api/src/main/java/org/apache/james/events/EventListener.java
+++ b/event-bus/api/src/main/java/org/apache/james/events/EventListener.java
@@ -120,8 +120,8 @@ public interface EventListener {
         return new ReactiveWrapper<>(listener);
     }
 
-    static ReactiveGroupEventListener wrapReactive(GroupEventListener groupMailboxListener) {
-        return new ReactiveGroupWrapper(groupMailboxListener);
+    static ReactiveGroupEventListener wrapReactive(GroupEventListener groupEventListener) {
+        return new ReactiveGroupWrapper(groupEventListener);
     }
 
     default ExecutionMode getExecutionMode() {
diff --git a/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java b/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java
index fd1bb22..e0cf4a8 100644
--- a/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java
@@ -31,7 +31,7 @@ import org.junit.jupiter.api.Test;
 interface EventDeadLettersHealthCheckContract {
 
     ComponentName COMPONENT_NAME = new ComponentName("EventDeadLettersHealthCheck");
-    String EXPECTED_DEGRADED_MESSAGE = "EventDeadLetters contain events. This might indicate transient failure on mailbox event processing.";
+    String EXPECTED_DEGRADED_MESSAGE = "EventDeadLetters contain events. This might indicate transient failure on event processing.";
 
     Username USERNAME = Username.of("user");
 
diff --git a/event-bus/api/src/test/java/org/apache/james/events/GroupContract.java b/event-bus/api/src/test/java/org/apache/james/events/GroupContract.java
index db42ff7..6a927ee 100644
--- a/event-bus/api/src/test/java/org/apache/james/events/GroupContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/GroupContract.java
@@ -418,20 +418,20 @@ public interface GroupContract {
 
         @Test
         default void groupsDefinedOnlyOnSomeNodesShouldBeNotifiedWhenDispatch() throws Exception {
-            EventListener mailboxListener = EventBusTestFixture.newListener();
+            EventListener listener = EventBusTestFixture.newListener();
 
-            eventBus().register(mailboxListener, GROUP_A);
+            eventBus().register(listener, GROUP_A);
 
             eventBus2().dispatch(EVENT, NO_KEYS).block();
 
-            verify(mailboxListener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void groupsDefinedOnlyOnSomeNodesShouldNotBeNotifiedWhenRedeliver() {
-            EventListener mailboxListener = EventBusTestFixture.newListener();
+            EventListener listener = EventBusTestFixture.newListener();
 
-            eventBus().register(mailboxListener, GROUP_A);
+            eventBus().register(listener, GROUP_A);
 
             assertThatThrownBy(() -> eventBus2().reDeliver(GROUP_A, EVENT).block())
                 .isInstanceOf(GroupRegistrationNotFound.class);
@@ -439,38 +439,38 @@ public interface GroupContract {
 
         @Test
         default void groupListenersShouldBeExecutedOnceWhenRedeliverInADistributedEnvironment() throws Exception {
-            EventListener mailboxListener = EventBusTestFixture.newListener();
+            EventListener listener = EventBusTestFixture.newListener();
 
-            eventBus().register(mailboxListener, GROUP_A);
-            eventBus2().register(mailboxListener, GROUP_A);
+            eventBus().register(listener, GROUP_A);
+            eventBus2().register(listener, GROUP_A);
 
             eventBus2().reDeliver(GROUP_A, EVENT).block();
 
-            verify(mailboxListener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void groupListenersShouldBeExecutedOnceInAControlledEnvironment() throws Exception {
-            EventListener mailboxListener = EventBusTestFixture.newListener();
+            EventListener listener = EventBusTestFixture.newListener();
 
-            eventBus().register(mailboxListener, GROUP_A);
-            eventBus2().register(mailboxListener, GROUP_A);
+            eventBus().register(listener, GROUP_A);
+            eventBus2().register(listener, GROUP_A);
 
             eventBus2().dispatch(EVENT, NO_KEYS).block();
 
-            verify(mailboxListener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void unregisterShouldStopNotificationForDistantGroups() throws Exception {
-            EventListener mailboxListener = EventBusTestFixture.newListener();
+            EventListener listener = EventBusTestFixture.newListener();
 
-            eventBus().register(mailboxListener, GROUP_A).unregister();
+            eventBus().register(listener, GROUP_A).unregister();
 
             eventBus2().dispatch(EVENT, NO_KEYS).block();
 
 
-            verify(mailboxListener, after(FIVE_HUNDRED_MS.toMillis()).never())
+            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
diff --git a/event-bus/api/src/test/java/org/apache/james/events/GroupTest.java b/event-bus/api/src/test/java/org/apache/james/events/GroupTest.java
index 5326e3f..0d8a663 100644
--- a/event-bus/api/src/test/java/org/apache/james/events/GroupTest.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/GroupTest.java
@@ -104,7 +104,7 @@ class GroupTest {
 
     @Test
     void deserializeShouldThrowWhenClassNotFound() {
-        assertThatThrownBy(() -> Group.deserialize("org.apache.james.mailbox.events.Noone"))
+        assertThatThrownBy(() -> Group.deserialize("org.apache.james.events.Noone"))
             .isInstanceOf(Group.GroupDeserializationException.class);
     }
 
diff --git a/event-bus/api/src/test/java/org/apache/james/events/KeyContract.java b/event-bus/api/src/test/java/org/apache/james/events/KeyContract.java
index 52e5a53..1c1c6bd 100644
--- a/event-bus/api/src/test/java/org/apache/james/events/KeyContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/KeyContract.java
@@ -383,13 +383,13 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void crossEventBusRegistrationShouldBeAllowed() throws Exception {
-            EventListener mailboxListener = EventBusTestFixture.newListener();
+            EventListener listener = EventBusTestFixture.newListener();
 
-            Mono.from(eventBus().register(mailboxListener, KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
 
             eventBus2().dispatch(EVENT, KEY_1).block();
 
-            verify(mailboxListener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
@@ -406,16 +406,16 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void allRegisteredListenersShouldBeDispatched() throws Exception {
-            EventListener mailboxListener1 = EventBusTestFixture.newListener();
-            EventListener mailboxListener2 = EventBusTestFixture.newListener();
+            EventListener listener1 = EventBusTestFixture.newListener();
+            EventListener listener2 = EventBusTestFixture.newListener();
 
-            Mono.from(eventBus().register(mailboxListener1, KEY_1)).block();
-            Mono.from(eventBus2().register(mailboxListener2, KEY_1)).block();
+            Mono.from(eventBus().register(listener1, KEY_1)).block();
+            Mono.from(eventBus2().register(listener2, KEY_1)).block();
 
             eventBus2().dispatch(EVENT, KEY_1).block();
 
-            verify(mailboxListener1, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
-            verify(mailboxListener2, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener1, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener2, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
@@ -432,16 +432,16 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void localDispatchedListenersShouldBeDispatchedWithoutDelay() throws Exception {
-            EventListener mailboxListener1 = EventBusTestFixture.newListener();
-            EventListener mailboxListener2 = EventBusTestFixture.newListener();
+            EventListener listener1 = EventBusTestFixture.newListener();
+            EventListener listener2 = EventBusTestFixture.newListener();
 
-            Mono.from(eventBus().register(mailboxListener1, KEY_1)).block();
-            Mono.from(eventBus2().register(mailboxListener2, KEY_1)).block();
+            Mono.from(eventBus().register(listener1, KEY_1)).block();
+            Mono.from(eventBus2().register(listener2, KEY_1)).block();
 
             eventBus2().dispatch(EVENT, KEY_1).block();
 
-            verify(mailboxListener2, times(1)).event(any());
-            verify(mailboxListener1, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener2, times(1)).event(any());
+            verify(listener1, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
     }
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java b/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
index 9543179..9a98aeb 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
@@ -69,12 +69,12 @@ public class EventDispatcher {
     private final Sender sender;
     private final LocalListenerRegistry localListenerRegistry;
     private final AMQP.BasicProperties basicProperties;
-    private final MailboxListenerExecutor mailboxListenerExecutor;
+    private final ListenerExecutor listenerExecutor;
     private final EventDeadLetters deadLetters;
 
     EventDispatcher(EventBusId eventBusId, EventSerializer eventSerializer, Sender sender,
                     LocalListenerRegistry localListenerRegistry,
-                    MailboxListenerExecutor mailboxListenerExecutor,
+                    ListenerExecutor listenerExecutor,
                     EventDeadLetters deadLetters) {
         this.eventSerializer = eventSerializer;
         this.sender = sender;
@@ -85,7 +85,7 @@ public class EventDispatcher {
             .priority(PERSISTENT_TEXT_PLAIN.getPriority())
             .contentType(PERSISTENT_TEXT_PLAIN.getContentType())
             .build();
-        this.mailboxListenerExecutor = mailboxListenerExecutor;
+        this.listenerExecutor = listenerExecutor;
         this.deadLetters = deadLetters;
     }
 
@@ -122,15 +122,15 @@ public class EventDispatcher {
 
     private Mono<Void> dispatchToLocalListeners(Event event, Set<RegistrationKey> keys) {
         return Flux.fromIterable(keys)
-            .flatMap(key -> localListenerRegistry.getLocalMailboxListeners(key)
+            .flatMap(key -> localListenerRegistry.getLocalListeners(key)
                 .map(listener -> Tuples.of(key, listener)), EventBus.EXECUTION_RATE)
             .filter(pair -> pair.getT2().getExecutionMode() == EventListener.ExecutionMode.SYNCHRONOUS)
             .flatMap(pair -> executeListener(event, pair.getT2(), pair.getT1()), EventBus.EXECUTION_RATE)
             .then();
     }
 
-    private Mono<Void> executeListener(Event event, EventListener.ReactiveEventListener mailboxListener, RegistrationKey registrationKey) {
-        return mailboxListenerExecutor.execute(mailboxListener,
+    private Mono<Void> executeListener(Event event, EventListener.ReactiveEventListener listener, RegistrationKey registrationKey) {
+        return listenerExecutor.execute(listener,
                     MDCBuilder.create()
                         .addContext(EventBus.StructuredLoggingFields.REGISTRATION_KEY, registrationKey),
                     event)
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java
index 07739ac..3b16688 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java
@@ -76,7 +76,7 @@ class GroupRegistration implements Registration {
     static final int DEFAULT_RETRY_COUNT = 0;
 
     private final ReactorRabbitMQChannelPool channelPool;
-    private final EventListener.ReactiveEventListener mailboxListener;
+    private final EventListener.ReactiveEventListener listener;
     private final WorkQueueName queueName;
     private final Receiver receiver;
     private final Runnable unregisterGroup;
@@ -86,21 +86,21 @@ class GroupRegistration implements Registration {
     private final WaitDelayGenerator delayGenerator;
     private final Group group;
     private final RetryBackoffConfiguration retryBackoff;
-    private final MailboxListenerExecutor mailboxListenerExecutor;
+    private final ListenerExecutor listenerExecutor;
     private Optional<Disposable> receiverSubscriber;
 
     GroupRegistration(ReactorRabbitMQChannelPool channelPool, Sender sender, ReceiverProvider receiverProvider, EventSerializer eventSerializer,
-                      EventListener.ReactiveEventListener mailboxListener, Group group, RetryBackoffConfiguration retryBackoff,
+                      EventListener.ReactiveEventListener listener, Group group, RetryBackoffConfiguration retryBackoff,
                       EventDeadLetters eventDeadLetters,
-                      Runnable unregisterGroup, MailboxListenerExecutor mailboxListenerExecutor) {
+                      Runnable unregisterGroup, ListenerExecutor listenerExecutor) {
         this.channelPool = channelPool;
         this.eventSerializer = eventSerializer;
-        this.mailboxListener = mailboxListener;
+        this.listener = listener;
         this.queueName = WorkQueueName.of(group);
         this.sender = sender;
         this.receiver = receiverProvider.createReceiver();
         this.retryBackoff = retryBackoff;
-        this.mailboxListenerExecutor = mailboxListenerExecutor;
+        this.listenerExecutor = listenerExecutor;
         this.receiverSubscriber = Optional.empty();
         this.unregisterGroup = unregisterGroup;
         this.retryHandler = new GroupConsumerRetry(sender, group, retryBackoff, eventDeadLetters, eventSerializer);
@@ -164,8 +164,8 @@ class GroupRegistration implements Registration {
     }
 
     private Mono<Void> runListener(Event event) {
-        return mailboxListenerExecutor.execute(
-            mailboxListener,
+        return listenerExecutor.execute(
+            listener,
             MDCBuilder.create()
                 .addContext(EventBus.StructuredLoggingFields.GROUP, group),
             event);
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
index 8e00eaa..f1ddb6c 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
@@ -36,18 +36,18 @@ class GroupRegistrationHandler {
     private final ReceiverProvider receiverProvider;
     private final RetryBackoffConfiguration retryBackoff;
     private final EventDeadLetters eventDeadLetters;
-    private final MailboxListenerExecutor mailboxListenerExecutor;
+    private final ListenerExecutor listenerExecutor;
 
     GroupRegistrationHandler(EventSerializer eventSerializer, ReactorRabbitMQChannelPool channelPool, Sender sender, ReceiverProvider receiverProvider,
                              RetryBackoffConfiguration retryBackoff,
-                             EventDeadLetters eventDeadLetters, MailboxListenerExecutor mailboxListenerExecutor) {
+                             EventDeadLetters eventDeadLetters, ListenerExecutor listenerExecutor) {
         this.eventSerializer = eventSerializer;
         this.channelPool = channelPool;
         this.sender = sender;
         this.receiverProvider = receiverProvider;
         this.retryBackoff = retryBackoff;
         this.eventDeadLetters = eventDeadLetters;
-        this.mailboxListenerExecutor = mailboxListenerExecutor;
+        this.listenerExecutor = listenerExecutor;
         this.groupRegistrations = new ConcurrentHashMap<>();
     }
 
@@ -81,6 +81,6 @@ class GroupRegistrationHandler {
             retryBackoff,
             eventDeadLetters,
             () -> groupRegistrations.remove(group),
-            mailboxListenerExecutor);
+            listenerExecutor);
     }
 }
\ No newline at end of file
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java b/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
index db1e24b..1963d40 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
@@ -67,21 +67,21 @@ class KeyRegistrationHandler {
     private final Receiver receiver;
     private final RegistrationQueueName registrationQueue;
     private final RegistrationBinder registrationBinder;
-    private final MailboxListenerExecutor mailboxListenerExecutor;
+    private final ListenerExecutor listenerExecutor;
     private final RetryBackoffConfiguration retryBackoff;
     private Optional<Disposable> receiverSubscriber;
 
     KeyRegistrationHandler(EventBusId eventBusId, EventSerializer eventSerializer,
                            Sender sender, ReceiverProvider receiverProvider,
                            RoutingKeyConverter routingKeyConverter, LocalListenerRegistry localListenerRegistry,
-                           MailboxListenerExecutor mailboxListenerExecutor, RetryBackoffConfiguration retryBackoff) {
+                           ListenerExecutor listenerExecutor, RetryBackoffConfiguration retryBackoff) {
         this.eventBusId = eventBusId;
         this.eventSerializer = eventSerializer;
         this.sender = sender;
         this.routingKeyConverter = routingKeyConverter;
         this.localListenerRegistry = localListenerRegistry;
         this.receiver = receiverProvider.createReceiver();
-        this.mailboxListenerExecutor = mailboxListenerExecutor;
+        this.listenerExecutor = listenerExecutor;
         this.retryBackoff = retryBackoff;
         this.registrationQueue = new RegistrationQueueName(EVENTBUS_QUEUE_NAME_PREFIX + eventBusId.asString());
         this.registrationBinder = new RegistrationBinder(sender, registrationQueue);
@@ -162,7 +162,7 @@ class KeyRegistrationHandler {
         RegistrationKey registrationKey = routingKeyConverter.toRegistrationKey(routingKey);
         Event event = toEvent(delivery);
 
-        return localListenerRegistry.getLocalMailboxListeners(registrationKey)
+        return localListenerRegistry.getLocalListeners(registrationKey)
             .filter(listener -> !isLocalSynchronousListeners(eventBusId, listener))
             .flatMap(listener -> executeListener(listener, event, registrationKey), EventBus.EXECUTION_RATE)
             .then();
@@ -172,7 +172,7 @@ class KeyRegistrationHandler {
         MDCBuilder mdcBuilder = MDCBuilder.create()
             .addContext(EventBus.StructuredLoggingFields.REGISTRATION_KEY, key);
 
-        return mailboxListenerExecutor.execute(listener, mdcBuilder, event)
+        return listenerExecutor.execute(listener, mdcBuilder, event)
             .doOnError(e -> structuredLogger(event, key)
                 .log(logger -> logger.error("Exception happens when handling event", e)))
             .onErrorResume(e -> Mono.empty())
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/MailboxListenerExecutor.java b/event-bus/distributed/src/main/java/org/apache/james/events/ListenerExecutor.java
similarity index 91%
rename from event-bus/distributed/src/main/java/org/apache/james/events/MailboxListenerExecutor.java
rename to event-bus/distributed/src/main/java/org/apache/james/events/ListenerExecutor.java
index e74e6ec..2d2f258 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/MailboxListenerExecutor.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/ListenerExecutor.java
@@ -27,10 +27,10 @@ import org.apache.james.util.ReactorUtils;
 
 import reactor.core.publisher.Mono;
 
-class MailboxListenerExecutor {
+class ListenerExecutor {
     private final MetricFactory metricFactory;
 
-    MailboxListenerExecutor(MetricFactory metricFactory) {
+    ListenerExecutor(MetricFactory metricFactory) {
         this.metricFactory = metricFactory;
     }
 
@@ -38,7 +38,7 @@ class MailboxListenerExecutor {
         if (listener.isHandling(event)) {
             return Mono.from(metricFactory.decoratePublisherWithTimerMetric(timerName(listener),
                 Mono.from(listener.reactiveEvent(event))
-                    .subscriberContext(ReactorUtils.context("MailboxListenerExecutor", mdc(listener, mdcBuilder, event)))));
+                    .subscriberContext(ReactorUtils.context("ListenerExecutor", mdc(listener, mdcBuilder, event)))));
         }
         return Mono.empty();
     }
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/LocalListenerRegistry.java b/event-bus/distributed/src/main/java/org/apache/james/events/LocalListenerRegistry.java
index f4e5537..4f68b4f 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/LocalListenerRegistry.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/LocalListenerRegistry.java
@@ -103,7 +103,7 @@ class LocalListenerRegistry {
         return remainingListeners;
     }
 
-    Flux<EventListener.ReactiveEventListener> getLocalMailboxListeners(RegistrationKey registrationKey) {
+    Flux<EventListener.ReactiveEventListener> getLocalListeners(RegistrationKey registrationKey) {
         return Flux.fromIterable(listenersByKey.getOrDefault(registrationKey, ImmutableSet.of()));
     }
 }
\ No newline at end of file
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/RabbitMQEventBus.java b/event-bus/distributed/src/main/java/org/apache/james/events/RabbitMQEventBus.java
index 772191b..78aeae7 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/RabbitMQEventBus.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/RabbitMQEventBus.java
@@ -50,7 +50,7 @@ public class RabbitMQEventBus implements EventBus, Startable {
     private final RetryBackoffConfiguration retryBackoff;
     private final EventBusId eventBusId;
     private final EventDeadLetters eventDeadLetters;
-    private final MailboxListenerExecutor mailboxListenerExecutor;
+    private final ListenerExecutor listenerExecutor;
     private final Sender sender;
     private final ReceiverProvider receiverProvider;
     private final ReactorRabbitMQChannelPool channelPool;
@@ -69,7 +69,7 @@ public class RabbitMQEventBus implements EventBus, Startable {
                             EventBusId eventBusId) {
         this.sender = sender;
         this.receiverProvider = receiverProvider;
-        this.mailboxListenerExecutor = new MailboxListenerExecutor(metricFactory);
+        this.listenerExecutor = new ListenerExecutor(metricFactory);
         this.channelPool = channelPool;
         this.eventBusId = eventBusId;
         this.eventSerializer = eventSerializer;
@@ -84,9 +84,9 @@ public class RabbitMQEventBus implements EventBus, Startable {
         if (!isRunning && !isStopping) {
 
             LocalListenerRegistry localListenerRegistry = new LocalListenerRegistry();
-            keyRegistrationHandler = new KeyRegistrationHandler(eventBusId, eventSerializer, sender, receiverProvider, routingKeyConverter, localListenerRegistry, mailboxListenerExecutor, retryBackoff);
-            groupRegistrationHandler = new GroupRegistrationHandler(eventSerializer, channelPool, sender, receiverProvider, retryBackoff, eventDeadLetters, mailboxListenerExecutor);
-            eventDispatcher = new EventDispatcher(eventBusId, eventSerializer, sender, localListenerRegistry, mailboxListenerExecutor, eventDeadLetters);
+            keyRegistrationHandler = new KeyRegistrationHandler(eventBusId, eventSerializer, sender, receiverProvider, routingKeyConverter, localListenerRegistry, listenerExecutor, retryBackoff);
+            groupRegistrationHandler = new GroupRegistrationHandler(eventSerializer, channelPool, sender, receiverProvider, retryBackoff, eventDeadLetters, listenerExecutor);
+            eventDispatcher = new EventDispatcher(eventBusId, eventSerializer, sender, localListenerRegistry, listenerExecutor, eventDeadLetters);
 
             eventDispatcher.start();
             keyRegistrationHandler.start();
@@ -99,9 +99,9 @@ public class RabbitMQEventBus implements EventBus, Startable {
         if (!isRunning && !isStopping) {
 
             LocalListenerRegistry localListenerRegistry = new LocalListenerRegistry();
-            keyRegistrationHandler = new KeyRegistrationHandler(eventBusId, eventSerializer, sender, receiverProvider, routingKeyConverter, localListenerRegistry, mailboxListenerExecutor, retryBackoff);
-            groupRegistrationHandler = new GroupRegistrationHandler(eventSerializer, channelPool, sender, receiverProvider, retryBackoff, eventDeadLetters, mailboxListenerExecutor);
-            eventDispatcher = new EventDispatcher(eventBusId, eventSerializer, sender, localListenerRegistry, mailboxListenerExecutor, eventDeadLetters);
+            keyRegistrationHandler = new KeyRegistrationHandler(eventBusId, eventSerializer, sender, receiverProvider, routingKeyConverter, localListenerRegistry, listenerExecutor, retryBackoff);
+            groupRegistrationHandler = new GroupRegistrationHandler(eventSerializer, channelPool, sender, receiverProvider, retryBackoff, eventDeadLetters, listenerExecutor);
+            eventDispatcher = new EventDispatcher(eventBusId, eventSerializer, sender, localListenerRegistry, listenerExecutor, eventDeadLetters);
 
             keyRegistrationHandler.declareQueue();
 
diff --git a/event-bus/distributed/src/test/java/org/apache/james/events/LocalListenerRegistryTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/LocalListenerRegistryTest.java
index 36953c6..81269af 100644
--- a/event-bus/distributed/src/test/java/org/apache/james/events/LocalListenerRegistryTest.java
+++ b/event-bus/distributed/src/test/java/org/apache/james/events/LocalListenerRegistryTest.java
@@ -45,33 +45,33 @@ class LocalListenerRegistryTest {
     }
 
     @Test
-    void getLocalMailboxListenersShouldReturnEmptyWhenNone() {
-        assertThat(testee.getLocalMailboxListeners(KEY_1).collectList().block())
+    void getLocalListenersShouldReturnEmptyWhenNone() {
+        assertThat(testee.getLocalListeners(KEY_1).collectList().block())
             .isEmpty();
     }
 
     @Test
-    void getLocalMailboxListenersShouldReturnPreviouslyAddedListener() {
+    void getLocalListenersShouldReturnPreviouslyAddedListener() {
         EventListener listener = event -> { };
         testee.addListener(KEY_1, listener);
 
-        assertThat(testee.getLocalMailboxListeners(KEY_1).collectList().block())
+        assertThat(testee.getLocalListeners(KEY_1).collectList().block())
             .containsOnly(wrapReactive(listener));
     }
 
     @Test
-    void getLocalMailboxListenersShouldReturnPreviouslyAddedListeners() {
+    void getLocalListenersShouldReturnPreviouslyAddedListeners() {
         EventListener listener1 = event -> { };
         EventListener listener2 = event -> { };
         testee.addListener(KEY_1, listener1);
         testee.addListener(KEY_1, listener2);
 
-        assertThat(testee.getLocalMailboxListeners(KEY_1).collectList().block())
+        assertThat(testee.getLocalListeners(KEY_1).collectList().block())
             .containsOnly(wrapReactive(listener1), wrapReactive(listener2));
     }
 
     @Test
-    void getLocalMailboxListenersShouldNotReturnRemovedListeners() {
+    void getLocalListenersShouldNotReturnRemovedListeners() {
         EventListener listener1 = event -> { };
         EventListener listener2 = event -> { };
         testee.addListener(KEY_1, listener1);
@@ -79,7 +79,7 @@ class LocalListenerRegistryTest {
 
         registration.unregister();
 
-        assertThat(testee.getLocalMailboxListeners(KEY_1).collectList().block())
+        assertThat(testee.getLocalListeners(KEY_1).collectList().block())
             .containsOnly(wrapReactive(listener1));
     }
 
@@ -126,7 +126,7 @@ class LocalListenerRegistryTest {
         private final Duration oneSecond = Duration.ofSeconds(1);
 
         @Test
-        void getLocalMailboxListenersShouldReturnPreviousAddedListener() throws Exception {
+        void getLocalListenersShouldReturnPreviousAddedListener() throws Exception {
             EventListener listener = event -> { };
 
             ConcurrentTestRunner.builder()
@@ -135,12 +135,12 @@ class LocalListenerRegistryTest {
                 .operationCount(10)
                 .runSuccessfullyWithin(oneSecond);
 
-            assertThat(testee.getLocalMailboxListeners(KEY_1).collectList().block())
+            assertThat(testee.getLocalListeners(KEY_1).collectList().block())
                 .containsOnly(wrapReactive(listener));
         }
 
         @Test
-        void getLocalMailboxListenersShouldReturnAllPreviousAddedListeners() throws Exception {
+        void getLocalListenersShouldReturnAllPreviousAddedListeners() throws Exception {
             EventListener listener1 = event -> { };
             EventListener listener2 = event -> { };
             EventListener listener3 = event -> { };
@@ -154,12 +154,12 @@ class LocalListenerRegistryTest {
                 .operationCount(10)
                 .runSuccessfullyWithin(oneSecond);
 
-            assertThat(testee.getLocalMailboxListeners(KEY_1).collectList().block())
+            assertThat(testee.getLocalListeners(KEY_1).collectList().block())
                 .containsOnly(wrapReactive(listener1), wrapReactive(listener2), wrapReactive(listener3));
         }
 
         @Test
-        void getLocalMailboxListenersShouldReturnEmptyWhenRemoveAddedListener() throws Exception {
+        void getLocalListenersShouldReturnEmptyWhenRemoveAddedListener() throws Exception {
             EventListener listener1 = event -> { };
 
             LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener1);
@@ -170,7 +170,7 @@ class LocalListenerRegistryTest {
                 .operationCount(10)
                 .runSuccessfullyWithin(oneSecond);
 
-            assertThat(testee.getLocalMailboxListeners(KEY_1).collectList().block())
+            assertThat(testee.getLocalListeners(KEY_1).collectList().block())
                 .isEmpty();
         }
 
@@ -241,7 +241,7 @@ class LocalListenerRegistryTest {
             testee.addListener(KEY_1, listener4);
             LocalListenerRegistry.LocalRegistration registration5 = testee.addListener(KEY_1, listener5);
 
-            Mono<List<EventListener.ReactiveEventListener>> listeners = testee.getLocalMailboxListeners(KEY_1)
+            Mono<List<EventListener.ReactiveEventListener>> listeners = testee.getLocalListeners(KEY_1)
                 .publishOn(Schedulers.elastic())
                 .delayElements(Duration.ofMillis(100))
                 .collectList();
diff --git a/event-bus/in-vm/src/main/java/org/apache/james/events/InVMEventBus.java b/event-bus/in-vm/src/main/java/org/apache/james/events/InVMEventBus.java
index a3360c5..c32f24d 100644
--- a/event-bus/in-vm/src/main/java/org/apache/james/events/InVMEventBus.java
+++ b/event-bus/in-vm/src/main/java/org/apache/james/events/InVMEventBus.java
@@ -102,12 +102,12 @@ public class InVMEventBus implements EventBus {
             .then();
     }
 
-    private Mono<Void> groupDelivery(Event event, EventListener.ReactiveEventListener mailboxListener, Group group) {
+    private Mono<Void> groupDelivery(Event event, EventListener.ReactiveEventListener listener, Group group) {
         return eventDelivery.deliver(
-            mailboxListener,
+            listener,
             event,
             EventDelivery.DeliveryOption.of(
-                EventDelivery.Retryer.BackoffRetryer.of(retryBackoff, mailboxListener),
+                EventDelivery.Retryer.BackoffRetryer.of(retryBackoff, listener),
                 EventDelivery.PermanentFailureHandler.StoreToDeadLetters.of(group, eventDeadLetters)));
     }
 
diff --git a/event-bus/in-vm/src/main/java/org/apache/james/events/delivery/EventDelivery.java b/event-bus/in-vm/src/main/java/org/apache/james/events/delivery/EventDelivery.java
index 11f6593..717f71f 100644
--- a/event-bus/in-vm/src/main/java/org/apache/james/events/delivery/EventDelivery.java
+++ b/event-bus/in-vm/src/main/java/org/apache/james/events/delivery/EventDelivery.java
@@ -69,18 +69,18 @@ public interface EventDelivery {
 
         class BackoffRetryer implements Retryer {
 
-            public static BackoffRetryer of(RetryBackoffConfiguration retryBackoff, EventListener mailboxListener) {
-                return new BackoffRetryer(retryBackoff, mailboxListener);
+            public static BackoffRetryer of(RetryBackoffConfiguration retryBackoff, EventListener listener) {
+                return new BackoffRetryer(retryBackoff, listener);
             }
 
             private static final Logger LOGGER = LoggerFactory.getLogger(BackoffRetryer.class);
 
             private final RetryBackoffConfiguration retryBackoff;
-            private final EventListener mailboxListener;
+            private final EventListener listener;
 
-            public BackoffRetryer(RetryBackoffConfiguration retryBackoff, EventListener mailboxListener) {
+            public BackoffRetryer(RetryBackoffConfiguration retryBackoff, EventListener listener) {
                 this.retryBackoff = retryBackoff;
-                this.mailboxListener = mailboxListener;
+                this.listener = listener;
             }
 
             @Override
@@ -88,7 +88,7 @@ public interface EventDelivery {
                 return executionResult
                     .retryWhen(Retry.backoff(retryBackoff.getMaxRetries(), retryBackoff.getFirstBackoff()).jitter(retryBackoff.getJitterFactor()).scheduler(Schedulers.elastic()))
                     .doOnError(throwable -> LOGGER.error("listener {} exceeded maximum retry({}) to handle event {}",
-                        mailboxListener.getClass().getCanonicalName(),
+                        listener.getClass().getCanonicalName(),
                         retryBackoff.getMaxRetries(),
                         event.getClass().getCanonicalName(),
                         throwable))
diff --git a/event-bus/in-vm/src/main/java/org/apache/james/events/delivery/InVmEventDelivery.java b/event-bus/in-vm/src/main/java/org/apache/james/events/delivery/InVmEventDelivery.java
index f67c022..0cc70d5 100644
--- a/event-bus/in-vm/src/main/java/org/apache/james/events/delivery/InVmEventDelivery.java
+++ b/event-bus/in-vm/src/main/java/org/apache/james/events/delivery/InVmEventDelivery.java
@@ -77,28 +77,28 @@ public class InVmEventDelivery implements EventDelivery {
             .then();
     }
 
-    private Mono<Void> doDeliverToListener(EventListener.ReactiveEventListener mailboxListener, Event event) {
-        if (mailboxListener.isHandling(event)) {
-            return Mono.defer(() -> Mono.from(metricFactory.decoratePublisherWithTimerMetric(timerName(mailboxListener),
-                    mailboxListener.reactiveEvent(event))))
-                .subscriberContext(context("deliver", buildMDC(mailboxListener, event)));
+    private Mono<Void> doDeliverToListener(EventListener.ReactiveEventListener listener, Event event) {
+        if (listener.isHandling(event)) {
+            return Mono.defer(() -> Mono.from(metricFactory.decoratePublisherWithTimerMetric(timerName(listener),
+                    listener.reactiveEvent(event))))
+                .subscriberContext(context("deliver", buildMDC(listener, event)));
         }
         return Mono.empty();
     }
 
-    private MDCBuilder buildMDC(EventListener mailboxListener, Event event) {
+    private MDCBuilder buildMDC(EventListener listener, Event event) {
         return MDCBuilder.create()
             .addContext(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
             .addContext(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
             .addContext(EventBus.StructuredLoggingFields.USER, event.getUsername())
-            .addContext(EventBus.StructuredLoggingFields.LISTENER_CLASS, mailboxListener.getClass());
+            .addContext(EventBus.StructuredLoggingFields.LISTENER_CLASS, listener.getClass());
     }
 
-    private StructuredLogger structuredLogger(Event event, EventListener mailboxListener) {
+    private StructuredLogger structuredLogger(Event event, EventListener listener) {
         return MDCStructuredLogger.forLogger(LOGGER)
             .addField(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
             .addField(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
             .addField(EventBus.StructuredLoggingFields.USER, event.getUsername())
-            .addField(EventBus.StructuredLoggingFields.LISTENER_CLASS, mailboxListener.getClass());
+            .addField(EventBus.StructuredLoggingFields.LISTENER_CLASS, listener.getClass());
     }
 }


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


[james-project] 15/18: JAMES-3498 Isolation for dead-letter queues in RabbitMQEventBusTest

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 d2dfb311a7a3584cdf914357aef57bc8735968fb
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue Jan 26 08:15:40 2021 +0700

    JAMES-3498 Isolation for dead-letter queues in RabbitMQEventBusTest
---
 .../events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java  | 13 +++++++------
 .../java/org/apache/james/events/RabbitMQEventBusTest.java  |  3 +++
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
index 9e9f284..137e59c 100644
--- a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
+++ b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
@@ -39,9 +39,12 @@ import org.junit.jupiter.api.extension.RegisterExtension;
 import reactor.rabbitmq.QueueSpecification;
 
 class RabbitMQEventBusDeadLetterQueueUpgradeTest {
+    private static final GroupA REGISTERED_GROUP = new GroupA();
+    private static final WorkQueueName WORK_QUEUE_NAME = WorkQueueName.of(REGISTERED_GROUP);
+
     @RegisterExtension
     static RabbitMQExtension rabbitMQExtension = RabbitMQExtension.singletonRabbitMQ()
-        .isolationPolicy(RabbitMQExtension.IsolationPolicy.WEAK);
+        .isolationPolicy(RabbitMQExtension.IsolationPolicy.STRONG);
 
     private RabbitMQEventBus eventBus;
 
@@ -67,18 +70,16 @@ class RabbitMQEventBusDeadLetterQueueUpgradeTest {
 
     @Test
     void eventBusShouldStartWhenDeadLetterUpgradeWasNotPerformed() {
-        GroupA registeredGroup = new GroupA();
-        WorkQueueName workQueueName = WorkQueueName.of(registeredGroup);
-        
+        rabbitMQExtension.getSender().delete(QueueSpecification.queue().name(WORK_QUEUE_NAME.asString())).block();
         rabbitMQExtension.getSender()
-            .declareQueue(QueueSpecification.queue(workQueueName.asString())
+            .declareQueue(QueueSpecification.queue(WORK_QUEUE_NAME.asString())
                 .durable(DURABLE)
                 .exclusive(!EXCLUSIVE)
                 .autoDelete(!AUTO_DELETE))
             .block();
 
         assertThatCode(eventBus::start).doesNotThrowAnyException();
-        assertThatCode(() -> eventBus.register(new EventCollector(), registeredGroup)).doesNotThrowAnyException();
+        assertThatCode(() -> eventBus.register(new EventCollector(), REGISTERED_GROUP)).doesNotThrowAnyException();
     }
 
 }
diff --git a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
index 5641089..b191547 100644
--- a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
+++ b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
@@ -143,6 +143,9 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
         rabbitMQExtension.getSender()
             .delete(ExchangeSpecification.exchange(MAILBOX_EVENT_EXCHANGE_NAME))
             .block();
+        rabbitMQExtension.getSender()
+            .delete(QueueSpecification.queue().name(MAILBOX_EVENT_DEAD_LETTER_QUEUE))
+            .block();
     }
 
     private RabbitMQEventBus newEventBus() {


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


[james-project] 07/18: JAMES-3498 event-bus-* should not depend on mailbox-*

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 9f39436ea4baed6aaa45970b3a2b4b028ddf6795
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 25 15:21:35 2021 +0700

    JAMES-3498 event-bus-* should not depend on mailbox-*
---
 event-bus/api/pom.xml                              |  11 --
 .../apache/james/events/EventBusTestFixture.java   | 178 ++++++++++++++++++---
 .../james/events/EventDeadLettersContract.java     |  18 +--
 .../EventDeadLettersHealthCheckContract.java       |  14 +-
 .../org/apache/james/events/GroupContract.java     |  14 +-
 .../java/org/apache/james/events/KeyContract.java  |   9 +-
 event-bus/cassandra/pom.xml                        |  29 +---
 .../events/CassandraEventDeadLettersDAOTest.java   |   6 +-
 .../CassandraEventDeadLettersHealthCheckTest.java  |   7 +-
 .../events/CassandraEventDeadLettersTest.java      |   7 +-
 event-bus/distributed/pom.xml                      |  53 ++----
 .../james/events/LocalListenerRegistryTest.java    |   3 +-
 .../org/apache/james/events/NetworkErrorTest.java  |  11 +-
 ...RabbitMQEventBusDeadLetterQueueUpgradeTest.java |  12 +-
 .../apache/james/events/RabbitMQEventBusTest.java  |  18 +--
 .../james/events/RoutingKeyConverterTest.java      |  39 ++---
 event-bus/in-vm/pom.xml                            |  20 +--
 .../AbstractMessageIdManagerSideEffectTest.java    |   3 +-
 .../mailbox/store/StoreMailboxManagerTest.java     |  11 +-
 19 files changed, 250 insertions(+), 213 deletions(-)

diff --git a/event-bus/api/pom.xml b/event-bus/api/pom.xml
index df7be49..6a577f1 100644
--- a/event-bus/api/pom.xml
+++ b/event-bus/api/pom.xml
@@ -34,17 +34,6 @@
     <dependencies>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>apache-james-mailbox-api</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
-            <artifactId>apache-james-mailbox-api</artifactId>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
             <artifactId>james-core</artifactId>
         </dependency>
         <dependency>
diff --git a/event-bus/api/src/test/java/org/apache/james/events/EventBusTestFixture.java b/event-bus/api/src/test/java/org/apache/james/events/EventBusTestFixture.java
index 9398247..917e24a 100644
--- a/event-bus/api/src/test/java/org/apache/james/events/EventBusTestFixture.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/EventBusTestFixture.java
@@ -25,18 +25,16 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.james.core.Username;
-import org.apache.james.events.MailboxEvents.MailboxAdded;
-import org.apache.james.events.MailboxEvents.MailboxEvent;
-import org.apache.james.events.MailboxEvents.MailboxRenamed;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.model.MailboxConstants;
-import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.TestId;
 
+import com.github.steveash.guavate.Guavate;
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 
@@ -93,25 +91,161 @@ public interface EventBusTestFixture {
 
     }
 
-    MailboxSession.SessionId SESSION_ID = MailboxSession.SessionId.of(42);
+    class TestEvent implements Event {
+        private final EventId eventId;
+        private final Username username;
+
+        public TestEvent(EventId eventId, Username username) {
+            this.eventId = eventId;
+            this.username = username;
+        }
+
+        @Override
+        public Username getUsername() {
+            return username;
+        }
+
+        @Override
+        public boolean isNoop() {
+            return username.asString().equals("noop");
+        }
+
+        @Override
+        public EventId getEventId() {
+            return eventId;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof TestEvent) {
+                TestEvent that = (TestEvent) o;
+
+                return Objects.equals(this.eventId, that.eventId)
+                    && Objects.equals(this.username, that.username);
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(eventId, username);
+        }
+    }
+
+    class UnsupportedEvent implements Event {
+        private final EventId eventId;
+        private final Username username;
+
+        public UnsupportedEvent(EventId eventId, Username username) {
+            this.eventId = eventId;
+            this.username = username;
+        }
+
+        @Override
+        public Username getUsername() {
+            return username;
+        }
+
+        @Override
+        public boolean isNoop() {
+            return false;
+        }
+
+        @Override
+        public EventId getEventId() {
+            return eventId;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof UnsupportedEvent) {
+                UnsupportedEvent that = (UnsupportedEvent) o;
+
+                return Objects.equals(this.eventId, that.eventId)
+                    && Objects.equals(this.username, that.username);
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(eventId, username);
+        }
+    }
+
+    class TestEventSerializer implements EventSerializer {
+        @Override
+        public String toJson(Event event) {
+            Preconditions.checkArgument(event instanceof TestEvent || event instanceof UnsupportedEvent);
+            return event.getClass().getCanonicalName() + "&" + event.getEventId().getId().toString() + "&" + event.getUsername().asString();
+        }
+
+        @Override
+        public Event asEvent(String serialized) {
+            Preconditions.checkArgument(serialized.contains("&"));
+            List<String> parts = Splitter.on("&").splitToList(serialized);
+            Preconditions.checkArgument(parts.get(0).equals(TestEvent.class.getCanonicalName()));
+
+            Event.EventId eventId = Event.EventId.of(UUID.fromString(parts.get(1)));
+            Username username = Username.of(Joiner.on("&").join(parts.stream().skip(2).collect(Guavate.toImmutableList())));
+            return new TestEvent(eventId, username);
+        }
+    }
+
+    class TestRegistrationKey implements RegistrationKey {
+        private final String value;
+
+        public TestRegistrationKey(String value) {
+            this.value = value;
+        }
+
+        @Override
+        public String asString() {
+            return value;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof TestRegistrationKey) {
+                TestRegistrationKey that = (TestRegistrationKey) o;
+
+                return Objects.equals(this.value, that.value);
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(value);
+        }
+    }
+
+    class TestRegistrationKeyFactory implements RegistrationKey.Factory {
+        @Override
+        public Class<? extends RegistrationKey> forClass() {
+            return TestRegistrationKey.class;
+        }
+
+        @Override
+        public RegistrationKey fromString(String asString) {
+            return new TestRegistrationKey(asString);
+        }
+    }
+
     Username USERNAME = Username.of("user");
-    MailboxPath MAILBOX_PATH = new MailboxPath(MailboxConstants.USER_NAMESPACE, USERNAME, "mailboxName");
-    TestId TEST_ID = TestId.of(18);
     Event.EventId EVENT_ID = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
     Event.EventId EVENT_ID_2 = Event.EventId.of("5a7a9f3f-5f03-44be-b457-a51e93760645");
-    MailboxEvent EVENT = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, EVENT_ID);
-    MailboxEvent EVENT_2 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, EVENT_ID_2);
-    MailboxRenamed EVENT_UNSUPPORTED_BY_LISTENER = new MailboxRenamed(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, MAILBOX_PATH, EVENT_ID_2);
+    Event EVENT = new TestEvent(EVENT_ID, USERNAME);
+    Event EVENT_2 = new TestEvent(EVENT_ID_2, USERNAME);
+    Event EVENT_UNSUPPORTED_BY_LISTENER = new UnsupportedEvent(EVENT_ID_2, USERNAME);
 
     java.time.Duration ONE_SECOND = java.time.Duration.ofSeconds(1);
     java.time.Duration FIVE_HUNDRED_MS = java.time.Duration.ofMillis(500);
-    MailboxId ID_1 = TEST_ID;
-    MailboxId ID_2 = TestId.of(24);
-    MailboxId ID_3 = TestId.of(36);
+
     ImmutableSet<RegistrationKey> NO_KEYS = ImmutableSet.of();
-    MailboxIdRegistrationKey KEY_1 = new MailboxIdRegistrationKey(ID_1);
-    MailboxIdRegistrationKey KEY_2 = new MailboxIdRegistrationKey(ID_2);
-    MailboxIdRegistrationKey KEY_3 = new MailboxIdRegistrationKey(ID_3);
+    RegistrationKey KEY_1 = new TestRegistrationKey("a");
+    RegistrationKey KEY_2 = new TestRegistrationKey("b");
+    RegistrationKey KEY_3 = new TestRegistrationKey("c");
     GroupA GROUP_A = new GroupA();
     GroupB GROUP_B = new GroupB();
     GroupC GROUP_C = new GroupC();
@@ -128,14 +262,14 @@ public interface EventBusTestFixture {
     static EventListener newListener() {
         EventListener listener = mock(EventListener.class);
         when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
-        when(listener.isHandling(any(MailboxAdded.class))).thenReturn(true);
+        when(listener.isHandling(any(TestEvent.class))).thenReturn(true);
         return listener;
     }
 
     static EventListener newAsyncListener() {
         EventListener listener = mock(EventListener.class);
         when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
-        when(listener.isHandling(any(MailboxAdded.class))).thenReturn(true);
+        when(listener.isHandling(any(TestEvent.class))).thenReturn(true);
         return listener;
     }
 }
diff --git a/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersContract.java b/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersContract.java
index 88b674d..e351e26 100644
--- a/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersContract.java
@@ -31,11 +31,7 @@ import java.util.stream.IntStream;
 import java.util.stream.Stream;
 
 import org.apache.james.core.Username;
-import org.apache.james.events.MailboxEvents.MailboxAdded;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.model.MailboxConstants;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.TestId;
+import org.apache.james.events.EventBusTestFixture.TestEvent;
 import org.apache.james.util.concurrency.ConcurrentTestRunner;
 import org.junit.jupiter.api.Test;
 
@@ -94,7 +90,7 @@ interface EventDeadLettersContract {
     }
 
     static Event event(Event.EventId eventId) {
-        return new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, eventId);
+        return new TestEvent(eventId, USERNAME);
     }
 
     List<Group> CONCURRENT_GROUPS = ImmutableList.of(new Group0(), new Group1(), new Group2(), new Group3(), new Group4(), new Group5(),
@@ -104,15 +100,13 @@ interface EventDeadLettersContract {
     int OPERATION_COUNT = 50;
 
     Username USERNAME = Username.of("user");
-    MailboxPath MAILBOX_PATH = new MailboxPath(MailboxConstants.USER_NAMESPACE, USERNAME, "mailboxName");
-    MailboxSession.SessionId SESSION_ID = MailboxSession.SessionId.of(235);
-    TestId MAILBOX_ID = TestId.of(563);
+
     Event.EventId EVENT_ID_1 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
     Event.EventId EVENT_ID_2 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b5");
     Event.EventId EVENT_ID_3 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b6");
-    MailboxAdded EVENT_1 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_1);
-    MailboxAdded EVENT_2 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_2);
-    MailboxAdded EVENT_3 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_3);
+    Event EVENT_1 = new TestEvent(EVENT_ID_1, USERNAME);
+    Event EVENT_2 = new TestEvent(EVENT_ID_2, USERNAME);
+    Event EVENT_3 = new TestEvent(EVENT_ID_3, USERNAME);
     EventDeadLetters.InsertionId INSERTION_ID_1 = EventDeadLetters.InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b7");
     EventDeadLetters.InsertionId INSERTION_ID_2 = EventDeadLetters.InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b8");
     EventDeadLetters.InsertionId INSERTION_ID_3 = EventDeadLetters.InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b9");
diff --git a/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java b/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java
index 7a0b5d5..335f1c7 100644
--- a/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java
@@ -24,11 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import org.apache.james.core.Username;
 import org.apache.james.core.healthcheck.ComponentName;
 import org.apache.james.core.healthcheck.Result;
-import org.apache.james.events.MailboxEvents.MailboxAdded;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.model.MailboxConstants;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.TestId;
+import org.apache.james.events.EventBusTestFixture.TestEvent;
 import org.junit.jupiter.api.Test;
 
 interface EventDeadLettersHealthCheckContract {
@@ -37,13 +33,11 @@ interface EventDeadLettersHealthCheckContract {
     String EXPECTED_DEGRADED_MESSAGE = "EventDeadLetters contain events. This might indicate transient failure on mailbox event processing.";
 
     Username USERNAME = Username.of("user");
-    MailboxPath MAILBOX_PATH = new MailboxPath(MailboxConstants.USER_NAMESPACE, USERNAME, "mailboxName");
-    MailboxSession.SessionId SESSION_ID = MailboxSession.SessionId.of(235);
-    TestId MAILBOX_ID = TestId.of(563);
+
     Event.EventId EVENT_ID_1 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
     Event.EventId EVENT_ID_2 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b5");
-    MailboxAdded EVENT_1 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_1);
-    MailboxAdded EVENT_2 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_2);
+    Event EVENT_1 = new TestEvent(EVENT_ID_1, USERNAME);
+    Event EVENT_2 = new TestEvent(EVENT_ID_2, USERNAME);
 
     Group GROUP_A = new EventBusTestFixture.GroupA();
     Group GROUP_B = new EventBusTestFixture.GroupB();
diff --git a/event-bus/api/src/test/java/org/apache/james/events/GroupContract.java b/event-bus/api/src/test/java/org/apache/james/events/GroupContract.java
index dc97bfb..246f6b7 100644
--- a/event-bus/api/src/test/java/org/apache/james/events/GroupContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/GroupContract.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.events;
 
+import static org.apache.james.events.EventBusTestFixture.EVENT_ID;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -38,16 +39,11 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.IntStream;
 
 import org.apache.james.core.Username;
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.TestId;
 import org.apache.james.events.EventBusTestFixture.TestEvent;
 import org.apache.james.mailbox.events.GenericGroup;
 import org.junit.jupiter.api.Test;
 
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedMap;
 
 import reactor.core.scheduler.Schedulers;
 
@@ -150,7 +146,7 @@ public interface GroupContract {
         default void listenersShouldBeAbleToDispatch() {
             AtomicBoolean successfulRetry = new AtomicBoolean(false);
             EventListener listener = event -> {
-                if (event.getEventId().equals(EventBusTestFixture.EVENT_ID)) {
+                if (event.getEventId().equals(EVENT_ID)) {
                     eventBus().dispatch(EventBusTestFixture.EVENT_2, EventBusTestFixture.NO_KEYS)
                         .subscribeOn(Schedulers.elastic())
                         .block();
@@ -193,8 +189,7 @@ public interface GroupContract {
 
             eventBus().register(listener, EventBusTestFixture.GROUP_A);
 
-            Username bob = Username.of("bob");
-            Added noopEvent = new Added(MailboxSession.SessionId.of(18), bob, MailboxPath.forUser(bob, "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
+            Event noopEvent = new TestEvent(EVENT_ID, Username.of("noop"));
             eventBus().dispatch(noopEvent, EventBusTestFixture.NO_KEYS).block();
 
             verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
@@ -404,8 +399,7 @@ public interface GroupContract {
 
             eventBus().register(listener, EventBusTestFixture.GROUP_A);
 
-            Username bob = Username.of("bob");
-            Added noopEvent = new Added(MailboxSession.SessionId.of(18), bob, MailboxPath.forUser(bob, "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
+            Event noopEvent = new TestEvent(EVENT_ID, Username.of("noop"));
             eventBus().reDeliver(EventBusTestFixture.GROUP_A, noopEvent).block();
 
             verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never()).event(any());
diff --git a/event-bus/api/src/test/java/org/apache/james/events/KeyContract.java b/event-bus/api/src/test/java/org/apache/james/events/KeyContract.java
index 6b2ae6b..190b517 100644
--- a/event-bus/api/src/test/java/org/apache/james/events/KeyContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/KeyContract.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.events;
 
+import static org.apache.james.events.EventBusTestFixture.EVENT_ID;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.junit.jupiter.api.Assertions.assertTimeout;
@@ -40,14 +41,9 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.IntStream;
 
 import org.apache.james.core.Username;
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.TestId;
 import org.junit.jupiter.api.Test;
 
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedMap;
 
 import reactor.core.publisher.Mono;
 import reactor.core.scheduler.Schedulers;
@@ -116,8 +112,7 @@ public interface KeyContract extends EventBusContract {
 
             Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
 
-            Username bob = Username.of("bob");
-            Added noopEvent = new Added(MailboxSession.SessionId.of(18), bob, MailboxPath.forUser(bob, "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
+            Event noopEvent = new EventBusTestFixture.TestEvent(EVENT_ID, Username.of("noop"));
             eventBus().dispatch(noopEvent, EventBusTestFixture.KEY_1).block();
 
             verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
diff --git a/event-bus/cassandra/pom.xml b/event-bus/cassandra/pom.xml
index 6982714..b085d77 100644
--- a/event-bus/cassandra/pom.xml
+++ b/event-bus/cassandra/pom.xml
@@ -33,11 +33,6 @@
 
     <dependencies>
         <dependency>
-            <groupId>${james.groupId}</groupId>
-            <artifactId>testing-base</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>apache-james-backends-cassandra</artifactId>
         </dependency>
@@ -48,25 +43,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-mailbox-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-mailbox-api</artifactId>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-mailbox-event-json</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-mailbox-store</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-api</artifactId>
         </dependency>
@@ -77,6 +53,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>testing-base</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.testcontainers</groupId>
             <artifactId>testcontainers</artifactId>
             <scope>test</scope>
diff --git a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java
index 18fd9a6..114022d 100644
--- a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java
+++ b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java
@@ -23,10 +23,6 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
-import org.apache.james.event.json.MailboxEventSerializer;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.mailbox.model.TestMessageId;
-import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
@@ -40,7 +36,7 @@ class CassandraEventDeadLettersDAOTest {
 
     @BeforeEach
     void setUp(CassandraCluster cassandraCluster) {
-        MailboxEventSerializer eventSerializer = new MailboxEventSerializer(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
+        EventSerializer eventSerializer = new EventBusTestFixture.TestEventSerializer();
         cassandraEventDeadLettersDAO = new CassandraEventDeadLettersDAO(cassandraCluster.getConf(), eventSerializer);
     }
 
diff --git a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java
index dc2e218..7a47797 100644
--- a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java
+++ b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java
@@ -22,10 +22,7 @@ package org.apache.james.events;
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
 import org.apache.james.backends.cassandra.DockerCassandra;
-import org.apache.james.event.json.MailboxEventSerializer;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.mailbox.model.TestMessageId;
-import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
+import org.apache.james.events.EventBusTestFixture.TestEventSerializer;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
@@ -39,7 +36,7 @@ class CassandraEventDeadLettersHealthCheckTest implements EventDeadLettersHealth
 
     @BeforeEach
     void setUp(CassandraCluster cassandraCluster, DockerCassandra dockerCassandra) {
-        MailboxEventSerializer eventSerializer = new MailboxEventSerializer(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
+        EventSerializer eventSerializer = new TestEventSerializer();
         eventDeadLetters = new CassandraEventDeadLetters(new CassandraEventDeadLettersDAO(cassandraCluster.getConf(), eventSerializer),
                                                          new CassandraEventDeadLettersGroupDAO(cassandraCluster.getConf()));
         testee = new EventDeadLettersHealthCheck(eventDeadLetters);
diff --git a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersTest.java b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersTest.java
index 8b0dd15..e9ba83a 100644
--- a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersTest.java
+++ b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersTest.java
@@ -21,10 +21,7 @@ package org.apache.james.events;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
-import org.apache.james.event.json.MailboxEventSerializer;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.mailbox.model.TestMessageId;
-import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
+import org.apache.james.events.EventBusTestFixture.TestEventSerializer;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
@@ -37,7 +34,7 @@ class CassandraEventDeadLettersTest implements EventDeadLettersContract.AllContr
 
     @BeforeEach
     void setUp(CassandraCluster cassandraCluster) {
-        MailboxEventSerializer eventSerializer = new MailboxEventSerializer(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
+        EventSerializer eventSerializer = new TestEventSerializer();
         eventDeadLetters = new CassandraEventDeadLetters(new CassandraEventDeadLettersDAO(cassandraCluster.getConf(), eventSerializer),
                                                          new CassandraEventDeadLettersGroupDAO(cassandraCluster.getConf()));
     }
diff --git a/event-bus/distributed/pom.xml b/event-bus/distributed/pom.xml
index be6d2a1..ea6a729 100644
--- a/event-bus/distributed/pom.xml
+++ b/event-bus/distributed/pom.xml
@@ -33,30 +33,6 @@
 
     <dependencies>
         <dependency>
-            <groupId>${james.groupId}</groupId>
-            <artifactId>apache-james-mailbox-store</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
-            <artifactId>james-server-lifecycle-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
-            <artifactId>james-server-testing</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
-            <artifactId>metrics-tests</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
-            <artifactId>testing-base</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>apache-james-backends-rabbitmq</artifactId>
         </dependency>
@@ -67,37 +43,42 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-mailbox-api</artifactId>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-mailbox-api</artifactId>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
             <type>test-jar</type>
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-mailbox-event-json</artifactId>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-in-vm</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>event-bus-api</artifactId>
+            <artifactId>james-server-lifecycle-api</artifactId>
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>event-bus-api</artifactId>
-            <type>test-jar</type>
+            <artifactId>james-server-testing</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>metrics-api</artifactId>
+        </dependency>
+        <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>event-bus-in-vm</artifactId>
+            <artifactId>metrics-tests</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>metrics-api</artifactId>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>testing-base</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>io.projectreactor</groupId>
diff --git a/event-bus/distributed/src/test/java/org/apache/james/events/LocalListenerRegistryTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/LocalListenerRegistryTest.java
index a3de3f6..36953c6 100644
--- a/event-bus/distributed/src/test/java/org/apache/james/events/LocalListenerRegistryTest.java
+++ b/event-bus/distributed/src/test/java/org/apache/james/events/LocalListenerRegistryTest.java
@@ -26,7 +26,6 @@ import java.time.Duration;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.apache.james.mailbox.model.TestId;
 import org.apache.james.util.concurrency.ConcurrentTestRunner;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
@@ -36,7 +35,7 @@ import reactor.core.publisher.Mono;
 import reactor.core.scheduler.Schedulers;
 
 class LocalListenerRegistryTest {
-    private static final MailboxIdRegistrationKey KEY_1 = new MailboxIdRegistrationKey(TestId.of(42));
+    private static final RegistrationKey KEY_1 = new EventBusTestFixture.TestRegistrationKey("a");
 
     private LocalListenerRegistry testee;
 
diff --git a/event-bus/distributed/src/test/java/org/apache/james/events/NetworkErrorTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/NetworkErrorTest.java
index 6584860..56d903c 100644
--- a/event-bus/distributed/src/test/java/org/apache/james/events/NetworkErrorTest.java
+++ b/event-bus/distributed/src/test/java/org/apache/james/events/NetworkErrorTest.java
@@ -29,10 +29,7 @@ import static org.mockito.Mockito.verify;
 
 import org.apache.james.backends.rabbitmq.RabbitMQExtension;
 import org.apache.james.backends.rabbitmq.RabbitMQFixture;
-import org.apache.james.event.json.MailboxEventSerializer;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.mailbox.model.TestMessageId;
-import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
+import org.apache.james.events.EventBusTestFixture.TestEventSerializer;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
@@ -50,9 +47,9 @@ class NetworkErrorTest {
     void setUp() {
         MemoryEventDeadLetters memoryEventDeadLetters = new MemoryEventDeadLetters();
 
-        TestId.Factory mailboxIdFactory = new TestId.Factory();
-        MailboxEventSerializer eventSerializer = new MailboxEventSerializer(mailboxIdFactory, new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
-        RoutingKeyConverter routingKeyConverter = RoutingKeyConverter.forFactories(new MailboxIdRegistrationKey.Factory(mailboxIdFactory));
+
+        EventSerializer eventSerializer = new TestEventSerializer();
+        RoutingKeyConverter routingKeyConverter = RoutingKeyConverter.forFactories(new EventBusTestFixture.TestRegistrationKeyFactory());
 
         eventBus = new RabbitMQEventBus(rabbitMQExtension.getSender(), rabbitMQExtension.getReceiverProvider(),
             eventSerializer, RETRY_BACKOFF_CONFIGURATION, routingKeyConverter,
diff --git a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
index 4f46d3f..9e9f284 100644
--- a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
+++ b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
@@ -26,13 +26,10 @@ import static org.apache.james.events.EventBusTestFixture.RETRY_BACKOFF_CONFIGUR
 import static org.assertj.core.api.Assertions.assertThatCode;
 
 import org.apache.james.backends.rabbitmq.RabbitMQExtension;
-import org.apache.james.event.json.MailboxEventSerializer;
 import org.apache.james.events.EventBusTestFixture.GroupA;
+import org.apache.james.events.EventBusTestFixture.TestEventSerializer;
+import org.apache.james.events.EventBusTestFixture.TestRegistrationKeyFactory;
 import org.apache.james.events.GroupRegistration.WorkQueueName;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.mailbox.model.TestMessageId;
-import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
-import org.apache.james.mailbox.util.EventCollector;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
@@ -52,9 +49,8 @@ class RabbitMQEventBusDeadLetterQueueUpgradeTest {
     void setUp() {
         MemoryEventDeadLetters memoryEventDeadLetters = new MemoryEventDeadLetters();
 
-        TestId.Factory mailboxIdFactory = new TestId.Factory();
-        MailboxEventSerializer eventSerializer = new MailboxEventSerializer(mailboxIdFactory, new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
-        RoutingKeyConverter routingKeyConverter = RoutingKeyConverter.forFactories(new MailboxIdRegistrationKey.Factory(mailboxIdFactory));
+        EventSerializer eventSerializer = new TestEventSerializer();
+        RoutingKeyConverter routingKeyConverter = RoutingKeyConverter.forFactories(new TestRegistrationKeyFactory());
 
         eventBus = new RabbitMQEventBus(rabbitMQExtension.getSender(), rabbitMQExtension.getReceiverProvider(),
             eventSerializer, RETRY_BACKOFF_CONFIGURATION, routingKeyConverter,
diff --git a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
index fb0e353..5641089 100644
--- a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
+++ b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
@@ -63,14 +63,12 @@ import org.apache.james.backends.rabbitmq.RabbitMQExtension.DockerRestartPolicy;
 import org.apache.james.backends.rabbitmq.RabbitMQFixture;
 import org.apache.james.backends.rabbitmq.RabbitMQManagementAPI;
 import org.apache.james.backends.rabbitmq.ReceiverProvider;
-import org.apache.james.event.json.MailboxEventSerializer;
 import org.apache.james.events.EventBusTestFixture.EventListenerCountingSuccessfulExecution;
 import org.apache.james.events.EventBusTestFixture.GroupA;
+import org.apache.james.events.EventBusTestFixture.TestEventSerializer;
+import org.apache.james.events.EventBusTestFixture.TestRegistrationKeyFactory;
 import org.apache.james.events.EventDispatcher.DispatchingFailureGroup;
 import org.apache.james.events.RoutingKeyConverter.RoutingKey;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.mailbox.model.TestMessageId;
-import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
 import org.apache.james.util.concurrency.ConcurrentTestRunner;
 import org.assertj.core.data.Percentage;
@@ -106,7 +104,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
     private RabbitMQEventBus eventBus2;
     private RabbitMQEventBus eventBus3;
     private RabbitMQEventBus eventBusWithKeyHandlerNotStarted;
-    private MailboxEventSerializer eventSerializer;
+    private EventSerializer eventSerializer;
     private RoutingKeyConverter routingKeyConverter;
     private MemoryEventDeadLetters memoryEventDeadLetters;
 
@@ -119,9 +117,8 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
     void setUp() {
         memoryEventDeadLetters = new MemoryEventDeadLetters();
 
-        TestId.Factory mailboxIdFactory = new TestId.Factory();
-        eventSerializer = new MailboxEventSerializer(mailboxIdFactory, new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
-        routingKeyConverter = RoutingKeyConverter.forFactories(new MailboxIdRegistrationKey.Factory(mailboxIdFactory));
+        eventSerializer = new TestEventSerializer();
+        routingKeyConverter = RoutingKeyConverter.forFactories(new TestRegistrationKeyFactory());
 
         eventBus = newEventBus();
         eventBus2 = newEventBus();
@@ -279,7 +276,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
 
     @Test
     void deserializeEventCollectorGroup() throws Exception {
-        assertThat(Group.deserialize("org.apache.james.mailbox.util.EventCollector$EventCollectorGroup"))
+        assertThat(Group.deserialize("org.apache.james.events.EventCollector$EventCollectorGroup"))
             .isEqualTo(new EventCollector.EventCollectorGroup());
     }
 
@@ -417,8 +414,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
                     .blockFirst()
                     .getBody();
 
-                return eventSerializer.fromJson(new String(eventInBytes, StandardCharsets.UTF_8))
-                    .get();
+                return eventSerializer.asEvent(new String(eventInBytes, StandardCharsets.UTF_8));
             }
         }
     }
diff --git a/event-bus/distributed/src/test/java/org/apache/james/events/RoutingKeyConverterTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/RoutingKeyConverterTest.java
index d07d95a..f41bfa3 100644
--- a/event-bus/distributed/src/test/java/org/apache/james/events/RoutingKeyConverterTest.java
+++ b/event-bus/distributed/src/test/java/org/apache/james/events/RoutingKeyConverterTest.java
@@ -24,26 +24,27 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.util.Objects;
 
-import org.apache.james.mailbox.model.TestId;
+import org.apache.james.events.EventBusTestFixture.TestRegistrationKey;
+import org.apache.james.events.EventBusTestFixture.TestRegistrationKeyFactory;
 import org.junit.jupiter.api.Test;
 
 class RoutingKeyConverterTest {
-    static class TestRegistrationKey implements RegistrationKey {
+    static class OtherTestRegistrationKey implements RegistrationKey {
         static class Factory implements RegistrationKey.Factory {
             @Override
             public Class<? extends RegistrationKey> forClass() {
-                return TestRegistrationKey.class;
+                return OtherTestRegistrationKey.class;
             }
 
             @Override
             public RegistrationKey fromString(String asString) {
-                return new TestRegistrationKey(asString);
+                return new OtherTestRegistrationKey(asString);
             }
         }
 
         private final String value;
 
-        TestRegistrationKey(String value) {
+        OtherTestRegistrationKey(String value) {
             this.value = value;
         }
 
@@ -54,8 +55,8 @@ class RoutingKeyConverterTest {
 
         @Override
         public final boolean equals(Object o) {
-            if (o instanceof TestRegistrationKey) {
-                TestRegistrationKey that = (TestRegistrationKey) o;
+            if (o instanceof OtherTestRegistrationKey) {
+                OtherTestRegistrationKey that = (OtherTestRegistrationKey) o;
 
                 return Objects.equals(this.value, that.value);
             }
@@ -68,12 +69,12 @@ class RoutingKeyConverterTest {
         }
     }
 
-    private static final RegistrationKey REGISTRATION_KEY_1 = new MailboxIdRegistrationKey(TestId.of(42));
-    private static final String ROUTING_KEY_1 = "org.apache.james.mailbox.events.MailboxIdRegistrationKey:42";
+    private static final RegistrationKey REGISTRATION_KEY_1 = new TestRegistrationKey("a");
+    private static final String ROUTING_KEY_1 = "org.apache.james.events.EventBusTestFixture$TestRegistrationKey:a";
 
     private RoutingKeyConverter testee = RoutingKeyConverter.forFactories(
-        new TestRegistrationKey.Factory(),
-        new MailboxIdRegistrationKey.Factory(new TestId.Factory()));
+        new OtherTestRegistrationKey.Factory(),
+        new TestRegistrationKeyFactory());
 
     @Test
     void toRoutingKeyShouldTransformAKeyIntoAString() {
@@ -89,26 +90,26 @@ class RoutingKeyConverterTest {
 
     @Test
     void toRoutingKeyShouldAcceptSeparator() {
-        assertThat(RoutingKeyConverter.RoutingKey.of(new TestRegistrationKey("a:b")).asString())
-            .isEqualTo("org.apache.james.mailbox.events.RoutingKeyConverterTest$TestRegistrationKey:a:b");
+        assertThat(RoutingKeyConverter.RoutingKey.of(new OtherTestRegistrationKey("a:b")).asString())
+            .isEqualTo("org.apache.james.events.RoutingKeyConverterTest$OtherTestRegistrationKey:a:b");
     }
 
     @Test
     void toRegistrationKeyShouldAcceptSeparator() {
-        assertThat(testee.toRegistrationKey("org.apache.james.mailbox.events.RoutingKeyConverterTest$TestRegistrationKey:a:b"))
-            .isEqualTo(new TestRegistrationKey("a:b"));
+        assertThat(testee.toRegistrationKey("org.apache.james.events.RoutingKeyConverterTest$OtherTestRegistrationKey:a:b"))
+            .isEqualTo(new OtherTestRegistrationKey("a:b"));
     }
 
     @Test
     void toRoutingKeyShouldAcceptEmptyValue() {
-        assertThat(RoutingKeyConverter.RoutingKey.of(new TestRegistrationKey("")).asString())
-            .isEqualTo("org.apache.james.mailbox.events.RoutingKeyConverterTest$TestRegistrationKey:");
+        assertThat(RoutingKeyConverter.RoutingKey.of(new OtherTestRegistrationKey("")).asString())
+            .isEqualTo("org.apache.james.events.RoutingKeyConverterTest$OtherTestRegistrationKey:");
     }
 
     @Test
     void toRegistrationKeyShouldAcceptEmptyValue() {
-        assertThat(testee.toRegistrationKey("org.apache.james.mailbox.events.RoutingKeyConverterTest$TestRegistrationKey:"))
-            .isEqualTo(new TestRegistrationKey(""));
+        assertThat(testee.toRegistrationKey("org.apache.james.events.RoutingKeyConverterTest$OtherTestRegistrationKey:"))
+            .isEqualTo(new OtherTestRegistrationKey(""));
     }
 
     @Test
diff --git a/event-bus/in-vm/pom.xml b/event-bus/in-vm/pom.xml
index 69208ba..00a3536 100644
--- a/event-bus/in-vm/pom.xml
+++ b/event-bus/in-vm/pom.xml
@@ -34,32 +34,22 @@
     <dependencies>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>metrics-tests</artifactId>
-            <scope>test</scope>
+            <artifactId>event-bus-api</artifactId>
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>testing-base</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-mailbox-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-mailbox-api</artifactId>
+            <artifactId>event-bus-api</artifactId>
             <type>test-jar</type>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>event-bus-api</artifactId>
+            <artifactId>metrics-tests</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>event-bus-api</artifactId>
-            <type>test-jar</type>
+            <artifactId>testing-base</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
index c420f61..a32c06e 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
@@ -39,7 +39,6 @@ import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
 import org.apache.james.events.EventBus;
-import org.apache.james.events.EventBusTestFixture;
 import org.apache.james.events.InVMEventBus;
 import org.apache.james.events.MailboxEvents.Added;
 import org.apache.james.events.MailboxEvents.Expunged;
@@ -110,7 +109,7 @@ public abstract class AbstractMessageIdManagerSideEffectTest {
 
     @BeforeEach
     void setUp() throws Exception {
-        eventBus = new InVMEventBus(new InVmEventDelivery(new RecordingMetricFactory()), EventBusTestFixture.RETRY_BACKOFF_CONFIGURATION, new MemoryEventDeadLetters());
+        eventBus = new InVMEventBus(new InVmEventDelivery(new RecordingMetricFactory()), StoreMailboxManagerTest.RETRY_BACKOFF_CONFIGURATION, new MemoryEventDeadLetters());
         eventCollector = new EventCollector();
         quotaManager = mock(QuotaManager.class);
 
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerTest.java
index 2126d3f..2eec7fc 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerTest.java
@@ -26,9 +26,9 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import org.apache.james.core.Username;
-import org.apache.james.events.EventBusTestFixture;
 import org.apache.james.events.InVMEventBus;
 import org.apache.james.events.MemoryEventDeadLetters;
+import org.apache.james.events.RetryBackoffConfiguration;
 import org.apache.james.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.MailboxSession;
@@ -72,6 +72,13 @@ class StoreMailboxManagerTest {
     static final Username UNKNOWN_USER = Username.of("otheruser");
     static final String BAD_PASSWORD = "badpassword";
     static final String EMPTY_PREFIX = "";
+    static final double DEFAULT_JITTER_FACTOR = 0.5;
+    static final java.time.Duration DEFAULT_FIRST_BACKOFF = java.time.Duration.ofMillis(5);
+    public static final RetryBackoffConfiguration RETRY_BACKOFF_CONFIGURATION = RetryBackoffConfiguration.builder()
+        .maxRetries(3)
+        .firstBackoff(DEFAULT_FIRST_BACKOFF)
+        .jitterFactor(DEFAULT_JITTER_FACTOR)
+        .build();
 
     StoreMailboxManager storeMailboxManager;
     MailboxMapper mockedMailboxMapper;
@@ -89,7 +96,7 @@ class StoreMailboxManagerTest {
         authenticator.addUser(CURRENT_USER, CURRENT_USER_PASSWORD);
         authenticator.addUser(ADMIN, ADMIN_PASSWORD);
 
-        InVMEventBus eventBus = new InVMEventBus(new InVmEventDelivery(new RecordingMetricFactory()), EventBusTestFixture.RETRY_BACKOFF_CONFIGURATION, new MemoryEventDeadLetters());
+        InVMEventBus eventBus = new InVMEventBus(new InVmEventDelivery(new RecordingMetricFactory()), RETRY_BACKOFF_CONFIGURATION, new MemoryEventDeadLetters());
 
         StoreRightManager storeRightManager = new StoreRightManager(mockedMapperFactory, new UnionMailboxACLResolver(),
                                                                     new SimpleGroupMembershipResolver(), eventBus);


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


[james-project] 13/18: JAMES-3498 Restore static imports

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 cfce689fcd2e55e59e689f78dbd10218ef82a2b3
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 25 18:58:43 2021 +0700

    JAMES-3498 Restore static imports
---
 .../events/EventBusConcurrentTestContract.java     | 131 +++++++------
 .../org/apache/james/events/EventBusContract.java  |  16 +-
 .../james/events/EventDeadLettersContract.java     |  51 ++---
 .../EventDeadLettersHealthCheckContract.java       |   7 +-
 .../org/apache/james/events/GroupContract.java     | 184 +++++++++---------
 .../java/org/apache/james/events/KeyContract.java  | 206 +++++++++++----------
 .../james/events/CassandraEventDeadLettersDAO.java |  57 +++---
 .../events/CassandraEventDeadLettersGroupDAO.java  |  15 +-
 .../events/CassandraEventDeadLettersDAOTest.java   |  57 +++---
 .../CassandraEventDeadLettersGroupDAOTest.java     |   8 +-
 .../apache/james/events/GroupConsumerRetry.java    |   3 +-
 .../org/apache/james/events/GroupRegistration.java |   3 +-
 .../james/events/KeyReconnectionHandler.java       |   4 +-
 .../events/delivery/InVmEventDeliveryTest.java     |  90 ++++-----
 14 files changed, 441 insertions(+), 391 deletions(-)

diff --git a/event-bus/api/src/test/java/org/apache/james/events/EventBusConcurrentTestContract.java b/event-bus/api/src/test/java/org/apache/james/events/EventBusConcurrentTestContract.java
index 6648458..8905df3 100644
--- a/event-bus/api/src/test/java/org/apache/james/events/EventBusConcurrentTestContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/EventBusConcurrentTestContract.java
@@ -19,6 +19,11 @@
 
 package org.apache.james.events;
 
+import static org.apache.james.events.EventBusTestFixture.EVENT;
+import static org.apache.james.events.EventBusTestFixture.KEY_1;
+import static org.apache.james.events.EventBusTestFixture.KEY_2;
+import static org.apache.james.events.EventBusTestFixture.KEY_3;
+import static org.apache.james.events.EventBusTestFixture.NO_KEYS;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.awaitility.Awaitility.await;
 
@@ -26,6 +31,10 @@ import java.time.Duration;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.james.events.EventBusTestFixture.EventListenerCountingSuccessfulExecution;
+import org.apache.james.events.EventBusTestFixture.GroupA;
+import org.apache.james.events.EventBusTestFixture.GroupB;
+import org.apache.james.events.EventBusTestFixture.GroupC;
 import org.apache.james.util.concurrency.ConcurrentTestRunner;
 import org.awaitility.core.ConditionFactory;
 import org.junit.jupiter.api.Test;
@@ -44,15 +53,15 @@ public interface EventBusConcurrentTestContract {
     int OPERATION_COUNT = 30;
     int TOTAL_DISPATCH_OPERATIONS = THREAD_COUNT * OPERATION_COUNT;
 
-    Set<RegistrationKey> ALL_KEYS = ImmutableSet.of(EventBusTestFixture.KEY_1, EventBusTestFixture.KEY_2, EventBusTestFixture.KEY_3);
+    Set<RegistrationKey> ALL_KEYS = ImmutableSet.of(KEY_1, KEY_2, KEY_3);
 
-    static EventBusTestFixture.EventListenerCountingSuccessfulExecution newCountingListener() {
-        return new EventBusTestFixture.EventListenerCountingSuccessfulExecution();
+    static EventListenerCountingSuccessfulExecution newCountingListener() {
+        return new EventListenerCountingSuccessfulExecution();
     }
 
-    static int totalEventsReceived(ImmutableList<EventBusTestFixture.EventListenerCountingSuccessfulExecution> allListeners) {
+    static int totalEventsReceived(ImmutableList<EventListenerCountingSuccessfulExecution> allListeners) {
         return allListeners.stream()
-            .mapToInt(EventBusTestFixture.EventListenerCountingSuccessfulExecution::numberOfEventCalls)
+            .mapToInt(EventListenerCountingSuccessfulExecution::numberOfEventCalls)
             .sum();
     }
 
@@ -60,17 +69,17 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchGroupShouldDeliverAllEventsToListenersWithSingleEventBus() throws Exception {
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
 
-            eventBus().register(countingListener1, new EventBusTestFixture.GroupA());
-            eventBus().register(countingListener2, new EventBusTestFixture.GroupB());
-            eventBus().register(countingListener3, new EventBusTestFixture.GroupC());
+            eventBus().register(countingListener1, new GroupA());
+            eventBus().register(countingListener2, new GroupB());
+            eventBus().register(countingListener3, new GroupC());
             int totalGlobalRegistrations = 3; // GroupA + GroupB + GroupC
 
             ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block())
+                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, NO_KEYS).block())
                 .threadCount(THREAD_COUNT)
                 .operationCount(OPERATION_COUNT)
                 .runSuccessfullyWithin(FIVE_SECONDS);
@@ -82,18 +91,18 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchKeyShouldDeliverAllEventsToListenersWithSingleEventBus() throws Exception {
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
-            Mono.from(eventBus().register(countingListener1, EventBusTestFixture.KEY_1)).block();
-            Mono.from(eventBus().register(countingListener2, EventBusTestFixture.KEY_2)).block();
-            Mono.from(eventBus().register(countingListener3, EventBusTestFixture.KEY_3)).block();
+            EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            Mono.from(eventBus().register(countingListener1, KEY_1)).block();
+            Mono.from(eventBus().register(countingListener2, KEY_2)).block();
+            Mono.from(eventBus().register(countingListener3, KEY_3)).block();
 
             int totalKeyListenerRegistrations = 3; // KEY1 + KEY2 + KEY3
             int totalEventBus = 1;
 
             ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EventBusTestFixture.EVENT, ALL_KEYS).block())
+                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, ALL_KEYS).block())
                 .threadCount(THREAD_COUNT)
                 .operationCount(OPERATION_COUNT)
                 .runSuccessfullyWithin(FIVE_SECONDS);
@@ -105,25 +114,25 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchShouldDeliverAllEventsToListenersWithSingleEventBus() throws Exception {
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
 
-            eventBus().register(countingListener1, new EventBusTestFixture.GroupA());
-            eventBus().register(countingListener2, new EventBusTestFixture.GroupB());
-            eventBus().register(countingListener3, new EventBusTestFixture.GroupC());
+            eventBus().register(countingListener1, new GroupA());
+            eventBus().register(countingListener2, new GroupB());
+            eventBus().register(countingListener3, new GroupC());
 
             int totalGlobalRegistrations = 3; // GroupA + GroupB + GroupC
             int totalEventDeliveredGlobally = totalGlobalRegistrations * TOTAL_DISPATCH_OPERATIONS;
 
-            Mono.from(eventBus().register(countingListener1, EventBusTestFixture.KEY_1)).block();
-            Mono.from(eventBus().register(countingListener2, EventBusTestFixture.KEY_2)).block();
-            Mono.from(eventBus().register(countingListener3, EventBusTestFixture.KEY_3)).block();
+            Mono.from(eventBus().register(countingListener1, KEY_1)).block();
+            Mono.from(eventBus().register(countingListener2, KEY_2)).block();
+            Mono.from(eventBus().register(countingListener3, KEY_3)).block();
             int totalKeyListenerRegistrations = 3; // KEY1 + KEY2 + KEY3
             int totalEventDeliveredByKeys = totalKeyListenerRegistrations * TOTAL_DISPATCH_OPERATIONS;
 
             ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EventBusTestFixture.EVENT, ALL_KEYS).block())
+                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, ALL_KEYS).block())
                 .threadCount(THREAD_COUNT)
                 .operationCount(OPERATION_COUNT)
                 .runSuccessfullyWithin(FIVE_SECONDS);
@@ -140,22 +149,22 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchGroupShouldDeliverAllEventsToListenersWithMultipleEventBus() throws Exception {
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
 
-            eventBus().register(countingListener1, new EventBusTestFixture.GroupA());
-            eventBus().register(countingListener2, new EventBusTestFixture.GroupB());
-            eventBus().register(countingListener3, new EventBusTestFixture.GroupC());
+            eventBus().register(countingListener1, new GroupA());
+            eventBus().register(countingListener2, new GroupB());
+            eventBus().register(countingListener3, new GroupC());
 
-            eventBus2().register(countingListener1, new EventBusTestFixture.GroupA());
-            eventBus2().register(countingListener2, new EventBusTestFixture.GroupB());
-            eventBus2().register(countingListener3, new EventBusTestFixture.GroupC());
+            eventBus2().register(countingListener1, new GroupA());
+            eventBus2().register(countingListener2, new GroupB());
+            eventBus2().register(countingListener3, new GroupC());
 
             int totalGlobalRegistrations = 3; // GroupA + GroupB + GroupC
 
             ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block())
+                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, NO_KEYS).block())
                 .threadCount(THREAD_COUNT)
                 .operationCount(OPERATION_COUNT)
                 .runSuccessfullyWithin(FIVE_SECONDS);
@@ -167,23 +176,23 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchKeyShouldDeliverAllEventsToListenersWithMultipleEventBus() throws Exception {
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
 
-            Mono.from(eventBus().register(countingListener1, EventBusTestFixture.KEY_1)).block();
-            Mono.from(eventBus().register(countingListener2, EventBusTestFixture.KEY_2)).block();
-            Mono.from(eventBus().register(countingListener3, EventBusTestFixture.KEY_3)).block();
+            Mono.from(eventBus().register(countingListener1, KEY_1)).block();
+            Mono.from(eventBus().register(countingListener2, KEY_2)).block();
+            Mono.from(eventBus().register(countingListener3, KEY_3)).block();
 
-            Mono.from(eventBus2().register(countingListener1, EventBusTestFixture.KEY_1)).block();
-            Mono.from(eventBus2().register(countingListener2, EventBusTestFixture.KEY_2)).block();
-            Mono.from(eventBus2().register(countingListener3, EventBusTestFixture.KEY_3)).block();
+            Mono.from(eventBus2().register(countingListener1, KEY_1)).block();
+            Mono.from(eventBus2().register(countingListener2, KEY_2)).block();
+            Mono.from(eventBus2().register(countingListener3, KEY_3)).block();
 
             int totalKeyListenerRegistrations = 3; // KEY1 + KEY2 + KEY3
             int totalEventBus = 2; // eventBus1 + eventBus2
 
             ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EventBusTestFixture.EVENT, ALL_KEYS).block())
+                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, ALL_KEYS).block())
                 .threadCount(THREAD_COUNT)
                 .operationCount(OPERATION_COUNT)
                 .runSuccessfullyWithin(FIVE_SECONDS);
@@ -195,31 +204,31 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchShouldDeliverAllEventsToListenersWithMultipleEventBus() throws Exception {
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
 
             eventBus2().register(countingListener1, EventDeadLettersContract.GROUP_A);
-            eventBus2().register(countingListener2, new EventBusTestFixture.GroupB());
-            eventBus2().register(countingListener3, new EventBusTestFixture.GroupC());
+            eventBus2().register(countingListener2, new GroupB());
+            eventBus2().register(countingListener3, new GroupC());
             int totalGlobalRegistrations = 3; // GroupA + GroupB + GroupC
             int totalEventDeliveredGlobally = totalGlobalRegistrations * TOTAL_DISPATCH_OPERATIONS;
 
-            Mono.from(eventBus().register(countingListener1, EventBusTestFixture.KEY_1)).block();
-            Mono.from(eventBus().register(countingListener2, EventBusTestFixture.KEY_2)).block();
+            Mono.from(eventBus().register(countingListener1, KEY_1)).block();
+            Mono.from(eventBus().register(countingListener2, KEY_2)).block();
 
-            Mono.from(eventBus2().register(countingListener1, EventBusTestFixture.KEY_1)).block();
-            Mono.from(eventBus2().register(countingListener2, EventBusTestFixture.KEY_2)).block();
+            Mono.from(eventBus2().register(countingListener1, KEY_1)).block();
+            Mono.from(eventBus2().register(countingListener2, KEY_2)).block();
 
-            Mono.from(eventBus3().register(countingListener3, EventBusTestFixture.KEY_1)).block();
-            Mono.from(eventBus3().register(countingListener3, EventBusTestFixture.KEY_2)).block();
+            Mono.from(eventBus3().register(countingListener3, KEY_1)).block();
+            Mono.from(eventBus3().register(countingListener3, KEY_2)).block();
 
             int totalKeyListenerRegistrations = 2; // KEY1 + KEY2
             int totalEventBus = 3; // eventBus1 + eventBus2 + eventBus3
             int totalEventDeliveredByKeys = totalKeyListenerRegistrations * totalEventBus * TOTAL_DISPATCH_OPERATIONS;
 
             ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EventBusTestFixture.EVENT, ALL_KEYS).block())
+                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, ALL_KEYS).block())
                 .threadCount(THREAD_COUNT)
                 .operationCount(OPERATION_COUNT)
                 .runSuccessfullyWithin(FIVE_SECONDS);
diff --git a/event-bus/api/src/test/java/org/apache/james/events/EventBusContract.java b/event-bus/api/src/test/java/org/apache/james/events/EventBusContract.java
index c1b52f9..d439d9c 100644
--- a/event-bus/api/src/test/java/org/apache/james/events/EventBusContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/EventBusContract.java
@@ -19,10 +19,12 @@
 
 package org.apache.james.events;
 
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static org.awaitility.Awaitility.await;
+import static org.awaitility.Duration.ONE_HUNDRED_MILLISECONDS;
+import static org.awaitility.Duration.ZERO;
 
 import java.time.Duration;
-import java.util.concurrent.TimeUnit;
 
 import org.awaitility.core.ConditionFactory;
 
@@ -49,15 +51,15 @@ public interface EventBusContract {
         }
 
         public ConditionFactory shortWaitCondition() {
-            return await().pollDelay(org.awaitility.Duration.ZERO)
-                .pollInterval(org.awaitility.Duration.ONE_HUNDRED_MILLISECONDS)
-                .timeout(new org.awaitility.Duration(this.getShortWaitTime().toMillis(), TimeUnit.MILLISECONDS));
+            return await().pollDelay(ZERO)
+                .pollInterval(ONE_HUNDRED_MILLISECONDS)
+                .timeout(new org.awaitility.Duration(this.getShortWaitTime().toMillis(), MILLISECONDS));
         }
 
         public ConditionFactory longWaitCondition() {
-            return await().pollDelay(org.awaitility.Duration.ZERO)
-                .pollInterval(org.awaitility.Duration.ONE_HUNDRED_MILLISECONDS)
-                .timeout(new org.awaitility.Duration(this.getLongWaitTime().toMillis(), TimeUnit.MILLISECONDS));
+            return await().pollDelay(ZERO)
+                .pollInterval(ONE_HUNDRED_MILLISECONDS)
+                .timeout(new org.awaitility.Duration(this.getLongWaitTime().toMillis(), MILLISECONDS));
         }
     }
 
diff --git a/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersContract.java b/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersContract.java
index e351e26..20f0d56 100644
--- a/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersContract.java
@@ -32,6 +32,7 @@ import java.util.stream.Stream;
 
 import org.apache.james.core.Username;
 import org.apache.james.events.EventBusTestFixture.TestEvent;
+import org.apache.james.events.EventDeadLetters.InsertionId;
 import org.apache.james.util.concurrency.ConcurrentTestRunner;
 import org.junit.jupiter.api.Test;
 
@@ -107,19 +108,19 @@ interface EventDeadLettersContract {
     Event EVENT_1 = new TestEvent(EVENT_ID_1, USERNAME);
     Event EVENT_2 = new TestEvent(EVENT_ID_2, USERNAME);
     Event EVENT_3 = new TestEvent(EVENT_ID_3, USERNAME);
-    EventDeadLetters.InsertionId INSERTION_ID_1 = EventDeadLetters.InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b7");
-    EventDeadLetters.InsertionId INSERTION_ID_2 = EventDeadLetters.InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b8");
-    EventDeadLetters.InsertionId INSERTION_ID_3 = EventDeadLetters.InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b9");
+    InsertionId INSERTION_ID_1 = InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b7");
+    InsertionId INSERTION_ID_2 = InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b8");
+    InsertionId INSERTION_ID_3 = InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b9");
 
     Group GROUP_A = new EventBusTestFixture.GroupA();
     Group GROUP_B = new EventBusTestFixture.GroupB();
     Group NULL_GROUP = null;
     Event NULL_EVENT = null;
-    EventDeadLetters.InsertionId NULL_INSERTION_ID = null;
+    InsertionId NULL_INSERTION_ID = null;
 
     EventDeadLetters eventDeadLetters();
 
-    default Stream<EventDeadLetters.InsertionId> allInsertionIds() {
+    default Stream<InsertionId> allInsertionIds() {
         EventDeadLetters eventDeadLetters = eventDeadLetters();
 
         return eventDeadLetters.groupsWithFailedEvents()
@@ -157,7 +158,7 @@ interface EventDeadLettersContract {
         default void storeShouldStoreGroupWithCorrespondingEvent() {
             EventDeadLetters eventDeadLetters = eventDeadLetters();
 
-            EventDeadLetters.InsertionId insertionId = eventDeadLetters.store(GROUP_A, EVENT_1).block();
+            InsertionId insertionId = eventDeadLetters.store(GROUP_A, EVENT_1).block();
             assertThat(eventDeadLetters.failedEvent(GROUP_A, insertionId).block())
                 .isEqualTo(EVENT_1);
         }
@@ -167,12 +168,12 @@ interface EventDeadLettersContract {
             EventDeadLetters eventDeadLetters = eventDeadLetters();
 
             ImmutableMap<Integer, Group> groups = concurrentGroups();
-            Multimap<Integer, EventDeadLetters.InsertionId> storedInsertionIds = Multimaps.synchronizedSetMultimap(HashMultimap.create());
+            Multimap<Integer, InsertionId> storedInsertionIds = Multimaps.synchronizedSetMultimap(HashMultimap.create());
 
             ConcurrentTestRunner.builder()
                 .operation((threadNumber, step) -> {
                     Event.EventId eventId = Event.EventId.random();
-                    EventDeadLetters.InsertionId insertionId = eventDeadLetters.store(groups.get(threadNumber), event(eventId)).block();
+                    InsertionId insertionId = eventDeadLetters.store(groups.get(threadNumber), event(eventId)).block();
                     storedInsertionIds.put(threadNumber, insertionId);
                 })
                 .threadCount(THREAD_COUNT)
@@ -230,9 +231,9 @@ interface EventDeadLettersContract {
         default void removeShouldKeepNonMatched() {
             EventDeadLetters eventDeadLetters = eventDeadLetters();
 
-            EventDeadLetters.InsertionId insertionId1 = eventDeadLetters.store(GROUP_A, EVENT_1).block();
-            EventDeadLetters.InsertionId insertionId2 = eventDeadLetters.store(GROUP_A, EVENT_2).block();
-            EventDeadLetters.InsertionId insertionId3 = eventDeadLetters.store(GROUP_A, EVENT_3).block();
+            InsertionId insertionId1 = eventDeadLetters.store(GROUP_A, EVENT_1).block();
+            InsertionId insertionId2 = eventDeadLetters.store(GROUP_A, EVENT_2).block();
+            InsertionId insertionId3 = eventDeadLetters.store(GROUP_A, EVENT_3).block();
 
             eventDeadLetters.remove(GROUP_A, insertionId1).block();
 
@@ -265,13 +266,13 @@ interface EventDeadLettersContract {
             EventDeadLetters eventDeadLetters = eventDeadLetters();
 
             ImmutableMap<Integer, Group> groups = concurrentGroups();
-            ConcurrentHashMap<Integer, EventDeadLetters.InsertionId> storedInsertionIds = new ConcurrentHashMap<>();
+            ConcurrentHashMap<Integer, InsertionId> storedInsertionIds = new ConcurrentHashMap<>();
 
             ConcurrentTestRunner.builder()
                 .operation((threadNumber, step) -> {
                     int operationIndex = threadNumber * OPERATION_COUNT + step;
                     Event.EventId eventId = Event.EventId.random();
-                    EventDeadLetters.InsertionId insertionId = eventDeadLetters.store(groups.get(threadNumber), event(eventId)).block();
+                    InsertionId insertionId = eventDeadLetters.store(groups.get(threadNumber), event(eventId)).block();
                     storedInsertionIds.put(operationIndex, insertionId);
                 })
                 .threadCount(THREAD_COUNT)
@@ -334,7 +335,7 @@ interface EventDeadLettersContract {
         default void failedEventShouldReturnEventWhenContains() {
             EventDeadLetters eventDeadLetters = eventDeadLetters();
 
-            EventDeadLetters.InsertionId insertionId = eventDeadLetters.store(GROUP_A, EVENT_1).block();
+            InsertionId insertionId = eventDeadLetters.store(GROUP_A, EVENT_1).block();
             eventDeadLetters.store(GROUP_A, EVENT_2).block();
 
             assertThat(eventDeadLetters.failedEvent(GROUP_A, insertionId).block())
@@ -345,9 +346,9 @@ interface EventDeadLettersContract {
         default void failedEventShouldNotRemoveEvent() {
             EventDeadLetters eventDeadLetters = eventDeadLetters();
 
-            EventDeadLetters.InsertionId insertionId1 = eventDeadLetters.store(GROUP_A, EVENT_1).block();
-            EventDeadLetters.InsertionId insertionId2 = eventDeadLetters.store(GROUP_A, EVENT_2).block();
-            EventDeadLetters.InsertionId insertionId3 = eventDeadLetters.store(GROUP_A, EVENT_3).block();
+            InsertionId insertionId1 = eventDeadLetters.store(GROUP_A, EVENT_1).block();
+            InsertionId insertionId2 = eventDeadLetters.store(GROUP_A, EVENT_2).block();
+            InsertionId insertionId3 = eventDeadLetters.store(GROUP_A, EVENT_3).block();
 
             eventDeadLetters.failedEvent(GROUP_A, insertionId1).block();
 
@@ -359,7 +360,7 @@ interface EventDeadLettersContract {
         default void failedEventShouldNotThrowWhenNoGroupMatched() {
             EventDeadLetters eventDeadLetters = eventDeadLetters();
 
-            EventDeadLetters.InsertionId insertionId = eventDeadLetters.store(GROUP_A, EVENT_1).block();
+            InsertionId insertionId = eventDeadLetters.store(GROUP_A, EVENT_1).block();
 
             assertThatCode(() -> eventDeadLetters.failedEvent(GROUP_B, insertionId).block())
                 .doesNotThrowAnyException();
@@ -392,7 +393,7 @@ interface EventDeadLettersContract {
         default void failedEventsByGroupShouldReturnAllEventsCorrespondingToGivenGroup() {
             EventDeadLetters eventDeadLetters = eventDeadLetters();
 
-            EventDeadLetters.InsertionId insertionId = eventDeadLetters.store(GROUP_A, EVENT_1).block();
+            InsertionId insertionId = eventDeadLetters.store(GROUP_A, EVENT_1).block();
             eventDeadLetters.store(GROUP_B, EVENT_2).block();
             eventDeadLetters.store(GROUP_B, EVENT_3).block();
 
@@ -404,9 +405,9 @@ interface EventDeadLettersContract {
         default void failedEventsByGroupShouldNotRemoveEvents() {
             EventDeadLetters eventDeadLetters = eventDeadLetters();
 
-            EventDeadLetters.InsertionId insertionId1 = eventDeadLetters.store(GROUP_A, EVENT_1).block();
-            EventDeadLetters.InsertionId insertionId2 = eventDeadLetters.store(GROUP_A, EVENT_2).block();
-            EventDeadLetters.InsertionId insertionId3 = eventDeadLetters.store(GROUP_B, EVENT_3).block();
+            InsertionId insertionId1 = eventDeadLetters.store(GROUP_A, EVENT_1).block();
+            InsertionId insertionId2 = eventDeadLetters.store(GROUP_A, EVENT_2).block();
+            InsertionId insertionId3 = eventDeadLetters.store(GROUP_B, EVENT_3).block();
 
             eventDeadLetters.failedIds(GROUP_A).toStream();
 
@@ -453,8 +454,8 @@ interface EventDeadLettersContract {
         @Test
         default void containEventsShouldReturnFalseWhenRemoveAllStoredEvents() {
             EventDeadLetters eventDeadLetters = eventDeadLetters();
-            EventDeadLetters.InsertionId insertionId1 = eventDeadLetters().store(GROUP_A, EVENT_1).block();
-            EventDeadLetters.InsertionId insertionId2 = eventDeadLetters().store(GROUP_A, EVENT_2).block();
+            InsertionId insertionId1 = eventDeadLetters().store(GROUP_A, EVENT_1).block();
+            InsertionId insertionId2 = eventDeadLetters().store(GROUP_A, EVENT_2).block();
 
             assertThat(eventDeadLetters.containEvents().block()).isTrue();
 
@@ -467,7 +468,7 @@ interface EventDeadLettersContract {
         @Test
         default void containEventsShouldReturnTrueWhenRemoveSomeStoredEvents() {
             EventDeadLetters eventDeadLetters = eventDeadLetters();
-            EventDeadLetters.InsertionId insertionId1 = eventDeadLetters().store(GROUP_A, EVENT_1).block();
+            InsertionId insertionId1 = eventDeadLetters().store(GROUP_A, EVENT_1).block();
             eventDeadLetters().store(GROUP_B, EVENT_2).block();
 
             assertThat(eventDeadLetters.containEvents().block()).isTrue();
diff --git a/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java b/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java
index 335f1c7..fd1bb22 100644
--- a/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java
@@ -25,6 +25,7 @@ import org.apache.james.core.Username;
 import org.apache.james.core.healthcheck.ComponentName;
 import org.apache.james.core.healthcheck.Result;
 import org.apache.james.events.EventBusTestFixture.TestEvent;
+import org.apache.james.events.EventDeadLetters.InsertionId;
 import org.junit.jupiter.api.Test;
 
 interface EventDeadLettersHealthCheckContract {
@@ -78,8 +79,8 @@ interface EventDeadLettersHealthCheckContract {
 
     @Test
     default void checkShouldReturnHealthyWhenRemovedAllEventDeadLetters() {
-        EventDeadLetters.InsertionId insertionId1 = eventDeadLetters().store(GROUP_A, EVENT_1).block();
-        EventDeadLetters.InsertionId insertionId2 = eventDeadLetters().store(GROUP_B, EVENT_2).block();
+        InsertionId insertionId1 = eventDeadLetters().store(GROUP_A, EVENT_1).block();
+        InsertionId insertionId2 = eventDeadLetters().store(GROUP_B, EVENT_2).block();
 
         assertThat(testee().check().block().isDegraded()).isTrue();
         assertThat(testee().check().block())
@@ -95,7 +96,7 @@ interface EventDeadLettersHealthCheckContract {
 
     @Test
     default void checkShouldReturnDegradedWhenRemovedSomeEventDeadLetters() {
-        EventDeadLetters.InsertionId insertionId1 = eventDeadLetters().store(GROUP_A, EVENT_1).block();
+        InsertionId insertionId1 = eventDeadLetters().store(GROUP_A, EVENT_1).block();
         eventDeadLetters().store(GROUP_B, EVENT_2).block();
 
         assertThat(testee().check().block().isDegraded()).isTrue();
diff --git a/event-bus/api/src/test/java/org/apache/james/events/GroupContract.java b/event-bus/api/src/test/java/org/apache/james/events/GroupContract.java
index 246f6b7..db42ff7 100644
--- a/event-bus/api/src/test/java/org/apache/james/events/GroupContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/GroupContract.java
@@ -19,7 +19,15 @@
 
 package org.apache.james.events;
 
+import static org.apache.james.events.EventBusTestFixture.EVENT;
+import static org.apache.james.events.EventBusTestFixture.EVENT_2;
 import static org.apache.james.events.EventBusTestFixture.EVENT_ID;
+import static org.apache.james.events.EventBusTestFixture.EVENT_UNSUPPORTED_BY_LISTENER;
+import static org.apache.james.events.EventBusTestFixture.FIVE_HUNDRED_MS;
+import static org.apache.james.events.EventBusTestFixture.GROUP_A;
+import static org.apache.james.events.EventBusTestFixture.GROUP_B;
+import static org.apache.james.events.EventBusTestFixture.NO_KEYS;
+import static org.apache.james.events.EventBusTestFixture.ONE_SECOND;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -79,10 +87,10 @@ public interface GroupContract {
                     finishedExecutions.incrementAndGet();
 
                 }
-            }, EventBusTestFixture.GROUP_A);
+            }, GROUP_A);
 
             IntStream.range(0, eventCount)
-                .forEach(i -> eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block());
+                .forEach(i -> eventBus().dispatch(EVENT, NO_KEYS).block());
 
             getSpeedProfile().shortWaitCondition().atMost(org.awaitility.Duration.TEN_MINUTES)
                 .untilAsserted(() -> assertThat(finishedExecutions.get()).isEqualTo(eventCount));
@@ -105,7 +113,7 @@ public interface GroupContract {
                         threads.add(Thread.currentThread().getName());
                         countDownLatch.await();
                     }
-                }, EventBusTestFixture.GROUP_A);
+                }, GROUP_A);
                 eventBus().register(new EventListener.GroupEventListener() {
                     @Override
                     public Group getDefaultGroup() {
@@ -117,7 +125,7 @@ public interface GroupContract {
                         threads.add(Thread.currentThread().getName());
                         countDownLatch.await();
                     }
-                }, EventBusTestFixture.GROUP_B);
+                }, GROUP_B);
                 eventBus().register(new EventListener.GroupEventListener() {
                     @Override
                     public Group getDefaultGroup() {
@@ -131,7 +139,7 @@ public interface GroupContract {
                     }
                 }, EventBusTestFixture.GROUP_C);
 
-                eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).subscribeOn(Schedulers.elastic()).subscribe();
+                eventBus().dispatch(EVENT, NO_KEYS).subscribeOn(Schedulers.elastic()).subscribe();
 
 
                 getSpeedProfile().shortWaitCondition().atMost(org.awaitility.Duration.TEN_SECONDS)
@@ -147,15 +155,15 @@ public interface GroupContract {
             AtomicBoolean successfulRetry = new AtomicBoolean(false);
             EventListener listener = event -> {
                 if (event.getEventId().equals(EVENT_ID)) {
-                    eventBus().dispatch(EventBusTestFixture.EVENT_2, EventBusTestFixture.NO_KEYS)
+                    eventBus().dispatch(EVENT_2, NO_KEYS)
                         .subscribeOn(Schedulers.elastic())
                         .block();
                     successfulRetry.set(true);
                 }
             };
 
-            eventBus().register(listener, EventBusTestFixture.GROUP_A);
-            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+            eventBus().register(listener, GROUP_A);
+            eventBus().dispatch(EVENT, NO_KEYS).block();
 
             getSpeedProfile().shortWaitCondition().until(successfulRetry::get);
         }
@@ -164,11 +172,11 @@ public interface GroupContract {
         default void registerShouldNotDispatchPastEventsForGroups() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+            eventBus().dispatch(EVENT, NO_KEYS).block();
 
-            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            eventBus().register(listener, GROUP_A);
 
-            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
@@ -176,23 +184,23 @@ public interface GroupContract {
         default void listenerGroupShouldReceiveEvents() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
 
-            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            eventBus().register(listener, GROUP_A);
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+            eventBus().dispatch(EVENT, NO_KEYS).block();
 
-            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void groupListenersShouldNotReceiveNoopEvents() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
 
-            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            eventBus().register(listener, GROUP_A);
 
             Event noopEvent = new TestEvent(EVENT_ID, Username.of("noop"));
-            eventBus().dispatch(noopEvent, EventBusTestFixture.NO_KEYS).block();
+            eventBus().dispatch(noopEvent, NO_KEYS).block();
 
-            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
@@ -200,11 +208,11 @@ public interface GroupContract {
         default void groupListenersShouldReceiveOnlyHandledEvents() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
 
-            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            eventBus().register(listener, GROUP_A);
 
-            eventBus().dispatch(EventBusTestFixture.EVENT_UNSUPPORTED_BY_LISTENER, EventBusTestFixture.NO_KEYS).block();
+            eventBus().dispatch(EVENT_UNSUPPORTED_BY_LISTENER, NO_KEYS).block();
 
-            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
@@ -213,9 +221,9 @@ public interface GroupContract {
             EventListener listener = EventBusTestFixture.newListener();
             doThrow(new RuntimeException()).when(listener).event(any());
 
-            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            eventBus().register(listener, GROUP_A);
 
-            assertThatCode(() -> eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block())
+            assertThatCode(() -> eventBus().dispatch(EVENT, NO_KEYS).block())
                 .doesNotThrowAnyException();
         }
 
@@ -223,24 +231,24 @@ public interface GroupContract {
         default void eachListenerGroupShouldReceiveEvents() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
             EventListener listener2 = EventBusTestFixture.newListener();
-            eventBus().register(listener, EventBusTestFixture.GROUP_A);
-            eventBus().register(listener2, EventBusTestFixture.GROUP_B);
+            eventBus().register(listener, GROUP_A);
+            eventBus().register(listener2, GROUP_B);
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+            eventBus().dispatch(EVENT, NO_KEYS).block();
 
-            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
-            verify(listener2, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener2, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void unregisteredGroupListenerShouldNotReceiveEvents() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
-            Registration registration = eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            Registration registration = eventBus().register(listener, GROUP_A);
 
             registration.unregister();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
-            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+            eventBus().dispatch(EVENT, NO_KEYS).block();
+            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
@@ -249,9 +257,9 @@ public interface GroupContract {
             EventListener listener = EventBusTestFixture.newListener();
             EventListener listener2 = EventBusTestFixture.newListener();
 
-            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            eventBus().register(listener, GROUP_A);
 
-            assertThatThrownBy(() -> eventBus().register(listener2, EventBusTestFixture.GROUP_A))
+            assertThatThrownBy(() -> eventBus().register(listener2, GROUP_A))
                 .isInstanceOf(GroupAlreadyRegistered.class);
         }
 
@@ -260,9 +268,9 @@ public interface GroupContract {
             EventListener listener = EventBusTestFixture.newListener();
             EventListener listener2 = EventBusTestFixture.newListener();
 
-            eventBus().register(listener, EventBusTestFixture.GROUP_A).unregister();
+            eventBus().register(listener, GROUP_A).unregister();
 
-            assertThatCode(() -> eventBus().register(listener2, EventBusTestFixture.GROUP_A))
+            assertThatCode(() -> eventBus().register(listener2, GROUP_A))
                 .doesNotThrowAnyException();
         }
 
@@ -270,7 +278,7 @@ public interface GroupContract {
         default void unregisterShouldBeIdempotentForGroups() {
             EventListener listener = EventBusTestFixture.newListener();
 
-            Registration registration = eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            Registration registration = eventBus().register(listener, GROUP_A);
             registration.unregister();
 
             assertThatCode(registration::unregister)
@@ -281,32 +289,32 @@ public interface GroupContract {
         default void registerShouldAcceptAlreadyUnregisteredGroups() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
 
-            eventBus().register(listener, EventBusTestFixture.GROUP_A).unregister();
-            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            eventBus().register(listener, GROUP_A).unregister();
+            eventBus().register(listener, GROUP_A);
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+            eventBus().dispatch(EVENT, NO_KEYS).block();
 
-            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void dispatchShouldCallSynchronousListener() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
 
-            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            eventBus().register(listener, GROUP_A);
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+            eventBus().dispatch(EVENT, NO_KEYS).block();
 
-            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void failingGroupListenersShouldNotAbortGroupDelivery() {
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution listener = new EventBusTestFixture.EventMatcherThrowingListener(ImmutableSet.of(EventBusTestFixture.EVENT));
-            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution listener = new EventBusTestFixture.EventMatcherThrowingListener(ImmutableSet.of(EVENT));
+            eventBus().register(listener, GROUP_A);
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
-            eventBus().dispatch(EventBusTestFixture.EVENT_2, EventBusTestFixture.NO_KEYS).block();
+            eventBus().dispatch(EVENT, NO_KEYS).block();
+            eventBus().dispatch(EVENT_2, NO_KEYS).block();
 
             getSpeedProfile().shortWaitCondition()
                 .untilAsserted(() -> assertThat(listener.numberOfEventCalls()).isEqualTo(1));
@@ -320,12 +328,12 @@ public interface GroupContract {
             when(failingListener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
             doThrow(new RuntimeException()).when(failingListener).event(any());
 
-            eventBus().register(failingListener, EventBusTestFixture.GROUP_A);
-            eventBus().register(listener, EventBusTestFixture.GROUP_B);
+            eventBus().register(failingListener, GROUP_A);
+            eventBus().register(listener, GROUP_B);
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+            eventBus().dispatch(EVENT, NO_KEYS).block();
 
-            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
@@ -336,21 +344,21 @@ public interface GroupContract {
             eventBus().register(listener1, new GenericGroup("a"));
             eventBus().register(listener2, new GenericGroup("b"));
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+            eventBus().dispatch(EVENT, NO_KEYS).block();
 
-            verify(listener1, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
-            verify(listener2, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener1, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener2, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void groupListenerShouldReceiveEventWhenRedeliver() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
 
-            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            eventBus().register(listener, GROUP_A);
 
-            eventBus().reDeliver(EventBusTestFixture.GROUP_A, EventBusTestFixture.EVENT).block();
+            eventBus().reDeliver(GROUP_A, EVENT).block();
 
-            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
@@ -358,15 +366,15 @@ public interface GroupContract {
             EventListener listener = EventBusTestFixture.newListener();
             doThrow(new RuntimeException()).when(listener).event(any());
 
-            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            eventBus().register(listener, GROUP_A);
 
-            assertThatCode(() -> eventBus().reDeliver(EventBusTestFixture.GROUP_A, EventBusTestFixture.EVENT).block())
+            assertThatCode(() -> eventBus().reDeliver(GROUP_A, EVENT).block())
                 .doesNotThrowAnyException();
         }
 
         @Test
         default void redeliverShouldThrowWhenGroupNotRegistered() {
-            assertThatThrownBy(() -> eventBus().reDeliver(EventBusTestFixture.GROUP_A, EventBusTestFixture.EVENT).block())
+            assertThatThrownBy(() -> eventBus().reDeliver(GROUP_A, EVENT).block())
                 .isInstanceOf(GroupRegistrationNotFound.class);
         }
 
@@ -374,9 +382,9 @@ public interface GroupContract {
         default void redeliverShouldThrowAfterGroupIsUnregistered() {
             EventListener listener = EventBusTestFixture.newListener();
 
-            eventBus().register(listener, EventBusTestFixture.GROUP_A).unregister();
+            eventBus().register(listener, GROUP_A).unregister();
 
-            assertThatThrownBy(() -> eventBus().reDeliver(EventBusTestFixture.GROUP_A, EventBusTestFixture.EVENT).block())
+            assertThatThrownBy(() -> eventBus().reDeliver(GROUP_A, EVENT).block())
                 .isInstanceOf(GroupRegistrationNotFound.class);
         }
 
@@ -384,25 +392,25 @@ public interface GroupContract {
         default void redeliverShouldOnlySendEventToDefinedGroup() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
             EventListener listener2 = EventBusTestFixture.newListener();
-            eventBus().register(listener, EventBusTestFixture.GROUP_A);
-            eventBus().register(listener2, EventBusTestFixture.GROUP_B);
+            eventBus().register(listener, GROUP_A);
+            eventBus().register(listener2, GROUP_B);
 
-            eventBus().reDeliver(EventBusTestFixture.GROUP_A, EventBusTestFixture.EVENT).block();
+            eventBus().reDeliver(GROUP_A, EVENT).block();
 
-            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
-            verify(listener2, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never()).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener2, after(FIVE_HUNDRED_MS.toMillis()).never()).event(any());
         }
 
         @Test
         default void groupListenersShouldNotReceiveNoopRedeliveredEvents() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
 
-            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            eventBus().register(listener, GROUP_A);
 
             Event noopEvent = new TestEvent(EVENT_ID, Username.of("noop"));
-            eventBus().reDeliver(EventBusTestFixture.GROUP_A, noopEvent).block();
+            eventBus().reDeliver(GROUP_A, noopEvent).block();
 
-            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never()).event(any());
+            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never()).event(any());
         }
     }
 
@@ -412,20 +420,20 @@ public interface GroupContract {
         default void groupsDefinedOnlyOnSomeNodesShouldBeNotifiedWhenDispatch() throws Exception {
             EventListener mailboxListener = EventBusTestFixture.newListener();
 
-            eventBus().register(mailboxListener, EventBusTestFixture.GROUP_A);
+            eventBus().register(mailboxListener, GROUP_A);
 
-            eventBus2().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+            eventBus2().dispatch(EVENT, NO_KEYS).block();
 
-            verify(mailboxListener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(mailboxListener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void groupsDefinedOnlyOnSomeNodesShouldNotBeNotifiedWhenRedeliver() {
             EventListener mailboxListener = EventBusTestFixture.newListener();
 
-            eventBus().register(mailboxListener, EventBusTestFixture.GROUP_A);
+            eventBus().register(mailboxListener, GROUP_A);
 
-            assertThatThrownBy(() -> eventBus2().reDeliver(EventBusTestFixture.GROUP_A, EventBusTestFixture.EVENT).block())
+            assertThatThrownBy(() -> eventBus2().reDeliver(GROUP_A, EVENT).block())
                 .isInstanceOf(GroupRegistrationNotFound.class);
         }
 
@@ -433,36 +441,36 @@ public interface GroupContract {
         default void groupListenersShouldBeExecutedOnceWhenRedeliverInADistributedEnvironment() throws Exception {
             EventListener mailboxListener = EventBusTestFixture.newListener();
 
-            eventBus().register(mailboxListener, EventBusTestFixture.GROUP_A);
-            eventBus2().register(mailboxListener, EventBusTestFixture.GROUP_A);
+            eventBus().register(mailboxListener, GROUP_A);
+            eventBus2().register(mailboxListener, GROUP_A);
 
-            eventBus2().reDeliver(EventBusTestFixture.GROUP_A, EventBusTestFixture.EVENT).block();
+            eventBus2().reDeliver(GROUP_A, EVENT).block();
 
-            verify(mailboxListener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(mailboxListener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void groupListenersShouldBeExecutedOnceInAControlledEnvironment() throws Exception {
             EventListener mailboxListener = EventBusTestFixture.newListener();
 
-            eventBus().register(mailboxListener, EventBusTestFixture.GROUP_A);
-            eventBus2().register(mailboxListener, EventBusTestFixture.GROUP_A);
+            eventBus().register(mailboxListener, GROUP_A);
+            eventBus2().register(mailboxListener, GROUP_A);
 
-            eventBus2().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+            eventBus2().dispatch(EVENT, NO_KEYS).block();
 
-            verify(mailboxListener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(mailboxListener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void unregisterShouldStopNotificationForDistantGroups() throws Exception {
             EventListener mailboxListener = EventBusTestFixture.newListener();
 
-            eventBus().register(mailboxListener, EventBusTestFixture.GROUP_A).unregister();
+            eventBus().register(mailboxListener, GROUP_A).unregister();
 
-            eventBus2().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+            eventBus2().dispatch(EVENT, NO_KEYS).block();
 
 
-            verify(mailboxListener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+            verify(mailboxListener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
@@ -470,11 +478,11 @@ public interface GroupContract {
         default void registerShouldNotDispatchPastEventsForGroupsInADistributedContext() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+            eventBus().dispatch(EVENT, NO_KEYS).block();
 
-            eventBus2().register(listener, EventBusTestFixture.GROUP_A);
+            eventBus2().register(listener, GROUP_A);
 
-            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
     }
diff --git a/event-bus/api/src/test/java/org/apache/james/events/KeyContract.java b/event-bus/api/src/test/java/org/apache/james/events/KeyContract.java
index 190b517..52e5a53 100644
--- a/event-bus/api/src/test/java/org/apache/james/events/KeyContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/KeyContract.java
@@ -19,7 +19,14 @@
 
 package org.apache.james.events;
 
+import static org.apache.james.events.EventBusTestFixture.EVENT;
 import static org.apache.james.events.EventBusTestFixture.EVENT_ID;
+import static org.apache.james.events.EventBusTestFixture.EVENT_UNSUPPORTED_BY_LISTENER;
+import static org.apache.james.events.EventBusTestFixture.FIVE_HUNDRED_MS;
+import static org.apache.james.events.EventBusTestFixture.KEY_1;
+import static org.apache.james.events.EventBusTestFixture.KEY_2;
+import static org.apache.james.events.EventBusTestFixture.NO_KEYS;
+import static org.apache.james.events.EventBusTestFixture.ONE_SECOND;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.junit.jupiter.api.Assertions.assertTimeout;
@@ -41,6 +48,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.IntStream;
 
 import org.apache.james.core.Username;
+import org.apache.james.events.EventListener.ExecutionMode;
 import org.junit.jupiter.api.Test;
 
 import com.google.common.collect.ImmutableSet;
@@ -66,10 +74,10 @@ public interface KeyContract extends EventBusContract {
                 Thread.sleep(Duration.ofMillis(20).toMillis());
                 finishedExecutions.incrementAndGet();
 
-            }, EventBusTestFixture.KEY_1)).block();
+            }, KEY_1)).block();
 
             IntStream.range(0, eventCount)
-                .forEach(i -> eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.KEY_1).block());
+                .forEach(i -> eventBus().dispatch(EVENT, KEY_1).block());
 
             getSpeedProfile().shortWaitCondition().atMost(org.awaitility.Duration.TEN_MINUTES)
                 .untilAsserted(() -> assertThat(finishedExecutions.get()).isEqualTo(eventCount));
@@ -84,17 +92,17 @@ public interface KeyContract extends EventBusContract {
                 Mono.from(eventBus().register(event -> {
                     threads.add(Thread.currentThread().getName());
                     countDownLatch.await();
-                }, EventBusTestFixture.KEY_1)).block();
+                }, KEY_1)).block();
                 Mono.from(eventBus().register(event -> {
                     threads.add(Thread.currentThread().getName());
                     countDownLatch.await();
-                }, EventBusTestFixture.KEY_1)).block();
+                }, KEY_1)).block();
                 Mono.from(eventBus().register(event -> {
                     threads.add(Thread.currentThread().getName());
                     countDownLatch.await();
-                }, EventBusTestFixture.KEY_1)).block();
+                }, KEY_1)).block();
 
-                eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.KEY_1).subscribeOn(Schedulers.elastic()).subscribe();
+                eventBus().dispatch(EVENT, KEY_1).subscribeOn(Schedulers.elastic()).subscribe();
 
 
                 getSpeedProfile().shortWaitCondition().atMost(org.awaitility.Duration.TEN_SECONDS)
@@ -110,12 +118,12 @@ public interface KeyContract extends EventBusContract {
         default void registeredListenersShouldNotReceiveNoopEvents() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
 
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
 
             Event noopEvent = new EventBusTestFixture.TestEvent(EVENT_ID, Username.of("noop"));
-            eventBus().dispatch(noopEvent, EventBusTestFixture.KEY_1).block();
+            eventBus().dispatch(noopEvent, KEY_1).block();
 
-            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
@@ -123,11 +131,11 @@ public interface KeyContract extends EventBusContract {
         default void registeredListenersShouldReceiveOnlyHandledEvents() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
 
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT_UNSUPPORTED_BY_LISTENER, EventBusTestFixture.KEY_1).block();
+            eventBus().dispatch(EVENT_UNSUPPORTED_BY_LISTENER, KEY_1).block();
 
-            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
@@ -136,50 +144,50 @@ public interface KeyContract extends EventBusContract {
             EventListener listener = EventBusTestFixture.newListener();
             doThrow(new RuntimeException()).when(listener).event(any());
 
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
 
-            assertThatCode(() -> eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block())
+            assertThatCode(() -> eventBus().dispatch(EVENT, NO_KEYS).block())
                 .doesNotThrowAnyException();
         }
 
         @Test
         default void dispatchShouldNotNotifyRegisteredListenerWhenEmptyKeySet() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+            eventBus().dispatch(EVENT, NO_KEYS).block();
 
-            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
         @Test
         default void dispatchShouldNotNotifyListenerRegisteredOnOtherKeys() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_2)).block();
+            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_2)).block();
 
-            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
         @Test
         default void dispatchShouldNotifyRegisteredListeners() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
 
-            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void dispatchShouldNotifyLocalRegisteredListenerWithoutDelay() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
 
             verify(listener, times(1)).event(any());
         }
@@ -188,13 +196,13 @@ public interface KeyContract extends EventBusContract {
         default void dispatchShouldNotifyOnlyRegisteredListener() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
             EventListener listener2 = EventBusTestFixture.newListener();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
-            Mono.from(eventBus().register(listener2, EventBusTestFixture.KEY_2)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
+            Mono.from(eventBus().register(listener2, KEY_2)).block();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
 
-            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
-            verify(listener2, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener2, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
@@ -202,35 +210,35 @@ public interface KeyContract extends EventBusContract {
         default void dispatchShouldNotifyAllListenersRegisteredOnAKey() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
             EventListener listener2 = EventBusTestFixture.newListener();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
-            Mono.from(eventBus().register(listener2, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
+            Mono.from(eventBus().register(listener2, KEY_1)).block();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
 
-            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
-            verify(listener2, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener2, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void registerShouldAllowDuplicatedRegistration() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
 
-            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void unregisterShouldRemoveDoubleRegisteredListener() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block().unregister();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block().unregister();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
 
-            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
@@ -238,43 +246,43 @@ public interface KeyContract extends EventBusContract {
         default void registerShouldNotDispatchPastEvents() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
 
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
 
-            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
         @Test
         default void callingAllUnregisterMethodShouldUnregisterTheListener() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
-            Registration registration = Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block().unregister();
+            Registration registration = Mono.from(eventBus().register(listener, KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block().unregister();
             registration.unregister();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
 
-            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
         @Test
         default void unregisterShouldHaveNotNotifyWhenCalledOnDifferentKeys() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_2)).block().unregister();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_2)).block().unregister();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
 
-            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void unregisterShouldBeIdempotentForKeyRegistrations() {
             EventListener listener = EventBusTestFixture.newListener();
 
-            Registration registration = Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Registration registration = Mono.from(eventBus().register(listener, KEY_1)).block();
             registration.unregister();
 
             assertThatCode(registration::unregister)
@@ -284,32 +292,32 @@ public interface KeyContract extends EventBusContract {
         @Test
         default void dispatchShouldAcceptSeveralKeys() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1, EventBusTestFixture.KEY_2)).block();
+            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1, KEY_2)).block();
 
-            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void dispatchShouldCallListenerOnceWhenSeveralKeysMatching() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_2)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_2)).block();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1, EventBusTestFixture.KEY_2)).block();
+            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1, KEY_2)).block();
 
-            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void dispatchShouldNotNotifyUnregisteredListener() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block().unregister();
+            Mono.from(eventBus().register(listener, KEY_1)).block().unregister();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
 
-            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
@@ -317,38 +325,38 @@ public interface KeyContract extends EventBusContract {
         @Test
         default void dispatchShouldNotifyAsynchronousListener() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            when(listener.getExecutionMode()).thenReturn(ExecutionMode.ASYNCHRONOUS);
+            Mono.from(eventBus().register(listener, KEY_1)).block();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.KEY_1).block();
+            eventBus().dispatch(EVENT, KEY_1).block();
 
-            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis())).event(EventBusTestFixture.EVENT);
+            verify(listener, after(FIVE_HUNDRED_MS.toMillis())).event(EVENT);
         }
 
         @Test
         default void dispatchShouldNotBlockAsynchronousListener() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
+            when(listener.getExecutionMode()).thenReturn(ExecutionMode.ASYNCHRONOUS);
             CountDownLatch latch = new CountDownLatch(1);
             doAnswer(invocation -> {
                 latch.await();
                 return null;
-            }).when(listener).event(EventBusTestFixture.EVENT);
+            }).when(listener).event(EVENT);
 
             assertTimeout(Duration.ofSeconds(2),
                 () -> {
-                    eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+                    eventBus().dispatch(EVENT, NO_KEYS).block();
                     latch.countDown();
                 });
         }
 
         @Test
         default void failingRegisteredListenersShouldNotAbortRegisteredDelivery() {
-            EventBusTestFixture.EventListenerCountingSuccessfulExecution listener = new EventBusTestFixture.EventMatcherThrowingListener(ImmutableSet.of(EventBusTestFixture.EVENT));
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution listener = new EventBusTestFixture.EventMatcherThrowingListener(ImmutableSet.of(EVENT));
+            Mono.from(eventBus().register(listener, KEY_1)).block();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.KEY_1).block();
-            eventBus().dispatch(EventBusTestFixture.EVENT_2, EventBusTestFixture.KEY_1).block();
+            eventBus().dispatch(EVENT, KEY_1).block();
+            eventBus().dispatch(EventBusTestFixture.EVENT_2, KEY_1).block();
 
             getSpeedProfile().shortWaitCondition()
                 .untilAsserted(() -> assertThat(listener.numberOfEventCalls()).isEqualTo(1));
@@ -359,15 +367,15 @@ public interface KeyContract extends EventBusContract {
             EventListener listener = EventBusTestFixture.newListener();
 
             EventListener failingListener = mock(EventListener.class);
-            when(failingListener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
+            when(failingListener.getExecutionMode()).thenReturn(ExecutionMode.SYNCHRONOUS);
             doThrow(new RuntimeException()).when(failingListener).event(any());
 
-            Mono.from(eventBus().register(failingListener, EventBusTestFixture.KEY_1)).block();
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(failingListener, KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
 
-            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+            eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
 
-            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
     }
 
@@ -377,22 +385,22 @@ public interface KeyContract extends EventBusContract {
         default void crossEventBusRegistrationShouldBeAllowed() throws Exception {
             EventListener mailboxListener = EventBusTestFixture.newListener();
 
-            Mono.from(eventBus().register(mailboxListener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(mailboxListener, KEY_1)).block();
 
-            eventBus2().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.KEY_1).block();
+            eventBus2().dispatch(EVENT, KEY_1).block();
 
-            verify(mailboxListener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(mailboxListener, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void unregisteredDistantListenersShouldNotBeNotified() throws Exception {
             EventListener eventListener = EventBusTestFixture.newListener();
 
-            Mono.from(eventBus().register(eventListener, EventBusTestFixture.KEY_1)).block().unregister();
+            Mono.from(eventBus().register(eventListener, KEY_1)).block().unregister();
 
-            eventBus2().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+            eventBus2().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
 
-            verify(eventListener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+            verify(eventListener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
@@ -401,24 +409,24 @@ public interface KeyContract extends EventBusContract {
             EventListener mailboxListener1 = EventBusTestFixture.newListener();
             EventListener mailboxListener2 = EventBusTestFixture.newListener();
 
-            Mono.from(eventBus().register(mailboxListener1, EventBusTestFixture.KEY_1)).block();
-            Mono.from(eventBus2().register(mailboxListener2, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(mailboxListener1, KEY_1)).block();
+            Mono.from(eventBus2().register(mailboxListener2, KEY_1)).block();
 
-            eventBus2().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.KEY_1).block();
+            eventBus2().dispatch(EVENT, KEY_1).block();
 
-            verify(mailboxListener1, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
-            verify(mailboxListener2, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(mailboxListener1, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(mailboxListener2, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
         @Test
         default void registerShouldNotDispatchPastEventsInDistributedContext() throws Exception {
             EventListener listener = EventBusTestFixture.newListener();
 
-            eventBus2().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+            eventBus2().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
 
-            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, KEY_1)).block();
 
-            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+            verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
@@ -427,13 +435,13 @@ public interface KeyContract extends EventBusContract {
             EventListener mailboxListener1 = EventBusTestFixture.newListener();
             EventListener mailboxListener2 = EventBusTestFixture.newListener();
 
-            Mono.from(eventBus().register(mailboxListener1, EventBusTestFixture.KEY_1)).block();
-            Mono.from(eventBus2().register(mailboxListener2, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(mailboxListener1, KEY_1)).block();
+            Mono.from(eventBus2().register(mailboxListener2, KEY_1)).block();
 
-            eventBus2().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.KEY_1).block();
+            eventBus2().dispatch(EVENT, KEY_1).block();
 
             verify(mailboxListener2, times(1)).event(any());
-            verify(mailboxListener1, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(mailboxListener1, timeout(ONE_SECOND.toMillis()).times(1)).event(any());
         }
 
     }
diff --git a/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java b/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java
index df1f339..096cce6 100644
--- a/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java
+++ b/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java
@@ -24,11 +24,14 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.delete;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+import static org.apache.james.events.tables.CassandraEventDeadLettersTable.EVENT;
+import static org.apache.james.events.tables.CassandraEventDeadLettersTable.GROUP;
+import static org.apache.james.events.tables.CassandraEventDeadLettersTable.INSERTION_ID;
+import static org.apache.james.events.tables.CassandraEventDeadLettersTable.TABLE_NAME;
 
 import javax.inject.Inject;
 
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
-import org.apache.james.events.tables.CassandraEventDeadLettersTable;
 
 import com.datastax.driver.core.PreparedStatement;
 import com.datastax.driver.core.Session;
@@ -57,62 +60,62 @@ public class CassandraEventDeadLettersDAO {
     }
 
     private PreparedStatement prepareInsertStatement(Session session) {
-        return session.prepare(insertInto(CassandraEventDeadLettersTable.TABLE_NAME)
-            .value(CassandraEventDeadLettersTable.GROUP, bindMarker(CassandraEventDeadLettersTable.GROUP))
-            .value(CassandraEventDeadLettersTable.INSERTION_ID, bindMarker(CassandraEventDeadLettersTable.INSERTION_ID))
-            .value(CassandraEventDeadLettersTable.EVENT, bindMarker(CassandraEventDeadLettersTable.EVENT)));
+        return session.prepare(insertInto(TABLE_NAME)
+            .value(GROUP, bindMarker(GROUP))
+            .value(INSERTION_ID, bindMarker(INSERTION_ID))
+            .value(EVENT, bindMarker(EVENT)));
     }
 
     private PreparedStatement prepareDeleteStatement(Session session) {
         return session.prepare(delete()
-            .from(CassandraEventDeadLettersTable.TABLE_NAME)
-            .where(eq(CassandraEventDeadLettersTable.GROUP, bindMarker(CassandraEventDeadLettersTable.GROUP)))
-            .and(eq(CassandraEventDeadLettersTable.INSERTION_ID, bindMarker(CassandraEventDeadLettersTable.INSERTION_ID))));
+            .from(TABLE_NAME)
+            .where(eq(GROUP, bindMarker(GROUP)))
+            .and(eq(INSERTION_ID, bindMarker(INSERTION_ID))));
     }
 
     private PreparedStatement prepareSelectEventStatement(Session session) {
-        return session.prepare(select(CassandraEventDeadLettersTable.EVENT)
-            .from(CassandraEventDeadLettersTable.TABLE_NAME)
-            .where(eq(CassandraEventDeadLettersTable.GROUP, bindMarker(CassandraEventDeadLettersTable.GROUP)))
-            .and(eq(CassandraEventDeadLettersTable.INSERTION_ID, bindMarker(CassandraEventDeadLettersTable.INSERTION_ID))));
+        return session.prepare(select(EVENT)
+            .from(TABLE_NAME)
+            .where(eq(GROUP, bindMarker(GROUP)))
+            .and(eq(INSERTION_ID, bindMarker(INSERTION_ID))));
     }
 
     private PreparedStatement prepareSelectInsertionIdsWithGroupStatement(Session session) {
-        return session.prepare(select(CassandraEventDeadLettersTable.INSERTION_ID)
-            .from(CassandraEventDeadLettersTable.TABLE_NAME)
-            .where(eq(CassandraEventDeadLettersTable.GROUP, bindMarker(CassandraEventDeadLettersTable.GROUP))));
+        return session.prepare(select(INSERTION_ID)
+            .from(TABLE_NAME)
+            .where(eq(GROUP, bindMarker(GROUP))));
     }
 
     private PreparedStatement prepareContainEventStatement(Session session) {
-        return session.prepare(select(CassandraEventDeadLettersTable.EVENT)
-            .from(CassandraEventDeadLettersTable.TABLE_NAME)
+        return session.prepare(select(EVENT)
+            .from(TABLE_NAME)
             .limit(1));
     }
 
     Mono<Void> store(Group group, Event failedEvent, EventDeadLetters.InsertionId insertionId) {
         return executor.executeVoid(insertStatement.bind()
-                .setString(CassandraEventDeadLettersTable.GROUP, group.asString())
-                .setUUID(CassandraEventDeadLettersTable.INSERTION_ID, insertionId.getId())
-                .setString(CassandraEventDeadLettersTable.EVENT, eventSerializer.toJson(failedEvent)));
+                .setString(GROUP, group.asString())
+                .setUUID(INSERTION_ID, insertionId.getId())
+                .setString(EVENT, eventSerializer.toJson(failedEvent)));
     }
 
     Mono<Void> removeEvent(Group group, EventDeadLetters.InsertionId failedInsertionId) {
         return executor.executeVoid(deleteStatement.bind()
-                .setString(CassandraEventDeadLettersTable.GROUP, group.asString())
-                .setUUID(CassandraEventDeadLettersTable.INSERTION_ID, failedInsertionId.getId()));
+                .setString(GROUP, group.asString())
+                .setUUID(INSERTION_ID, failedInsertionId.getId()));
     }
 
     Mono<Event> retrieveFailedEvent(Group group, EventDeadLetters.InsertionId insertionId) {
         return executor.executeSingleRow(selectEventStatement.bind()
-                .setString(CassandraEventDeadLettersTable.GROUP, group.asString())
-                .setUUID(CassandraEventDeadLettersTable.INSERTION_ID, insertionId.getId()))
-            .map(row -> deserializeEvent(row.getString(CassandraEventDeadLettersTable.EVENT)));
+                .setString(GROUP, group.asString())
+                .setUUID(INSERTION_ID, insertionId.getId()))
+            .map(row -> deserializeEvent(row.getString(EVENT)));
     }
 
     Flux<EventDeadLetters.InsertionId> retrieveInsertionIdsWithGroup(Group group) {
         return executor.executeRows(selectEventIdsWithGroupStatement.bind()
-                .setString(CassandraEventDeadLettersTable.GROUP, group.asString()))
-            .map(row -> EventDeadLetters.InsertionId.of(row.getUUID(CassandraEventDeadLettersTable.INSERTION_ID)));
+                .setString(GROUP, group.asString()))
+            .map(row -> EventDeadLetters.InsertionId.of(row.getUUID(INSERTION_ID)));
     }
 
     Mono<Boolean> containEvents() {
diff --git a/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersGroupDAO.java b/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersGroupDAO.java
index 2fefd3c..bd0c27e 100644
--- a/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersGroupDAO.java
+++ b/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersGroupDAO.java
@@ -20,11 +20,12 @@
 package org.apache.james.events;
 
 import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
+import static org.apache.james.events.tables.CassandraEventDeadLettersGroupTable.GROUP;
+import static org.apache.james.events.tables.CassandraEventDeadLettersGroupTable.TABLE_NAME;
 
 import javax.inject.Inject;
 
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
-import org.apache.james.events.tables.CassandraEventDeadLettersGroupTable;
 
 import com.datastax.driver.core.PreparedStatement;
 import com.datastax.driver.core.Session;
@@ -47,22 +48,22 @@ public class CassandraEventDeadLettersGroupDAO {
     }
 
     private PreparedStatement prepareInsertStatement(Session session) {
-        return session.prepare(QueryBuilder.insertInto(CassandraEventDeadLettersGroupTable.TABLE_NAME)
-            .value(CassandraEventDeadLettersGroupTable.GROUP, bindMarker(CassandraEventDeadLettersGroupTable.GROUP)));
+        return session.prepare(QueryBuilder.insertInto(TABLE_NAME)
+            .value(GROUP, bindMarker(GROUP)));
     }
 
     private PreparedStatement prepareSelectStatement(Session session) {
-        return session.prepare(QueryBuilder.select(CassandraEventDeadLettersGroupTable.GROUP)
-            .from(CassandraEventDeadLettersGroupTable.TABLE_NAME));
+        return session.prepare(QueryBuilder.select(GROUP)
+            .from(TABLE_NAME));
     }
 
     Mono<Void> storeGroup(Group group) {
         return executor.executeVoid(insertStatement.bind()
-                .setString(CassandraEventDeadLettersGroupTable.GROUP, group.asString()));
+                .setString(GROUP, group.asString()));
     }
 
     Flux<Group> retrieveAllGroups() {
         return executor.executeRows(selectAllStatement.bind())
-            .map(Throwing.function(row -> Group.deserialize(row.getString(CassandraEventDeadLettersGroupTable.GROUP))));
+            .map(Throwing.function(row -> Group.deserialize(row.getString(GROUP))));
     }
 }
diff --git a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java
index 114022d..ffa7cd3 100644
--- a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java
+++ b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java
@@ -19,6 +19,13 @@
 
 package org.apache.james.events;
 
+import static org.apache.james.events.EventDeadLettersContract.EVENT_1;
+import static org.apache.james.events.EventDeadLettersContract.EVENT_2;
+import static org.apache.james.events.EventDeadLettersContract.GROUP_A;
+import static org.apache.james.events.EventDeadLettersContract.GROUP_B;
+import static org.apache.james.events.EventDeadLettersContract.INSERTION_ID_1;
+import static org.apache.james.events.EventDeadLettersContract.INSERTION_ID_2;
+import static org.apache.james.events.EventDeadLettersContract.INSERTION_ID_3;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
@@ -42,12 +49,12 @@ class CassandraEventDeadLettersDAOTest {
 
     @Test
     void removeEventShouldSucceededWhenRemoveStoredEvent() {
-        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_A, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_1).block();
+        cassandraEventDeadLettersDAO.store(GROUP_A, EVENT_1, INSERTION_ID_1).block();
 
-        cassandraEventDeadLettersDAO.removeEvent(EventDeadLettersContract.GROUP_A, EventDeadLettersContract.INSERTION_ID_1).block();
+        cassandraEventDeadLettersDAO.removeEvent(GROUP_A, INSERTION_ID_1).block();
 
         assertThat(cassandraEventDeadLettersDAO
-                .retrieveInsertionIdsWithGroup(EventDeadLettersContract.GROUP_A)
+                .retrieveInsertionIdsWithGroup(GROUP_A)
                 .collectList().block())
             .isEmpty();
     }
@@ -55,45 +62,45 @@ class CassandraEventDeadLettersDAOTest {
     @Test
     void retrieveFailedEventShouldReturnEmptyWhenDefault() {
         assertThat(cassandraEventDeadLettersDAO
-                .retrieveFailedEvent(EventDeadLettersContract.GROUP_A, EventDeadLettersContract.INSERTION_ID_1)
+                .retrieveFailedEvent(GROUP_A, INSERTION_ID_1)
                 .blockOptional().isPresent())
             .isFalse();
     }
 
     @Test
     void retrieveFailedEventShouldReturnStoredEvent() {
-        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_A, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_1).block();
-        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_2, EventDeadLettersContract.INSERTION_ID_2).block();
+        cassandraEventDeadLettersDAO.store(GROUP_A, EVENT_1, INSERTION_ID_1).block();
+        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_2, INSERTION_ID_2).block();
 
         assertThat(cassandraEventDeadLettersDAO
-                .retrieveFailedEvent(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.INSERTION_ID_2)
+                .retrieveFailedEvent(GROUP_B, INSERTION_ID_2)
                 .blockOptional().get())
-            .isEqualTo(EventDeadLettersContract.EVENT_2);
+            .isEqualTo(EVENT_2);
     }
 
     @Test
     void retrieveInsertionIdsWithGroupShouldReturnEmptyWhenDefault() {
         assertThat(cassandraEventDeadLettersDAO
-                .retrieveInsertionIdsWithGroup(EventDeadLettersContract.GROUP_A)
+                .retrieveInsertionIdsWithGroup(GROUP_A)
                 .collectList().block())
             .isEmpty();
     }
 
     @Test
     void retrieveInsertionIdsWithGroupShouldReturnStoredInsertionId() {
-        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_1).block();
-        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_2, EventDeadLettersContract.INSERTION_ID_2).block();
-        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_3, EventDeadLettersContract.INSERTION_ID_3).block();
+        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_1, INSERTION_ID_1).block();
+        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_2, INSERTION_ID_2).block();
+        cassandraEventDeadLettersDAO.store(GROUP_B, EventDeadLettersContract.EVENT_3, INSERTION_ID_3).block();
 
         assertThat(cassandraEventDeadLettersDAO
-                .retrieveInsertionIdsWithGroup(EventDeadLettersContract.GROUP_B)
+                .retrieveInsertionIdsWithGroup(GROUP_B)
                 .collectList().block())
-            .containsOnly(EventDeadLettersContract.INSERTION_ID_1, EventDeadLettersContract.INSERTION_ID_2, EventDeadLettersContract.INSERTION_ID_3);
+            .containsOnly(INSERTION_ID_1, INSERTION_ID_2, INSERTION_ID_3);
     }
 
     @Test
     void shouldReturnTrueWhenEventStored() {
-        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_1).block();
+        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_1, INSERTION_ID_1).block();
         assertThat(cassandraEventDeadLettersDAO.containEvents().block()).isTrue();
     }
 
@@ -104,28 +111,28 @@ class CassandraEventDeadLettersDAOTest {
 
     @Test
     void shouldReturnTrueWhenEventsStoredAndRemovedSome() {
-        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_1).block();
-        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_2).block();
-        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_3).block();
+        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_1, INSERTION_ID_1).block();
+        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_1, INSERTION_ID_2).block();
+        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_1, INSERTION_ID_3).block();
 
         assertThat(cassandraEventDeadLettersDAO.containEvents().block()).isTrue();
 
-        cassandraEventDeadLettersDAO.removeEvent(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.INSERTION_ID_3).block();
+        cassandraEventDeadLettersDAO.removeEvent(GROUP_B, INSERTION_ID_3).block();
 
         assertThat(cassandraEventDeadLettersDAO.containEvents().block()).isTrue();
     }
 
     @Test
     void shouldReturnFalseWhenRemovedAllEventsStored() {
-        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_1).block();
-        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_2).block();
-        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_3).block();
+        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_1, INSERTION_ID_1).block();
+        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_1, INSERTION_ID_2).block();
+        cassandraEventDeadLettersDAO.store(GROUP_B, EVENT_1, INSERTION_ID_3).block();
 
         assertThat(cassandraEventDeadLettersDAO.containEvents().block()).isTrue();
 
-        cassandraEventDeadLettersDAO.removeEvent(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.INSERTION_ID_3).block();
-        cassandraEventDeadLettersDAO.removeEvent(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.INSERTION_ID_2).block();
-        cassandraEventDeadLettersDAO.removeEvent(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.INSERTION_ID_1).block();
+        cassandraEventDeadLettersDAO.removeEvent(GROUP_B, INSERTION_ID_3).block();
+        cassandraEventDeadLettersDAO.removeEvent(GROUP_B, INSERTION_ID_2).block();
+        cassandraEventDeadLettersDAO.removeEvent(GROUP_B, INSERTION_ID_1).block();
 
         assertThat(cassandraEventDeadLettersDAO.containEvents().block()).isFalse();
     }
diff --git a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersGroupDAOTest.java b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersGroupDAOTest.java
index f5eef74..891070e 100644
--- a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersGroupDAOTest.java
+++ b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersGroupDAOTest.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.events;
 
+import static org.apache.james.events.EventDeadLettersContract.GROUP_A;
+import static org.apache.james.events.EventDeadLettersContract.GROUP_B;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
@@ -48,11 +50,11 @@ public class CassandraEventDeadLettersGroupDAOTest {
 
     @Test
     void retrieveAllGroupsShouldReturnStoredGroups() {
-        GROUP_DAO.storeGroup(EventDeadLettersContract.GROUP_A).block();
-        GROUP_DAO.storeGroup(EventDeadLettersContract.GROUP_B).block();
+        GROUP_DAO.storeGroup(GROUP_A).block();
+        GROUP_DAO.storeGroup(GROUP_B).block();
 
         assertThat(GROUP_DAO.retrieveAllGroups()
                 .collectList().block())
-            .containsOnly(EventDeadLettersContract.GROUP_A, EventDeadLettersContract.GROUP_B);
+            .containsOnly(GROUP_A, GROUP_B);
     }
 }
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java b/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
index 10d922a..5c6fd2e 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
@@ -24,6 +24,7 @@ import static org.apache.james.backends.rabbitmq.Constants.DIRECT_EXCHANGE;
 import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
 import static org.apache.james.backends.rabbitmq.Constants.EMPTY_ROUTING_KEY;
 import static org.apache.james.events.GroupRegistration.RETRY_COUNT;
+import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT;
 
 import java.nio.charset.StandardCharsets;
 
@@ -51,7 +52,7 @@ class GroupConsumerRetry {
             return new RetryExchangeName(group.asString());
         }
 
-        static final String MAILBOX_EVENT_RETRY_EXCHANGE_PREFIX = RabbitMQEventBus.MAILBOX_EVENT + "-retryExchange-";
+        static final String MAILBOX_EVENT_RETRY_EXCHANGE_PREFIX = MAILBOX_EVENT + "-retryExchange-";
 
         private final String name;
 
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java
index ad2b7ad..07739ac 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java
@@ -25,6 +25,7 @@ import static org.apache.james.backends.rabbitmq.Constants.EMPTY_ROUTING_KEY;
 import static org.apache.james.backends.rabbitmq.Constants.EXCLUSIVE;
 import static org.apache.james.backends.rabbitmq.Constants.REQUEUE;
 import static org.apache.james.backends.rabbitmq.Constants.deadLetterQueue;
+import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT;
 
 import java.nio.charset.StandardCharsets;
 import java.util.Objects;
@@ -56,7 +57,7 @@ class GroupRegistration implements Registration {
             return new WorkQueueName(group);
         }
 
-        static final String MAILBOX_EVENT_WORK_QUEUE_PREFIX = RabbitMQEventBus.MAILBOX_EVENT + "-workQueue-";
+        static final String MAILBOX_EVENT_WORK_QUEUE_PREFIX = MAILBOX_EVENT + "-workQueue-";
 
         private final Group group;
 
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/KeyReconnectionHandler.java b/event-bus/distributed/src/main/java/org/apache/james/events/KeyReconnectionHandler.java
index 24b5dd1..8b15173 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/KeyReconnectionHandler.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/KeyReconnectionHandler.java
@@ -22,6 +22,8 @@ package org.apache.james.events;
 import static org.apache.james.backends.rabbitmq.Constants.AUTO_DELETE;
 import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
 import static org.apache.james.backends.rabbitmq.Constants.EXCLUSIVE;
+import static org.apache.james.events.KeyRegistrationHandler.EVENTBUS_QUEUE_NAME_PREFIX;
+import static org.apache.james.events.KeyRegistrationHandler.QUEUE_ARGUMENTS;
 
 import javax.inject.Inject;
 
@@ -49,7 +51,7 @@ public class KeyReconnectionHandler implements SimpleConnectionPool.Reconnection
     public Publisher<Void> handleReconnection(Connection connection) {
         return Mono.fromRunnable(() -> {
             try (Channel channel = connection.createChannel()) {
-                channel.queueDeclare(KeyRegistrationHandler.EVENTBUS_QUEUE_NAME_PREFIX + eventBusId.asString(), DURABLE, !EXCLUSIVE, AUTO_DELETE, KeyRegistrationHandler.QUEUE_ARGUMENTS);
+                channel.queueDeclare(EVENTBUS_QUEUE_NAME_PREFIX + eventBusId.asString(), DURABLE, !EXCLUSIVE, AUTO_DELETE, QUEUE_ARGUMENTS);
             } catch (Exception e) {
                 LOGGER.error("Error recovering connection", e);
             }
diff --git a/event-bus/in-vm/src/test/java/org/apache/james/events/delivery/InVmEventDeliveryTest.java b/event-bus/in-vm/src/test/java/org/apache/james/events/delivery/InVmEventDeliveryTest.java
index a0536a0..ab2a92b 100644
--- a/event-bus/in-vm/src/test/java/org/apache/james/events/delivery/InVmEventDeliveryTest.java
+++ b/event-bus/in-vm/src/test/java/org/apache/james/events/delivery/InVmEventDeliveryTest.java
@@ -19,19 +19,23 @@
 
 package org.apache.james.events.delivery;
 
+import static org.apache.james.events.EventBusTestFixture.EVENT;
+import static org.apache.james.events.EventBusTestFixture.GROUP_A;
+import static org.apache.james.events.delivery.EventDelivery.PermanentFailureHandler.NO_HANDLER;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
 import java.time.Duration;
 
 import org.apache.james.events.EventBusTestFixture;
-import org.apache.james.events.EventListener;
+import org.apache.james.events.EventListener.ExecutionMode;
 import org.apache.james.events.MemoryEventDeadLetters;
 import org.apache.james.events.RetryBackoffConfiguration;
+import org.apache.james.events.delivery.EventDelivery.DeliveryOption;
+import org.apache.james.events.delivery.EventDelivery.Retryer.BackoffRetryer;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
 import org.assertj.core.api.SoftAssertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -58,8 +62,8 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldDeliverEvent() {
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
-            inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT, EventDelivery.DeliveryOption.none())
+            when(listener.getExecutionMode()).thenReturn(ExecutionMode.SYNCHRONOUS);
+            inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
                 .block();
 
             assertThat(listener.numberOfEventCalls())
@@ -68,19 +72,19 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldReturnSuccessSynchronousMono() {
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
-            assertThatCode(() -> inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT, EventDelivery.DeliveryOption.none())
+            when(listener.getExecutionMode()).thenReturn(ExecutionMode.SYNCHRONOUS);
+            assertThatCode(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
                     .block())
                 .doesNotThrowAnyException();
         }
 
         @Test
         void deliverShouldNotDeliverWhenListenerGetException() {
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
+            when(listener.getExecutionMode()).thenReturn(ExecutionMode.SYNCHRONOUS);
             doThrow(new RuntimeException())
-                .when(listener).event(EventBusTestFixture.EVENT);
+                .when(listener).event(EVENT);
 
-            assertThatThrownBy(() -> inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT, EventDelivery.DeliveryOption.none())
+            assertThatThrownBy(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
                 .block())
             .isInstanceOf(RuntimeException.class);
 
@@ -90,11 +94,11 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldReturnAnErrorMonoWhenListenerGetException() {
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
+            when(listener.getExecutionMode()).thenReturn(ExecutionMode.SYNCHRONOUS);
             doThrow(new RuntimeException())
-                .when(listener).event(EventBusTestFixture.EVENT);
+                .when(listener).event(EVENT);
 
-            assertThatThrownBy(() -> inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT, EventDelivery.DeliveryOption.none())
+            assertThatThrownBy(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
                 .block())
             .isInstanceOf(RuntimeException.class);
         }
@@ -105,8 +109,8 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldDeliverEvent() {
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
-            inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT, EventDelivery.DeliveryOption.none())
+            when(listener.getExecutionMode()).thenReturn(ExecutionMode.ASYNCHRONOUS);
+            inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
                 .block();
 
             assertThat(listener.numberOfEventCalls())
@@ -115,30 +119,30 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldReturnSuccessSynchronousMono() {
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
-            assertThatCode(() -> inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT, EventDelivery.DeliveryOption.none())
+            when(listener.getExecutionMode()).thenReturn(ExecutionMode.ASYNCHRONOUS);
+            assertThatCode(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
                     .block())
                 .doesNotThrowAnyException();
         }
 
         @Test
         void deliverShouldNotFailWhenListenerGetException() {
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
+            when(listener.getExecutionMode()).thenReturn(ExecutionMode.ASYNCHRONOUS);
             doThrow(new RuntimeException())
-                .when(listener).event(EventBusTestFixture.EVENT);
+                .when(listener).event(EVENT);
 
-            assertThatCode(() -> inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT, EventDelivery.DeliveryOption.none())
+            assertThatCode(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
                 .block())
             .doesNotThrowAnyException();
         }
 
         @Test
         void deliverShouldReturnAnSuccessSyncMonoWhenListenerGetException() {
-            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
+            when(listener.getExecutionMode()).thenReturn(ExecutionMode.ASYNCHRONOUS);
             doThrow(new RuntimeException())
-                .when(listener).event(EventBusTestFixture.EVENT);
+                .when(listener).event(EVENT);
 
-            assertThatCode(() -> inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT, EventDelivery.DeliveryOption.none())
+            assertThatCode(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
                 .block())
             .doesNotThrowAnyException();
         }
@@ -154,12 +158,12 @@ class InVmEventDeliveryTest {
                 .doThrow(new RuntimeException())
                 .doThrow(new RuntimeException())
                 .doCallRealMethod()
-                .when(listener).event(EventBusTestFixture.EVENT);
+                .when(listener).event(EVENT);
 
-            inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT,
-                EventDelivery.DeliveryOption.of(
-                    EventDelivery.Retryer.BackoffRetryer.of(RetryBackoffConfiguration.DEFAULT, listener),
-                    EventDelivery.PermanentFailureHandler.NO_HANDLER))
+            inVmEventDelivery.deliver(listener, EVENT,
+                DeliveryOption.of(
+                    BackoffRetryer.of(RetryBackoffConfiguration.DEFAULT, listener),
+                    NO_HANDLER))
                 .block();
 
             assertThat(listener.numberOfEventCalls())
@@ -170,18 +174,18 @@ class InVmEventDeliveryTest {
         void failureHandlerShouldWorkWhenDeliverWithFailureHandler() {
             EventBusTestFixture.EventListenerCountingSuccessfulExecution listener = newListener();
             doThrow(new RuntimeException())
-                .when(listener).event(EventBusTestFixture.EVENT);
+                .when(listener).event(EVENT);
 
             MemoryEventDeadLetters deadLetter = new MemoryEventDeadLetters();
 
-            inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT,
-                EventDelivery.DeliveryOption.of(
+            inVmEventDelivery.deliver(listener, EVENT,
+                DeliveryOption.of(
                     EventDelivery.Retryer.NO_RETRYER,
-                    EventDelivery.PermanentFailureHandler.StoreToDeadLetters.of(EventBusTestFixture.GROUP_A, deadLetter)))
+                    EventDelivery.PermanentFailureHandler.StoreToDeadLetters.of(GROUP_A, deadLetter)))
                 .block();
 
             assertThat(deadLetter.groupsWithFailedEvents().toStream())
-                .containsOnly(EventBusTestFixture.GROUP_A);
+                .containsOnly(GROUP_A);
         }
 
         @Test
@@ -190,14 +194,14 @@ class InVmEventDeliveryTest {
             doThrow(new RuntimeException())
                 .doThrow(new RuntimeException())
                 .doCallRealMethod()
-                .when(listener).event(EventBusTestFixture.EVENT);
+                .when(listener).event(EVENT);
 
             MemoryEventDeadLetters deadLetter = new MemoryEventDeadLetters();
 
-            inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT,
-                EventDelivery.DeliveryOption.of(
-                    EventDelivery.Retryer.BackoffRetryer.of(RetryBackoffConfiguration.DEFAULT, listener),
-                    EventDelivery.PermanentFailureHandler.StoreToDeadLetters.of(EventBusTestFixture.GROUP_A, deadLetter)))
+            inVmEventDelivery.deliver(listener, EVENT,
+                DeliveryOption.of(
+                    BackoffRetryer.of(RetryBackoffConfiguration.DEFAULT, listener),
+                    EventDelivery.PermanentFailureHandler.StoreToDeadLetters.of(GROUP_A, deadLetter)))
                 .block();
 
             SoftAssertions.assertSoftly(softy -> {
@@ -223,25 +227,25 @@ class InVmEventDeliveryTest {
                 .doThrow(new RuntimeException())
                 .doThrow(new RuntimeException())
                 .doCallRealMethod()
-                .when(listener).event(EventBusTestFixture.EVENT);
+                .when(listener).event(EVENT);
 
             MemoryEventDeadLetters deadLetter = new MemoryEventDeadLetters();
 
-            inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT,
-                EventDelivery.DeliveryOption.of(
-                    EventDelivery.Retryer.BackoffRetryer.of(RetryBackoffConfiguration.builder()
+            inVmEventDelivery.deliver(listener, EVENT,
+                DeliveryOption.of(
+                    BackoffRetryer.of(RetryBackoffConfiguration.builder()
                             .maxRetries(8)
                             .firstBackoff(Duration.ofMillis(1))
                             .jitterFactor(0.2)
                             .build(), listener),
-                    EventDelivery.PermanentFailureHandler.StoreToDeadLetters.of(EventBusTestFixture.GROUP_A, deadLetter)))
+                    EventDelivery.PermanentFailureHandler.StoreToDeadLetters.of(GROUP_A, deadLetter)))
                 .block();
 
             SoftAssertions.assertSoftly(softy -> {
                 softy.assertThat(listener.numberOfEventCalls())
                     .isEqualTo(0);
                 assertThat(deadLetter.groupsWithFailedEvents().toStream())
-                    .containsOnly(EventBusTestFixture.GROUP_A);
+                    .containsOnly(GROUP_A);
             });
         }
     }


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


[james-project] 14/18: JAMES-3498 Restore JavaEvent convenience import

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 e5d675fae6705d92dd0c15ad7f64e8a64ddfce04
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 25 19:09:52 2021 +0700

    JAMES-3498 Restore JavaEvent convenience import
---
 .../james/event/json/MailboxEventSerializer.scala  | 35 +++++++++++-----------
 1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala b/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala
index cee6dc3..0b07edc 100644
--- a/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala
+++ b/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala
@@ -28,9 +28,8 @@ import org.apache.james.core.Username
 import org.apache.james.core.quota.{QuotaCountLimit, QuotaCountUsage, QuotaSizeLimit, QuotaSizeUsage}
 import org.apache.james.event.json.DTOs.SystemFlag.SystemFlag
 import org.apache.james.event.json.DTOs._
-import org.apache.james.events
 import org.apache.james.events.Event.EventId
-import org.apache.james.events.EventSerializer
+import org.apache.james.events.{EventSerializer, Event => JavaEvent}
 import org.apache.james.mailbox.MailboxSession.SessionId
 import org.apache.james.mailbox.events.MailboxEvents.{Added => JavaAdded, Expunged => JavaExpunged, FlagsUpdated => JavaFlagsUpdated, MailboxACLUpdated => JavaMailboxACLUpdated, MailboxAdded => JavaMailboxAdded, MailboxDeletion => JavaMailboxDeletion, MailboxRenamed => JavaMailboxRenamed, QuotaUsageUpdatedEvent => JavaQuotaUsageUpdatedEvent}
 import org.apache.james.mailbox.events.{MessageMoveEvent => JavaMessageMoveEvent}
@@ -42,36 +41,36 @@ import play.api.libs.json._
 import scala.jdk.CollectionConverters._
 
 private sealed trait Event {
-  def toJava: events.Event
+  def toJava: JavaEvent
 }
 
 private object DTO {
   case class MailboxACLUpdated(eventId: EventId, sessionId: SessionId, user: Username, mailboxPath: MailboxPath, aclDiff: ACLDiff, mailboxId: MailboxId) extends Event {
-    override def toJava: events.Event = new JavaMailboxACLUpdated(sessionId, user, mailboxPath.toJava, aclDiff.toJava, mailboxId, eventId)
+    override def toJava: JavaEvent = new JavaMailboxACLUpdated(sessionId, user, mailboxPath.toJava, aclDiff.toJava, mailboxId, eventId)
   }
 
   case class MailboxAdded(eventId: EventId, mailboxPath: MailboxPath, mailboxId: MailboxId, user: Username, sessionId: SessionId) extends Event {
-    override def toJava: events.Event = new JavaMailboxAdded(sessionId, user, mailboxPath.toJava, mailboxId, eventId)
+    override def toJava: JavaEvent = new JavaMailboxAdded(sessionId, user, mailboxPath.toJava, mailboxId, eventId)
   }
 
   case class MailboxDeletion(eventId: EventId, sessionId: SessionId, user: Username, path: MailboxPath, mailboxACL: Option[MailboxACL], quotaRoot: QuotaRoot,
                              deletedMessageCount: QuotaCountUsage, totalDeletedSize: QuotaSizeUsage, mailboxId: MailboxId) extends Event {
-    override def toJava: events.Event = new JavaMailboxDeletion(sessionId, user, path.toJava, mailboxACL.map(mailboxACL => mailboxACL.toJava).getOrElse(new JavaMailboxACL()), quotaRoot, deletedMessageCount,
+    override def toJava: JavaEvent = new JavaMailboxDeletion(sessionId, user, path.toJava, mailboxACL.map(mailboxACL => mailboxACL.toJava).getOrElse(new JavaMailboxACL()), quotaRoot, deletedMessageCount,
       totalDeletedSize, mailboxId, eventId)
   }
 
   case class MailboxRenamed(eventId: EventId, sessionId: SessionId, user: Username, path: MailboxPath, mailboxId: MailboxId, newPath: MailboxPath) extends Event {
-    override def toJava: events.Event = new JavaMailboxRenamed(sessionId, user, path.toJava, mailboxId, newPath.toJava, eventId)
+    override def toJava: JavaEvent = new JavaMailboxRenamed(sessionId, user, path.toJava, mailboxId, newPath.toJava, eventId)
   }
 
   case class QuotaUsageUpdatedEvent(eventId: EventId, user: Username, quotaRoot: QuotaRoot, countQuota: Quota[QuotaCountLimit, QuotaCountUsage],
                                     sizeQuota: Quota[QuotaSizeLimit, QuotaSizeUsage], time: Instant) extends Event {
-    override def toJava: events.Event = new JavaQuotaUsageUpdatedEvent(eventId, user, quotaRoot, countQuota.toJava, sizeQuota.toJava, time)
+    override def toJava: JavaEvent = new JavaQuotaUsageUpdatedEvent(eventId, user, quotaRoot, countQuota.toJava, sizeQuota.toJava, time)
   }
 
   case class Added(eventId: EventId, sessionId: SessionId, user: Username, path: MailboxPath, mailboxId: MailboxId,
                    added: Map[MessageUid, DTOs.MessageMetaData]) extends Event {
-    override def toJava: events.Event = new JavaAdded(
+    override def toJava: JavaEvent = new JavaAdded(
       sessionId,
       user,
       path.toJava,
@@ -82,7 +81,7 @@ private object DTO {
 
   case class Expunged(eventId: EventId, sessionId: SessionId, user: Username, path: MailboxPath, mailboxId: MailboxId,
                       expunged: Map[MessageUid, DTOs.MessageMetaData]) extends Event {
-    override def toJava: events.Event = new JavaExpunged(
+    override def toJava: JavaEvent = new JavaExpunged(
       sessionId,
       user,
       path.toJava,
@@ -93,7 +92,7 @@ private object DTO {
 
   case class MessageMoveEvent(eventId: EventId, user: Username, previousMailboxIds: Iterable[MailboxId], targetMailboxIds: Iterable[MailboxId],
                               messageIds: Iterable[MessageId]) extends Event {
-    override def toJava: events.Event = JavaMessageMoveEvent.builder()
+    override def toJava: JavaEvent = JavaMessageMoveEvent.builder()
       .eventId(eventId)
       .user(user)
       .messageId(messageIds.asJava)
@@ -106,7 +105,7 @@ private object DTO {
 
   case class FlagsUpdated(eventId: EventId, sessionId: SessionId, user: Username, path: MailboxPath, mailboxId: MailboxId,
                           updatedFlags: List[DTOs.UpdatedFlags]) extends Event {
-    override def toJava: events.Event = new JavaFlagsUpdated(
+    override def toJava: JavaEvent = new JavaFlagsUpdated(
       sessionId,
       user,
       path.toJava,
@@ -190,7 +189,7 @@ private object ScalaConverter {
     mailboxId = event.getMailboxId,
     updatedFlags = event.getUpdatedFlags.asScala.toList.map(DTOs.UpdatedFlags.toUpdatedFlags))
 
-  def toScala(javaEvent: events.Event): Event = javaEvent match {
+  def toScala(javaEvent: JavaEvent): Event = javaEvent match {
     case e: JavaAdded => toScala(e)
     case e: JavaExpunged => toScala(e)
     case e: JavaFlagsUpdated => toScala(e)
@@ -349,18 +348,18 @@ class JsonSerialize(mailboxIdFactory: MailboxId.Factory, messageIdFactory: Messa
   }
 
   private val eventSerializerPrivateWrapper = new EventSerializerPrivateWrapper()
-  def toJson(event: events.Event): String = eventSerializerPrivateWrapper.toJson(ScalaConverter.toScala(event))
-  def fromJson(json: String): JsResult[events.Event] = eventSerializerPrivateWrapper.fromJson(json)
+  def toJson(event: JavaEvent): String = eventSerializerPrivateWrapper.toJson(ScalaConverter.toScala(event))
+  def fromJson(json: String): JsResult[JavaEvent] = eventSerializerPrivateWrapper.fromJson(json)
     .map(event => event.toJava)
 }
 
 class MailboxEventSerializer @Inject()(mailboxIdFactory: MailboxId.Factory, messageIdFactory: MessageId.Factory, quotaRootDeserializer: QuotaRootDeserializer) extends EventSerializer{
   private val jsonSerialize = new JsonSerialize(mailboxIdFactory, messageIdFactory, quotaRootDeserializer)
 
-  override def toJson(event: events.Event): String = jsonSerialize.toJson(event)
+  override def toJson(event: JavaEvent): String = jsonSerialize.toJson(event)
 
-  def fromJson(json: String): JsResult[events.Event] = jsonSerialize.fromJson(json)
+  def fromJson(json: String): JsResult[JavaEvent] = jsonSerialize.fromJson(json)
 
-  override def asEvent(serialized: String): events.Event = fromJson(serialized).get
+  override def asEvent(serialized: String): JavaEvent = fromJson(serialized).get
 }
 


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


[james-project] 18/18: JAMES-3498 NamingStrategy should allow RabbitMQ eventBus isolation

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 3e3c83d7919037b90225d9152e2456d926b798c6
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Feb 1 17:10:51 2021 +0700

    JAMES-3498 NamingStrategy should allow RabbitMQ eventBus isolation
---
 .../apache/james/events/RabbitMQEventBusTest.java  | 59 ++++++++++++++++++++--
 1 file changed, 54 insertions(+), 5 deletions(-)

diff --git a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
index efc3db4..2554609 100644
--- a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
+++ b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
@@ -67,6 +67,7 @@ import org.apache.james.events.EventDispatcher.DispatchingFailureGroup;
 import org.apache.james.events.RoutingKeyConverter.RoutingKey;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
 import org.apache.james.util.concurrency.ConcurrentTestRunner;
+import org.assertj.core.api.SoftAssertions;
 import org.assertj.core.data.Percentage;
 import org.awaitility.Awaitility;
 import org.junit.jupiter.api.AfterEach;
@@ -146,11 +147,11 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
     }
 
     private RabbitMQEventBus newEventBus() {
-        return newEventBus(rabbitMQExtension.getSender(), rabbitMQExtension.getReceiverProvider());
+        return newEventBus(TEST_NAMING_STRATEGY, rabbitMQExtension.getSender(), rabbitMQExtension.getReceiverProvider());
     }
 
-    private RabbitMQEventBus newEventBus(Sender sender, ReceiverProvider receiverProvider) {
-        return new RabbitMQEventBus(TEST_NAMING_STRATEGY, sender, receiverProvider, eventSerializer,
+    private RabbitMQEventBus newEventBus(NamingStrategy namingStrategy, Sender sender, ReceiverProvider receiverProvider) {
+        return new RabbitMQEventBus(namingStrategy, sender, receiverProvider, eventSerializer,
             EventBusTestFixture.RETRY_BACKOFF_CONFIGURATION, routingKeyConverter,
             memoryEventDeadLetters, new RecordingMetricFactory(),
             rabbitMQExtension.getRabbitChannelPool(), EventBusId.random());
@@ -451,7 +452,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
 
                 @BeforeEach
                 void beforeEach() {
-                    rabbitMQEventBusWithNetWorkIssue = newEventBus(rabbitMQNetWorkIssueExtension.getSender(), rabbitMQNetWorkIssueExtension.getReceiverProvider());
+                    rabbitMQEventBusWithNetWorkIssue = newEventBus(TEST_NAMING_STRATEGY, rabbitMQNetWorkIssueExtension.getSender(), rabbitMQNetWorkIssueExtension.getReceiverProvider());
                 }
 
                 @Test
@@ -774,7 +775,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
 
                 assertThat(rabbitManagementAPI.listQueues())
                     .filteredOn(queue -> !queue.getName().startsWith("test-")
-                        && !queue.getName().startsWith("test-dead-letter-queue"))
+                        && !queue.getName().startsWith("other-"))
                     .isEmpty();
             }
 
@@ -810,6 +811,54 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
     }
 
     @Nested
+    class IsolationTest {
+        private RabbitMQEventBus otherEventBus;
+
+        @BeforeEach
+        void beforeEach() {
+            otherEventBus = newEventBus(new NamingStrategy("other"), rabbitMQExtension.getSender(), rabbitMQExtension.getReceiverProvider());
+            otherEventBus.start();
+        }
+
+        @AfterEach
+        void tearDown() {
+            otherEventBus.stop();
+        }
+
+        @Test
+        void eventBusGroupsWithDistinctNamingStrategiesShouldBeIsolated() throws Exception {
+            EventCollector listener = new EventCollector();
+            EventCollector otherListener = new EventCollector();
+            eventBus.register(listener, GROUP_A);
+            otherEventBus.register(otherListener, GROUP_B);
+
+            eventBus.dispatch(EVENT, ImmutableSet.of()).block();
+
+            TimeUnit.SECONDS.sleep(1);
+            SoftAssertions.assertSoftly(softly -> {
+                softly.assertThat(listener.getEvents()).hasSize(1);
+                softly.assertThat(otherListener.getEvents()).isEmpty();
+            });
+        }
+
+        @Test
+        void eventBusPubSubWithDistinctNamingStrategiesShouldBeIsolated() throws Exception {
+            EventCollector listener = new EventCollector();
+            EventCollector otherListener = new EventCollector();
+            eventBus.register(listener, KEY_1);
+            otherEventBus.register(otherListener, KEY_1);
+
+            eventBus.dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
+
+            TimeUnit.SECONDS.sleep(1);
+            SoftAssertions.assertSoftly(softly -> {
+                softly.assertThat(listener.getEvents()).hasSize(1);
+                softly.assertThat(otherListener.getEvents()).isEmpty();
+            });
+        }
+    }
+
+    @Nested
     class ErrorDispatchingTest {
 
         @AfterEach


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


[james-project] 17/18: JAMES-3498 Allow alternative namings for RabbitMQ queues/exchanges 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 65ca31380b2f84489192b4ef089a90d8ea28f6b8
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Feb 1 15:25:43 2021 +0700

    JAMES-3498 Allow alternative namings for RabbitMQ queues/exchanges names
    
    ```
    ~/Documents/james-project/event-bus$ grep -i mailbox * -R | grep -v target | grep -v *.iml | grep -i mailbox
    api/src/main/java/org/apache/james/events/EventBus.java:            return "mailbox-listener-" + listener.getClass().getSimpleName();
    api/src/main/java/org/apache/james/events/Group.java:import org.apache.james.mailbox.events.GenericGroup;
    api/src/main/java/org/apache/james/mailbox/events/GenericGroup.java:package org.apache.james.mailbox.events;
    api/src/test/java/org/apache/james/events/GroupTest.java:import org.apache.james.mailbox.events.GenericGroup;
    api/src/test/java/org/apache/james/events/GroupTest.java:        assertThat(new GenericGroup("abc").asString()).isEqualTo("org.apache.james.mailbox.events.GenericGroup-abc");
    api/src/test/java/org/apache/james/events/GroupTest.java:        assertThat(Group.deserialize("org.apache.james.mailbox.events.GenericGroup-abc"))
    api/src/test/java/org/apache/james/events/GroupTest.java:        assertThat(Group.deserialize("org.apache.james.mailbox.events.GenericGroup-"))
    api/src/test/java/org/apache/james/events/GroupTest.java:        assertThatThrownBy(() -> Group.deserialize("org.apache.james.mailbox.events.GenericGroup"))
    api/src/test/java/org/apache/james/events/GroupContract.java:import org.apache.james.mailbox.events.GenericGroup;
    ```
    
     - Keep `api/src/main/java/org/apache/james/events/EventBus.java:            return "mailbox-listener-" + listener.getClass().getSimpleName();` to preserve backward compatibility
     - `GenericGroup` should stay in mailbox package to not alter its FQDN
---
 .../org/apache/james/events/EventDispatcher.java   | 20 ++++-----
 .../apache/james/events/GroupConsumerRetry.java    | 25 ++++-------
 .../org/apache/james/events/GroupRegistration.java | 25 +++++------
 .../james/events/GroupRegistrationHandler.java     |  6 ++-
 .../james/events/KeyReconnectionHandler.java       |  7 ++--
 .../james/events/KeyRegistrationHandler.java       | 11 ++---
 ...RegistrationBinder.java => NamingStrategy.java} | 46 ++++++++++----------
 .../org/apache/james/events/RabbitMQEventBus.java  | 20 ++++-----
 .../apache/james/events/RegistrationBinder.java    |  8 ++--
 .../org/apache/james/events/NetworkErrorTest.java  |  2 +-
 ...RabbitMQEventBusDeadLetterQueueUpgradeTest.java |  5 ++-
 .../apache/james/events/RabbitMQEventBusTest.java  | 49 ++++++++++------------
 .../rabbitmq/host/RabbitMQEventBusHostSystem.java  |  3 +-
 .../modules/event/RabbitMQEventBusModule.java      |  2 +
 14 files changed, 109 insertions(+), 120 deletions(-)

diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java b/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
index 9a98aeb..ddfa875 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
@@ -27,9 +27,6 @@ import static org.apache.james.backends.rabbitmq.Constants.EMPTY_ROUTING_KEY;
 import static org.apache.james.backends.rabbitmq.Constants.EXCLUSIVE;
 import static org.apache.james.backends.rabbitmq.Constants.NO_ARGUMENTS;
 import static org.apache.james.events.RabbitMQEventBus.EVENT_BUS_ID;
-import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT_DEAD_LETTER_EXCHANGE_NAME;
-import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT_DEAD_LETTER_QUEUE;
-import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME;
 
 import java.nio.charset.StandardCharsets;
 import java.util.Collection;
@@ -54,7 +51,6 @@ import reactor.core.publisher.MonoProcessor;
 import reactor.rabbitmq.BindingSpecification;
 import reactor.rabbitmq.ExchangeSpecification;
 import reactor.rabbitmq.OutboundMessage;
-import reactor.rabbitmq.QueueSpecification;
 import reactor.rabbitmq.Sender;
 import reactor.util.function.Tuples;
 
@@ -65,6 +61,7 @@ public class EventDispatcher {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(EventDispatcher.class);
 
+    private final NamingStrategy namingStrategy;
     private final EventSerializer eventSerializer;
     private final Sender sender;
     private final LocalListenerRegistry localListenerRegistry;
@@ -72,10 +69,11 @@ public class EventDispatcher {
     private final ListenerExecutor listenerExecutor;
     private final EventDeadLetters deadLetters;
 
-    EventDispatcher(EventBusId eventBusId, EventSerializer eventSerializer, Sender sender,
+    EventDispatcher(NamingStrategy namingStrategy, EventBusId eventBusId, EventSerializer eventSerializer, Sender sender,
                     LocalListenerRegistry localListenerRegistry,
                     ListenerExecutor listenerExecutor,
                     EventDeadLetters deadLetters) {
+        this.namingStrategy = namingStrategy;
         this.eventSerializer = eventSerializer;
         this.sender = sender;
         this.localListenerRegistry = localListenerRegistry;
@@ -91,20 +89,20 @@ public class EventDispatcher {
 
     void start() {
         Flux.concat(
-            sender.declareExchange(ExchangeSpecification.exchange(MAILBOX_EVENT_EXCHANGE_NAME)
+            sender.declareExchange(ExchangeSpecification.exchange(namingStrategy.exchange())
                 .durable(DURABLE)
                 .type(DIRECT_EXCHANGE)),
-            sender.declareExchange(ExchangeSpecification.exchange(MAILBOX_EVENT_DEAD_LETTER_EXCHANGE_NAME)
+            sender.declareExchange(ExchangeSpecification.exchange(namingStrategy.deadLetterExchange())
                 .durable(DURABLE)
                 .type(DIRECT_EXCHANGE)),
-            sender.declareQueue(QueueSpecification.queue(MAILBOX_EVENT_DEAD_LETTER_QUEUE)
+            sender.declareQueue(namingStrategy.deadLetterQueue()
                 .durable(DURABLE)
                 .exclusive(!EXCLUSIVE)
                 .autoDelete(!AUTO_DELETE)
                 .arguments(NO_ARGUMENTS)),
             sender.bind(BindingSpecification.binding()
-                .exchange(MAILBOX_EVENT_DEAD_LETTER_EXCHANGE_NAME)
-                .queue(MAILBOX_EVENT_DEAD_LETTER_QUEUE)
+                .exchange(namingStrategy.deadLetterExchange())
+                .queue(namingStrategy.deadLetterQueue().getName())
                 .routingKey(EMPTY_ROUTING_KEY)))
             .then()
             .block();
@@ -185,7 +183,7 @@ public class EventDispatcher {
 
     private Flux<OutboundMessage> toMessages(byte[] serializedEvent, Collection<RoutingKey> routingKeys) {
         return Flux.fromIterable(routingKeys)
-                .map(routingKey -> new OutboundMessage(MAILBOX_EVENT_EXCHANGE_NAME, routingKey.asString(), basicProperties, serializedEvent));
+                .map(routingKey -> new OutboundMessage(namingStrategy.exchange(), routingKey.asString(), basicProperties, serializedEvent));
     }
 
     private byte[] serializeEvent(Event event) {
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java b/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
index 5c6fd2e..5982933 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
@@ -24,7 +24,6 @@ import static org.apache.james.backends.rabbitmq.Constants.DIRECT_EXCHANGE;
 import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
 import static org.apache.james.backends.rabbitmq.Constants.EMPTY_ROUTING_KEY;
 import static org.apache.james.events.GroupRegistration.RETRY_COUNT;
-import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT;
 
 import java.nio.charset.StandardCharsets;
 
@@ -33,8 +32,6 @@ import org.apache.james.util.StructuredLogger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableMap;
 import com.rabbitmq.client.AMQP;
 
@@ -46,23 +43,17 @@ import reactor.rabbitmq.OutboundMessage;
 import reactor.rabbitmq.Sender;
 
 class GroupConsumerRetry {
-
     static class RetryExchangeName {
-        static RetryExchangeName of(Group group) {
-            return new RetryExchangeName(group.asString());
-        }
-
-        static final String MAILBOX_EVENT_RETRY_EXCHANGE_PREFIX = MAILBOX_EVENT + "-retryExchange-";
-
-        private final String name;
+        private final String prefix;
+        private final Group group;
 
-        private RetryExchangeName(String name) {
-            Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "Exchange name must be specified");
-            this.name = name;
+        RetryExchangeName(String prefix, Group group) {
+            this.prefix = prefix;
+            this.group = group;
         }
 
         String asString() {
-            return MAILBOX_EVENT_RETRY_EXCHANGE_PREFIX + name;
+            return prefix + "-retryExchange-" + group.asString();
         }
     }
 
@@ -75,10 +66,10 @@ class GroupConsumerRetry {
     private final Group group;
     private final EventSerializer eventSerializer;
 
-    GroupConsumerRetry(Sender sender, Group group, RetryBackoffConfiguration retryBackoff,
+    GroupConsumerRetry(NamingStrategy namingStrategy, Sender sender, Group group, RetryBackoffConfiguration retryBackoff,
                        EventDeadLetters eventDeadLetters, EventSerializer eventSerializer) {
         this.sender = sender;
-        this.retryExchangeName = RetryExchangeName.of(group);
+        this.retryExchangeName = namingStrategy.retryExchange(group);
         this.retryBackoff = retryBackoff;
         this.eventDeadLetters = eventDeadLetters;
         this.group = group;
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java
index 3b16688..d0013ff 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java
@@ -25,7 +25,6 @@ import static org.apache.james.backends.rabbitmq.Constants.EMPTY_ROUTING_KEY;
 import static org.apache.james.backends.rabbitmq.Constants.EXCLUSIVE;
 import static org.apache.james.backends.rabbitmq.Constants.REQUEUE;
 import static org.apache.james.backends.rabbitmq.Constants.deadLetterQueue;
-import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT;
 
 import java.nio.charset.StandardCharsets;
 import java.util.Objects;
@@ -53,21 +52,17 @@ import reactor.util.retry.Retry;
 
 class GroupRegistration implements Registration {
     static class WorkQueueName {
-        static WorkQueueName of(Group group) {
-            return new WorkQueueName(group);
-        }
-
-        static final String MAILBOX_EVENT_WORK_QUEUE_PREFIX = MAILBOX_EVENT + "-workQueue-";
-
+        private final String prefix;
         private final Group group;
 
-        private WorkQueueName(Group group) {
+        WorkQueueName(String prefix, Group group) {
+            this.prefix = prefix;
             Preconditions.checkNotNull(group, "Group must be specified");
             this.group = group;
         }
 
         String asString() {
-            return MAILBOX_EVENT_WORK_QUEUE_PREFIX + group.asString();
+            return prefix + "-workQueue-" + group.asString();
         }
     }
 
@@ -75,6 +70,7 @@ class GroupRegistration implements Registration {
     static final String RETRY_COUNT = "retry-count";
     static final int DEFAULT_RETRY_COUNT = 0;
 
+    private final NamingStrategy namingStrategy;
     private final ReactorRabbitMQChannelPool channelPool;
     private final EventListener.ReactiveEventListener listener;
     private final WorkQueueName queueName;
@@ -89,21 +85,22 @@ class GroupRegistration implements Registration {
     private final ListenerExecutor listenerExecutor;
     private Optional<Disposable> receiverSubscriber;
 
-    GroupRegistration(ReactorRabbitMQChannelPool channelPool, Sender sender, ReceiverProvider receiverProvider, EventSerializer eventSerializer,
+    GroupRegistration(NamingStrategy namingStrategy, ReactorRabbitMQChannelPool channelPool, Sender sender, ReceiverProvider receiverProvider, EventSerializer eventSerializer,
                       EventListener.ReactiveEventListener listener, Group group, RetryBackoffConfiguration retryBackoff,
                       EventDeadLetters eventDeadLetters,
                       Runnable unregisterGroup, ListenerExecutor listenerExecutor) {
+        this.namingStrategy = namingStrategy;
         this.channelPool = channelPool;
         this.eventSerializer = eventSerializer;
         this.listener = listener;
-        this.queueName = WorkQueueName.of(group);
+        this.queueName = namingStrategy.workQueue(group);
         this.sender = sender;
         this.receiver = receiverProvider.createReceiver();
         this.retryBackoff = retryBackoff;
         this.listenerExecutor = listenerExecutor;
         this.receiverSubscriber = Optional.empty();
         this.unregisterGroup = unregisterGroup;
-        this.retryHandler = new GroupConsumerRetry(sender, group, retryBackoff, eventDeadLetters, eventSerializer);
+        this.retryHandler = new GroupConsumerRetry(namingStrategy, sender, group, retryBackoff, eventDeadLetters, eventSerializer);
         this.delayGenerator = WaitDelayGenerator.of(retryBackoff);
         this.group = group;
     }
@@ -124,9 +121,9 @@ class GroupRegistration implements Registration {
                 .durable(DURABLE)
                 .exclusive(!EXCLUSIVE)
                 .autoDelete(!AUTO_DELETE)
-                .arguments(deadLetterQueue(RabbitMQEventBus.MAILBOX_EVENT_DEAD_LETTER_EXCHANGE_NAME)),
+                .arguments(deadLetterQueue(namingStrategy.deadLetterExchange())),
             BindingSpecification.binding()
-                .exchange(RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME)
+                .exchange(namingStrategy.exchange())
                 .queue(queueName.asString())
                 .routingKey(EMPTY_ROUTING_KEY));
     }
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
index f1ddb6c..cb224d4 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
@@ -29,6 +29,7 @@ import org.apache.james.backends.rabbitmq.ReceiverProvider;
 import reactor.rabbitmq.Sender;
 
 class GroupRegistrationHandler {
+    private final NamingStrategy namingStrategy;
     private final Map<Group, GroupRegistration> groupRegistrations;
     private final EventSerializer eventSerializer;
     private final ReactorRabbitMQChannelPool channelPool;
@@ -38,9 +39,10 @@ class GroupRegistrationHandler {
     private final EventDeadLetters eventDeadLetters;
     private final ListenerExecutor listenerExecutor;
 
-    GroupRegistrationHandler(EventSerializer eventSerializer, ReactorRabbitMQChannelPool channelPool, Sender sender, ReceiverProvider receiverProvider,
+    GroupRegistrationHandler(NamingStrategy namingStrategy, EventSerializer eventSerializer, ReactorRabbitMQChannelPool channelPool, Sender sender, ReceiverProvider receiverProvider,
                              RetryBackoffConfiguration retryBackoff,
                              EventDeadLetters eventDeadLetters, ListenerExecutor listenerExecutor) {
+        this.namingStrategy = namingStrategy;
         this.eventSerializer = eventSerializer;
         this.channelPool = channelPool;
         this.sender = sender;
@@ -73,7 +75,7 @@ class GroupRegistrationHandler {
 
     private GroupRegistration newGroupRegistration(EventListener.ReactiveEventListener listener, Group group) {
         return new GroupRegistration(
-            channelPool, sender,
+            namingStrategy, channelPool, sender,
             receiverProvider,
             eventSerializer,
             listener,
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/KeyReconnectionHandler.java b/event-bus/distributed/src/main/java/org/apache/james/events/KeyReconnectionHandler.java
index 8b15173..41b3bba 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/KeyReconnectionHandler.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/KeyReconnectionHandler.java
@@ -22,7 +22,6 @@ package org.apache.james.events;
 import static org.apache.james.backends.rabbitmq.Constants.AUTO_DELETE;
 import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
 import static org.apache.james.backends.rabbitmq.Constants.EXCLUSIVE;
-import static org.apache.james.events.KeyRegistrationHandler.EVENTBUS_QUEUE_NAME_PREFIX;
 import static org.apache.james.events.KeyRegistrationHandler.QUEUE_ARGUMENTS;
 
 import javax.inject.Inject;
@@ -40,10 +39,12 @@ import reactor.core.publisher.Mono;
 public class KeyReconnectionHandler implements SimpleConnectionPool.ReconnectionHandler {
     private static final Logger LOGGER = LoggerFactory.getLogger(KeyReconnectionHandler.class);
 
+    private final NamingStrategy namingStrategy;
     private final EventBusId eventBusId;
 
     @Inject
-    public KeyReconnectionHandler(EventBusId eventBusId) {
+    public KeyReconnectionHandler(NamingStrategy namingStrategy, EventBusId eventBusId) {
+        this.namingStrategy = namingStrategy;
         this.eventBusId = eventBusId;
     }
 
@@ -51,7 +52,7 @@ public class KeyReconnectionHandler implements SimpleConnectionPool.Reconnection
     public Publisher<Void> handleReconnection(Connection connection) {
         return Mono.fromRunnable(() -> {
             try (Channel channel = connection.createChannel()) {
-                channel.queueDeclare(EVENTBUS_QUEUE_NAME_PREFIX + eventBusId.asString(), DURABLE, !EXCLUSIVE, AUTO_DELETE, QUEUE_ARGUMENTS);
+                channel.queueDeclare(namingStrategy.queueName(eventBusId).asString(), DURABLE, !EXCLUSIVE, AUTO_DELETE, QUEUE_ARGUMENTS);
             } catch (Exception e) {
                 LOGGER.error("Error recovering connection", e);
             }
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java b/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
index 1963d40..a6088be 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
@@ -53,12 +53,12 @@ import reactor.util.retry.Retry;
 
 class KeyRegistrationHandler {
     private static final Logger LOGGER = LoggerFactory.getLogger(KeyRegistrationHandler.class);
-    static final String EVENTBUS_QUEUE_NAME_PREFIX = "eventbus-";
     private static final Duration EXPIRATION_TIMEOUT = Duration.ofMinutes(30);
     static final Map<String, Object> QUEUE_ARGUMENTS = ImmutableMap.of("x-expires", EXPIRATION_TIMEOUT.toMillis());
 
     private static final Duration TOPOLOGY_CHANGES_TIMEOUT = Duration.ofMinutes(1);
 
+    private final NamingStrategy namingStrategy;
     private final EventBusId eventBusId;
     private final LocalListenerRegistry localListenerRegistry;
     private final EventSerializer eventSerializer;
@@ -71,10 +71,11 @@ class KeyRegistrationHandler {
     private final RetryBackoffConfiguration retryBackoff;
     private Optional<Disposable> receiverSubscriber;
 
-    KeyRegistrationHandler(EventBusId eventBusId, EventSerializer eventSerializer,
+    KeyRegistrationHandler(NamingStrategy namingStrategy, EventBusId eventBusId, EventSerializer eventSerializer,
                            Sender sender, ReceiverProvider receiverProvider,
                            RoutingKeyConverter routingKeyConverter, LocalListenerRegistry localListenerRegistry,
                            ListenerExecutor listenerExecutor, RetryBackoffConfiguration retryBackoff) {
+        this.namingStrategy = namingStrategy;
         this.eventBusId = eventBusId;
         this.eventSerializer = eventSerializer;
         this.sender = sender;
@@ -83,8 +84,8 @@ class KeyRegistrationHandler {
         this.receiver = receiverProvider.createReceiver();
         this.listenerExecutor = listenerExecutor;
         this.retryBackoff = retryBackoff;
-        this.registrationQueue = new RegistrationQueueName(EVENTBUS_QUEUE_NAME_PREFIX + eventBusId.asString());
-        this.registrationBinder = new RegistrationBinder(sender, registrationQueue);
+        this.registrationQueue = namingStrategy.queueName(eventBusId);
+        this.registrationBinder = new RegistrationBinder(namingStrategy, sender, registrationQueue);
         this.receiverSubscriber = Optional.empty();
 
     }
@@ -105,7 +106,7 @@ class KeyRegistrationHandler {
 
     private void declareQueue(Sender sender) {
         sender.declareQueue(
-            QueueSpecification.queue(EVENTBUS_QUEUE_NAME_PREFIX + eventBusId.asString())
+            QueueSpecification.queue(registrationQueue.asString())
                 .durable(DURABLE)
                 .exclusive(!EXCLUSIVE)
                 .autoDelete(AUTO_DELETE)
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/RegistrationBinder.java b/event-bus/distributed/src/main/java/org/apache/james/events/NamingStrategy.java
similarity index 53%
copy from event-bus/distributed/src/main/java/org/apache/james/events/RegistrationBinder.java
copy to event-bus/distributed/src/main/java/org/apache/james/events/NamingStrategy.java
index 45fbd49..80dc2d2 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/RegistrationBinder.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/NamingStrategy.java
@@ -19,36 +19,36 @@
 
 package org.apache.james.events;
 
-import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME;
+import reactor.rabbitmq.QueueSpecification;
 
-import reactor.core.publisher.Mono;
-import reactor.rabbitmq.BindingSpecification;
-import reactor.rabbitmq.Sender;
+public class NamingStrategy {
+    private final String prefix;
 
-class RegistrationBinder {
-    private final Sender sender;
-    private final RegistrationQueueName registrationQueue;
+    public NamingStrategy(String prefix) {
+        this.prefix = prefix;
+    }
+
+    public RegistrationQueueName queueName(EventBusId eventBusId) {
+        return new RegistrationQueueName(prefix + "-eventbus-" + eventBusId.asString());
+    }
+
+    public QueueSpecification deadLetterQueue() {
+        return QueueSpecification.queue(prefix + "-dead-letter-queue");
+    }
 
-    RegistrationBinder(Sender sender, RegistrationQueueName registrationQueue) {
-        this.sender = sender;
-        this.registrationQueue = registrationQueue;
+    public String exchange() {
+        return prefix + "-exchange";
     }
 
-    Mono<Void> bind(RegistrationKey key) {
-        return sender.bind(bindingSpecification(key))
-            .then();
+    public String deadLetterExchange() {
+        return prefix + "-dead-letter-exchange";
     }
 
-    Mono<Void> unbind(RegistrationKey key) {
-        return sender.unbind(bindingSpecification(key))
-            .then();
+    public GroupConsumerRetry.RetryExchangeName retryExchange(Group group) {
+        return new GroupConsumerRetry.RetryExchangeName(prefix, group);
     }
 
-    private BindingSpecification bindingSpecification(RegistrationKey key) {
-        RoutingKeyConverter.RoutingKey routingKey = RoutingKeyConverter.RoutingKey.of(key);
-        return BindingSpecification.binding()
-            .exchange(MAILBOX_EVENT_EXCHANGE_NAME)
-            .queue(registrationQueue.asString())
-            .routingKey(routingKey.asString());
+    public GroupRegistration.WorkQueueName workQueue(Group group) {
+        return new GroupRegistration.WorkQueueName(prefix, group);
     }
-}
\ No newline at end of file
+}
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/RabbitMQEventBus.java b/event-bus/distributed/src/main/java/org/apache/james/events/RabbitMQEventBus.java
index 78aeae7..ad50412 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/RabbitMQEventBus.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/RabbitMQEventBus.java
@@ -39,12 +39,9 @@ import reactor.rabbitmq.Sender;
 public class RabbitMQEventBus implements EventBus, Startable {
     private static final Set<RegistrationKey> NO_KEY = ImmutableSet.of();
     private static final String NOT_RUNNING_ERROR_MESSAGE = "Event Bus is not running";
-    static final String MAILBOX_EVENT = "mailboxEvent";
-    static final String MAILBOX_EVENT_DEAD_LETTER_QUEUE = MAILBOX_EVENT + "-dead-letter-queue";
-    static final String MAILBOX_EVENT_EXCHANGE_NAME = MAILBOX_EVENT + "-exchange";
-    static final String MAILBOX_EVENT_DEAD_LETTER_EXCHANGE_NAME = MAILBOX_EVENT + "-dead-letter-exchange";
     static final String EVENT_BUS_ID = "eventBusId";
 
+    private final NamingStrategy namingStrategy;
     private final EventSerializer eventSerializer;
     private final RoutingKeyConverter routingKeyConverter;
     private final RetryBackoffConfiguration retryBackoff;
@@ -62,11 +59,12 @@ public class RabbitMQEventBus implements EventBus, Startable {
     private EventDispatcher eventDispatcher;
 
     @Inject
-    public RabbitMQEventBus(Sender sender, ReceiverProvider receiverProvider, EventSerializer eventSerializer,
+    public RabbitMQEventBus(NamingStrategy namingStrategy, Sender sender, ReceiverProvider receiverProvider, EventSerializer eventSerializer,
                             RetryBackoffConfiguration retryBackoff,
                             RoutingKeyConverter routingKeyConverter,
                             EventDeadLetters eventDeadLetters, MetricFactory metricFactory, ReactorRabbitMQChannelPool channelPool,
                             EventBusId eventBusId) {
+        this.namingStrategy = namingStrategy;
         this.sender = sender;
         this.receiverProvider = receiverProvider;
         this.listenerExecutor = new ListenerExecutor(metricFactory);
@@ -84,9 +82,9 @@ public class RabbitMQEventBus implements EventBus, Startable {
         if (!isRunning && !isStopping) {
 
             LocalListenerRegistry localListenerRegistry = new LocalListenerRegistry();
-            keyRegistrationHandler = new KeyRegistrationHandler(eventBusId, eventSerializer, sender, receiverProvider, routingKeyConverter, localListenerRegistry, listenerExecutor, retryBackoff);
-            groupRegistrationHandler = new GroupRegistrationHandler(eventSerializer, channelPool, sender, receiverProvider, retryBackoff, eventDeadLetters, listenerExecutor);
-            eventDispatcher = new EventDispatcher(eventBusId, eventSerializer, sender, localListenerRegistry, listenerExecutor, eventDeadLetters);
+            keyRegistrationHandler = new KeyRegistrationHandler(namingStrategy, eventBusId, eventSerializer, sender, receiverProvider, routingKeyConverter, localListenerRegistry, listenerExecutor, retryBackoff);
+            groupRegistrationHandler = new GroupRegistrationHandler(namingStrategy, eventSerializer, channelPool, sender, receiverProvider, retryBackoff, eventDeadLetters, listenerExecutor);
+            eventDispatcher = new EventDispatcher(namingStrategy, eventBusId, eventSerializer, sender, localListenerRegistry, listenerExecutor, eventDeadLetters);
 
             eventDispatcher.start();
             keyRegistrationHandler.start();
@@ -99,9 +97,9 @@ public class RabbitMQEventBus implements EventBus, Startable {
         if (!isRunning && !isStopping) {
 
             LocalListenerRegistry localListenerRegistry = new LocalListenerRegistry();
-            keyRegistrationHandler = new KeyRegistrationHandler(eventBusId, eventSerializer, sender, receiverProvider, routingKeyConverter, localListenerRegistry, listenerExecutor, retryBackoff);
-            groupRegistrationHandler = new GroupRegistrationHandler(eventSerializer, channelPool, sender, receiverProvider, retryBackoff, eventDeadLetters, listenerExecutor);
-            eventDispatcher = new EventDispatcher(eventBusId, eventSerializer, sender, localListenerRegistry, listenerExecutor, eventDeadLetters);
+            keyRegistrationHandler = new KeyRegistrationHandler(namingStrategy, eventBusId, eventSerializer, sender, receiverProvider, routingKeyConverter, localListenerRegistry, listenerExecutor, retryBackoff);
+            groupRegistrationHandler = new GroupRegistrationHandler(namingStrategy, eventSerializer, channelPool, sender, receiverProvider, retryBackoff, eventDeadLetters, listenerExecutor);
+            eventDispatcher = new EventDispatcher(namingStrategy, eventBusId, eventSerializer, sender, localListenerRegistry, listenerExecutor, eventDeadLetters);
 
             keyRegistrationHandler.declareQueue();
 
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/RegistrationBinder.java b/event-bus/distributed/src/main/java/org/apache/james/events/RegistrationBinder.java
index 45fbd49..acd3475 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/RegistrationBinder.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/RegistrationBinder.java
@@ -19,17 +19,17 @@
 
 package org.apache.james.events;
 
-import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME;
-
 import reactor.core.publisher.Mono;
 import reactor.rabbitmq.BindingSpecification;
 import reactor.rabbitmq.Sender;
 
 class RegistrationBinder {
+    private final NamingStrategy namingStrategy;
     private final Sender sender;
     private final RegistrationQueueName registrationQueue;
 
-    RegistrationBinder(Sender sender, RegistrationQueueName registrationQueue) {
+    RegistrationBinder(NamingStrategy namingStrategy, Sender sender, RegistrationQueueName registrationQueue) {
+        this.namingStrategy = namingStrategy;
         this.sender = sender;
         this.registrationQueue = registrationQueue;
     }
@@ -47,7 +47,7 @@ class RegistrationBinder {
     private BindingSpecification bindingSpecification(RegistrationKey key) {
         RoutingKeyConverter.RoutingKey routingKey = RoutingKeyConverter.RoutingKey.of(key);
         return BindingSpecification.binding()
-            .exchange(MAILBOX_EVENT_EXCHANGE_NAME)
+            .exchange(namingStrategy.exchange())
             .queue(registrationQueue.asString())
             .routingKey(routingKey.asString());
     }
diff --git a/event-bus/distributed/src/test/java/org/apache/james/events/NetworkErrorTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/NetworkErrorTest.java
index 56d903c..fbcc13e 100644
--- a/event-bus/distributed/src/test/java/org/apache/james/events/NetworkErrorTest.java
+++ b/event-bus/distributed/src/test/java/org/apache/james/events/NetworkErrorTest.java
@@ -51,7 +51,7 @@ class NetworkErrorTest {
         EventSerializer eventSerializer = new TestEventSerializer();
         RoutingKeyConverter routingKeyConverter = RoutingKeyConverter.forFactories(new EventBusTestFixture.TestRegistrationKeyFactory());
 
-        eventBus = new RabbitMQEventBus(rabbitMQExtension.getSender(), rabbitMQExtension.getReceiverProvider(),
+        eventBus = new RabbitMQEventBus(new NamingStrategy("test"), rabbitMQExtension.getSender(), rabbitMQExtension.getReceiverProvider(),
             eventSerializer, RETRY_BACKOFF_CONFIGURATION, routingKeyConverter,
             memoryEventDeadLetters, new RecordingMetricFactory(), rabbitMQExtension.getRabbitChannelPool(),
             EventBusId.random());
diff --git a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
index 137e59c..ea73049 100644
--- a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
+++ b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
@@ -40,7 +40,8 @@ import reactor.rabbitmq.QueueSpecification;
 
 class RabbitMQEventBusDeadLetterQueueUpgradeTest {
     private static final GroupA REGISTERED_GROUP = new GroupA();
-    private static final WorkQueueName WORK_QUEUE_NAME = WorkQueueName.of(REGISTERED_GROUP);
+    public static final NamingStrategy NAMING_STRATEGY = new NamingStrategy("test");
+    private static final WorkQueueName WORK_QUEUE_NAME = NAMING_STRATEGY.workQueue(REGISTERED_GROUP);
 
     @RegisterExtension
     static RabbitMQExtension rabbitMQExtension = RabbitMQExtension.singletonRabbitMQ()
@@ -55,7 +56,7 @@ class RabbitMQEventBusDeadLetterQueueUpgradeTest {
         EventSerializer eventSerializer = new TestEventSerializer();
         RoutingKeyConverter routingKeyConverter = RoutingKeyConverter.forFactories(new TestRegistrationKeyFactory());
 
-        eventBus = new RabbitMQEventBus(rabbitMQExtension.getSender(), rabbitMQExtension.getReceiverProvider(),
+        eventBus = new RabbitMQEventBus(NAMING_STRATEGY, rabbitMQExtension.getSender(), rabbitMQExtension.getReceiverProvider(),
             eventSerializer, RETRY_BACKOFF_CONFIGURATION, routingKeyConverter,
             memoryEventDeadLetters, new RecordingMetricFactory(), rabbitMQExtension.getRabbitChannelPool(),
             EventBusId.random());
diff --git a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
index b191547..efc3db4 100644
--- a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
+++ b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
@@ -35,10 +35,6 @@ import static org.apache.james.events.EventBusTestFixture.KEY_1;
 import static org.apache.james.events.EventBusTestFixture.NO_KEYS;
 import static org.apache.james.events.EventBusTestFixture.newAsyncListener;
 import static org.apache.james.events.EventBusTestFixture.newListener;
-import static org.apache.james.events.GroupRegistration.WorkQueueName.MAILBOX_EVENT_WORK_QUEUE_PREFIX;
-import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT;
-import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT_DEAD_LETTER_QUEUE;
-import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -95,6 +91,7 @@ import reactor.rabbitmq.Sender;
 class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract, GroupContract.MultipleEventBusGroupContract,
     KeyContract.SingleEventBusKeyContract, KeyContract.MultipleEventBusKeyContract,
     ErrorHandlingContract {
+    static NamingStrategy TEST_NAMING_STRATEGY = new NamingStrategy("test");
 
     @RegisterExtension
     static RabbitMQExtension rabbitMQExtension = RabbitMQExtension.singletonRabbitMQ()
@@ -138,13 +135,13 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
         eventBus3.stop();
         eventBusWithKeyHandlerNotStarted.stop();
         ALL_GROUPS.stream()
-            .map(GroupRegistration.WorkQueueName::of)
+            .map(TEST_NAMING_STRATEGY::workQueue)
             .forEach(queueName -> rabbitMQExtension.getSender().delete(QueueSpecification.queue(queueName.asString())).block());
         rabbitMQExtension.getSender()
-            .delete(ExchangeSpecification.exchange(MAILBOX_EVENT_EXCHANGE_NAME))
+            .delete(ExchangeSpecification.exchange(TEST_NAMING_STRATEGY.exchange()))
             .block();
         rabbitMQExtension.getSender()
-            .delete(QueueSpecification.queue().name(MAILBOX_EVENT_DEAD_LETTER_QUEUE))
+            .delete(TEST_NAMING_STRATEGY.deadLetterQueue())
             .block();
     }
 
@@ -153,7 +150,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
     }
 
     private RabbitMQEventBus newEventBus(Sender sender, ReceiverProvider receiverProvider) {
-        return new RabbitMQEventBus(sender, receiverProvider, eventSerializer,
+        return new RabbitMQEventBus(TEST_NAMING_STRATEGY, sender, receiverProvider, eventSerializer,
             EventBusTestFixture.RETRY_BACKOFF_CONFIGURATION, routingKeyConverter,
             memoryEventDeadLetters, new RecordingMetricFactory(),
             rabbitMQExtension.getRabbitChannelPool(), EventBusId.random());
@@ -189,7 +186,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
 
         String emptyRoutingKey = "";
         rabbitMQExtension.getSender()
-            .send(Mono.just(new OutboundMessage(MAILBOX_EVENT_EXCHANGE_NAME,
+            .send(Mono.just(new OutboundMessage(TEST_NAMING_STRATEGY.exchange(),
                 emptyRoutingKey,
                 "BAD_PAYLOAD!".getBytes(StandardCharsets.UTF_8))))
             .block();
@@ -208,7 +205,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
 
         String emptyRoutingKey = "";
         IntStream.range(0, 10).forEach(i -> rabbitMQExtension.getSender()
-            .send(Mono.just(new OutboundMessage(MAILBOX_EVENT_EXCHANGE_NAME,
+            .send(Mono.just(new OutboundMessage(TEST_NAMING_STRATEGY.exchange(),
                 emptyRoutingKey,
                 "BAD_PAYLOAD!".getBytes(StandardCharsets.UTF_8))))
             .block());
@@ -227,7 +224,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
 
         String emptyRoutingKey = "";
         rabbitMQExtension.getSender()
-            .send(Mono.just(new OutboundMessage(MAILBOX_EVENT_EXCHANGE_NAME,
+            .send(Mono.just(new OutboundMessage(TEST_NAMING_STRATEGY.exchange(),
                 emptyRoutingKey,
                 "BAD_PAYLOAD!".getBytes(StandardCharsets.UTF_8))))
             .block();
@@ -235,7 +232,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
         AtomicInteger deadLetteredCount = new AtomicInteger();
         rabbitMQExtension.getRabbitChannelPool()
             .createReceiver()
-            .consumeAutoAck(MAILBOX_EVENT_DEAD_LETTER_QUEUE)
+            .consumeAutoAck(TEST_NAMING_STRATEGY.deadLetterQueue().getName())
             .doOnNext(next -> deadLetteredCount.incrementAndGet())
             .subscribeOn(Schedulers.elastic())
             .subscribe();
@@ -250,7 +247,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
         Mono.from(eventBus.register(listener, KEY_1)).block();
 
         rabbitMQExtension.getSender()
-            .send(Mono.just(new OutboundMessage(MAILBOX_EVENT_EXCHANGE_NAME,
+            .send(Mono.just(new OutboundMessage(TEST_NAMING_STRATEGY.exchange(),
                 RoutingKey.of(KEY_1).asString(),
                 "BAD_PAYLOAD!".getBytes(StandardCharsets.UTF_8))))
             .block();
@@ -267,7 +264,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
 
         IntStream.range(0, 100)
             .forEach(i -> rabbitMQExtension.getSender()
-                .send(Mono.just(new OutboundMessage(MAILBOX_EVENT_EXCHANGE_NAME,
+                .send(Mono.just(new OutboundMessage(TEST_NAMING_STRATEGY.exchange(),
                     RoutingKey.of(KEY_1).asString(),
                     "BAD_PAYLOAD!".getBytes(StandardCharsets.UTF_8))))
                 .block());
@@ -289,7 +286,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
         GroupA registeredGroup = new GroupA();
         eventBus.register(listener, registeredGroup);
 
-        GroupConsumerRetry.RetryExchangeName retryExchangeName = GroupConsumerRetry.RetryExchangeName.of(registeredGroup);
+        GroupConsumerRetry.RetryExchangeName retryExchangeName = TEST_NAMING_STRATEGY.retryExchange(registeredGroup);
         assertThat(rabbitMQExtension.managementAPI().listExchanges())
             .anyMatch(exchange -> exchange.getName().equals(retryExchangeName.asString()));
     }
@@ -378,21 +375,21 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
 
     @Nested
     class PublishingTest {
-        private static final String MAILBOX_WORK_QUEUE_NAME = MAILBOX_EVENT + "-workQueue";
+        private static final String WORK_QUEUE_NAME = "test-workQueue";
 
         @BeforeEach
         void setUp() {
             Sender sender = rabbitMQExtension.getSender();
 
-            sender.declareQueue(QueueSpecification.queue(MAILBOX_WORK_QUEUE_NAME)
+            sender.declareQueue(QueueSpecification.queue(WORK_QUEUE_NAME)
                 .durable(DURABLE)
                 .exclusive(!EXCLUSIVE)
                 .autoDelete(!AUTO_DELETE)
                 .arguments(NO_ARGUMENTS))
                 .block();
             sender.bind(BindingSpecification.binding()
-                .exchange(MAILBOX_EVENT_EXCHANGE_NAME)
-                .queue(MAILBOX_WORK_QUEUE_NAME)
+                .exchange(TEST_NAMING_STRATEGY.exchange())
+                .queue(WORK_QUEUE_NAME)
                 .routingKey(EMPTY_ROUTING_KEY))
                 .block();
         }
@@ -413,7 +410,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
 
         private Event dequeueEvent() {
             try (Receiver receiver = rabbitMQExtension.getReceiverProvider().createReceiver()) {
-                byte[] eventInBytes = receiver.consumeAutoAck(MAILBOX_WORK_QUEUE_NAME)
+                byte[] eventInBytes = receiver.consumeAutoAck(WORK_QUEUE_NAME)
                     .blockFirst()
                     .getBody();
 
@@ -480,7 +477,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             void startShouldCreateEventExchange() {
                 eventBus.start();
                 assertThat(rabbitManagementAPI.listExchanges())
-                    .filteredOn(exchange -> exchange.getName().equals(MAILBOX_EVENT_EXCHANGE_NAME))
+                    .filteredOn(exchange -> exchange.getName().equals(TEST_NAMING_STRATEGY.exchange()))
                     .hasOnlyOneElementSatisfying(exchange -> {
                         assertThat(exchange.isDurable()).isTrue();
                         assertThat(exchange.getType()).isEqualTo(DIRECT_EXCHANGE);
@@ -659,7 +656,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
                 eventBus.stop();
 
                 assertThat(rabbitManagementAPI.listExchanges())
-                    .anySatisfy(exchange -> assertThat(exchange.getName()).isEqualTo(MAILBOX_EVENT_EXCHANGE_NAME));
+                    .anySatisfy(exchange -> assertThat(exchange.getName()).isEqualTo(TEST_NAMING_STRATEGY.exchange()));
             }
 
             @Test
@@ -719,7 +716,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void multipleEventBusStartShouldCreateOnlyOneEventExchange() {
                 assertThat(rabbitManagementAPI.listExchanges())
-                    .filteredOn(exchange -> exchange.getName().equals(MAILBOX_EVENT_EXCHANGE_NAME))
+                    .filteredOn(exchange -> exchange.getName().equals(TEST_NAMING_STRATEGY.exchange()))
                     .hasSize(1);
             }
 
@@ -752,7 +749,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
                 eventBusWithKeyHandlerNotStarted.stop();
 
                 assertThat(rabbitManagementAPI.listExchanges())
-                    .anySatisfy(exchange -> assertThat(exchange.getName()).isEqualTo(MAILBOX_EVENT_EXCHANGE_NAME));
+                    .anySatisfy(exchange -> assertThat(exchange.getName()).isEqualTo(TEST_NAMING_STRATEGY.exchange()));
             }
 
             @Test
@@ -776,8 +773,8 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
                 eventBusWithKeyHandlerNotStarted.stop();
 
                 assertThat(rabbitManagementAPI.listQueues())
-                    .filteredOn(queue -> !queue.getName().startsWith(MAILBOX_EVENT_WORK_QUEUE_PREFIX)
-                        && !queue.getName().startsWith(MAILBOX_EVENT_DEAD_LETTER_QUEUE))
+                    .filteredOn(queue -> !queue.getName().startsWith("test-")
+                        && !queue.getName().startsWith("test-dead-letter-queue"))
                     .isEmpty();
             }
 
diff --git a/mpt/impl/imap-mailbox/rabbitmq/src/test/java/org/apache/james/mpt/imapmailbox/rabbitmq/host/RabbitMQEventBusHostSystem.java b/mpt/impl/imap-mailbox/rabbitmq/src/test/java/org/apache/james/mpt/imapmailbox/rabbitmq/host/RabbitMQEventBusHostSystem.java
index d6a451d..831183e 100644
--- a/mpt/impl/imap-mailbox/rabbitmq/src/test/java/org/apache/james/mpt/imapmailbox/rabbitmq/host/RabbitMQEventBusHostSystem.java
+++ b/mpt/impl/imap-mailbox/rabbitmq/src/test/java/org/apache/james/mpt/imapmailbox/rabbitmq/host/RabbitMQEventBusHostSystem.java
@@ -33,6 +33,7 @@ import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.event.json.MailboxEventSerializer;
 import org.apache.james.events.EventBusId;
 import org.apache.james.events.MemoryEventDeadLetters;
+import org.apache.james.events.NamingStrategy;
 import org.apache.james.events.RabbitMQEventBus;
 import org.apache.james.events.RetryBackoffConfiguration;
 import org.apache.james.events.RoutingKeyConverter;
@@ -117,7 +118,7 @@ public class RabbitMQEventBusHostSystem extends JamesImapHostSystem {
         InMemoryId.Factory mailboxIdFactory = new InMemoryId.Factory();
         MailboxEventSerializer eventSerializer = new MailboxEventSerializer(mailboxIdFactory, messageIdFactory, new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
         RoutingKeyConverter routingKeyConverter = new RoutingKeyConverter(ImmutableSet.of(new MailboxIdRegistrationKey.Factory(mailboxIdFactory)));
-        return new RabbitMQEventBus(reactorRabbitMQChannelPool.getSender(), reactorRabbitMQChannelPool::createReceiver,
+        return new RabbitMQEventBus(new NamingStrategy("mailboxEvent-"), reactorRabbitMQChannelPool.getSender(), reactorRabbitMQChannelPool::createReceiver,
             eventSerializer, RetryBackoffConfiguration.DEFAULT, routingKeyConverter, new MemoryEventDeadLetters(),
             new RecordingMetricFactory(),
             reactorRabbitMQChannelPool, EventBusId.random());
diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java
index 8dc2e5e..fea6b3f 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java
@@ -25,6 +25,7 @@ import org.apache.james.events.EventBus;
 import org.apache.james.events.EventBusId;
 import org.apache.james.events.EventSerializer;
 import org.apache.james.events.KeyReconnectionHandler;
+import org.apache.james.events.NamingStrategy;
 import org.apache.james.events.RabbitMQEventBus;
 import org.apache.james.events.RegistrationKey;
 import org.apache.james.events.RetryBackoffConfiguration;
@@ -44,6 +45,7 @@ public class RabbitMQEventBusModule extends AbstractModule {
         bind(MailboxEventSerializer.class).in(Scopes.SINGLETON);
         bind(EventSerializer.class).to(MailboxEventSerializer.class);
 
+        bind(NamingStrategy.class).toInstance(new NamingStrategy("mailboxEvent"));
         bind(RabbitMQEventBus.class).in(Scopes.SINGLETON);
         bind(EventBus.class).to(RabbitMQEventBus.class);
 


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


[james-project] 05/18: JAMES-3498 Move the event-bus contracts out of mailbox-api

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 a76f45fff45534295cdbed240e9b781498f99b05
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 25 14:24:03 2021 +0700

    JAMES-3498 Move the event-bus contracts out of mailbox-api
---
 event-bus/api/pom.xml                              | 41 +++++++++++++++++++++
 .../james/events/RetryBackoffConfiguration.java    |  0
 .../apache/james/events/ErrorHandlingContract.java |  1 -
 .../events/EventBusConcurrentTestContract.java     |  0
 .../org/apache/james/events/EventBusContract.java  |  0
 .../apache/james/events/EventBusTestFixture.java   |  2 +-
 .../org/apache/james/events/EventCollector.java    | 42 ++++++++++------------
 .../james/events/EventDeadLettersContract.java     |  2 +-
 .../EventDeadLettersHealthCheckContract.java       |  2 +-
 .../org/apache/james/events/GroupContract.java     |  2 +-
 .../java/org/apache/james/events/GroupTest.java    |  4 +--
 .../org/apache/james/events/InsertionIdTest.java   |  1 -
 .../java/org/apache/james/events/KeyContract.java  |  2 +-
 .../events/RetryBackoffConfigurationTest.java      |  0
 event-bus/cassandra/pom.xml                        | 10 ++++++
 event-bus/distributed/pom.xml                      | 10 ++++++
 event-bus/in-vm/pom.xml                            | 10 ++++++
 mailbox/maildir/pom.xml                            |  6 ++++
 pom.xml                                            |  6 ++++
 protocols/imap/pom.xml                             |  6 ++++
 20 files changed, 115 insertions(+), 32 deletions(-)

diff --git a/event-bus/api/pom.xml b/event-bus/api/pom.xml
index cbf7cc8..df7be49 100644
--- a/event-bus/api/pom.xml
+++ b/event-bus/api/pom.xml
@@ -34,9 +34,35 @@
     <dependencies>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>apache-james-mailbox-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>apache-james-mailbox-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-core</artifactId>
         </dependency>
         <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-util</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>metrics-tests</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>testing-base</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
         </dependency>
@@ -48,5 +74,20 @@
             <groupId>javax.inject</groupId>
             <artifactId>javax.inject</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>java-hamcrest</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
\ No newline at end of file
diff --git a/mailbox/api/src/main/java/org/apache/james/events/RetryBackoffConfiguration.java b/event-bus/api/src/main/java/org/apache/james/events/RetryBackoffConfiguration.java
similarity index 100%
rename from mailbox/api/src/main/java/org/apache/james/events/RetryBackoffConfiguration.java
rename to event-bus/api/src/main/java/org/apache/james/events/RetryBackoffConfiguration.java
diff --git a/mailbox/api/src/test/java/org/apache/james/events/ErrorHandlingContract.java b/event-bus/api/src/test/java/org/apache/james/events/ErrorHandlingContract.java
similarity index 99%
rename from mailbox/api/src/test/java/org/apache/james/events/ErrorHandlingContract.java
rename to event-bus/api/src/test/java/org/apache/james/events/ErrorHandlingContract.java
index 3d20090..76c25a8 100644
--- a/mailbox/api/src/test/java/org/apache/james/events/ErrorHandlingContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/ErrorHandlingContract.java
@@ -37,7 +37,6 @@ import java.util.List;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import org.apache.james.mailbox.util.EventCollector;
 import org.assertj.core.api.SoftAssertions;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
diff --git a/mailbox/api/src/test/java/org/apache/james/events/EventBusConcurrentTestContract.java b/event-bus/api/src/test/java/org/apache/james/events/EventBusConcurrentTestContract.java
similarity index 100%
rename from mailbox/api/src/test/java/org/apache/james/events/EventBusConcurrentTestContract.java
rename to event-bus/api/src/test/java/org/apache/james/events/EventBusConcurrentTestContract.java
diff --git a/mailbox/api/src/test/java/org/apache/james/events/EventBusContract.java b/event-bus/api/src/test/java/org/apache/james/events/EventBusContract.java
similarity index 100%
rename from mailbox/api/src/test/java/org/apache/james/events/EventBusContract.java
rename to event-bus/api/src/test/java/org/apache/james/events/EventBusContract.java
diff --git a/mailbox/api/src/test/java/org/apache/james/events/EventBusTestFixture.java b/event-bus/api/src/test/java/org/apache/james/events/EventBusTestFixture.java
similarity index 100%
rename from mailbox/api/src/test/java/org/apache/james/events/EventBusTestFixture.java
rename to event-bus/api/src/test/java/org/apache/james/events/EventBusTestFixture.java
index e415382..9398247 100644
--- a/mailbox/api/src/test/java/org/apache/james/events/EventBusTestFixture.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/EventBusTestFixture.java
@@ -28,10 +28,10 @@ import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.james.core.Username;
-import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.events.MailboxEvents.MailboxAdded;
 import org.apache.james.events.MailboxEvents.MailboxEvent;
 import org.apache.james.events.MailboxEvents.MailboxRenamed;
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
diff --git a/mailbox/api/src/test/java/org/apache/james/events/InsertionIdTest.java b/event-bus/api/src/test/java/org/apache/james/events/EventCollector.java
similarity index 53%
copy from mailbox/api/src/test/java/org/apache/james/events/InsertionIdTest.java
copy to event-bus/api/src/test/java/org/apache/james/events/EventCollector.java
index d592590..077e61b 100644
--- a/mailbox/api/src/test/java/org/apache/james/events/InsertionIdTest.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/EventCollector.java
@@ -19,39 +19,35 @@
 
 package org.apache.james.events;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import java.util.Collection;
+import java.util.concurrent.ConcurrentLinkedDeque;
 
-import java.util.UUID;
+public class EventCollector implements EventListener.GroupEventListener {
+    public static class EventCollectorGroup extends Group {
 
-import org.apache.james.events.EventDeadLetters;
-import org.junit.jupiter.api.Test;
+    }
 
-import nl.jqno.equalsverifier.EqualsVerifier;
+    private static final Group GROUP = new EventCollectorGroup();
 
-class InsertionIdTest {
-    private static final UUID UUID_1 = UUID.fromString("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
+    private final ConcurrentLinkedDeque<Event> events = new ConcurrentLinkedDeque<>();
 
-    @Test
-    void eventIdShouldMatchBeanContract() {
-        EqualsVerifier.forClass(EventDeadLetters.InsertionId.class).verify();
+    @Override
+    public Group getDefaultGroup() {
+        return GROUP;
     }
 
-    @Test
-    void ofShouldDeserializeUUIDs() {
-        assertThat(EventDeadLetters.InsertionId.of(UUID_1.toString()))
-            .isEqualTo(EventDeadLetters.InsertionId.of(UUID_1));
+    public Collection<Event> getEvents() {
+        return events;
     }
 
-    @Test
-    void ofStringShouldThrowOnNullValue() {
-        assertThatThrownBy(() -> EventDeadLetters.InsertionId.of((String) null))
-            .isInstanceOf(NullPointerException.class);
+    @Override
+    public boolean isHandling(Event event) {
+        return true;
     }
 
-    @Test
-    void ofUuidShouldThrowOnNullValue() {
-        assertThatThrownBy(() -> EventDeadLetters.InsertionId.of((UUID) null))
-            .isInstanceOf(NullPointerException.class);
+    @Override
+    public void event(Event event) {
+        events.add(event);
     }
+
 }
diff --git a/mailbox/api/src/test/java/org/apache/james/events/EventDeadLettersContract.java b/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersContract.java
similarity index 99%
rename from mailbox/api/src/test/java/org/apache/james/events/EventDeadLettersContract.java
rename to event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersContract.java
index c8f158c..88b674d 100644
--- a/mailbox/api/src/test/java/org/apache/james/events/EventDeadLettersContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersContract.java
@@ -31,8 +31,8 @@ import java.util.stream.IntStream;
 import java.util.stream.Stream;
 
 import org.apache.james.core.Username;
-import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.events.MailboxEvents.MailboxAdded;
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.TestId;
diff --git a/mailbox/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java b/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java
similarity index 100%
rename from mailbox/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java
rename to event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java
index 6e4dc63..7a0b5d5 100644
--- a/mailbox/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java
@@ -24,8 +24,8 @@ import static org.assertj.core.api.Assertions.assertThat;
 import org.apache.james.core.Username;
 import org.apache.james.core.healthcheck.ComponentName;
 import org.apache.james.core.healthcheck.Result;
-import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.events.MailboxEvents.MailboxAdded;
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.TestId;
diff --git a/mailbox/api/src/test/java/org/apache/james/events/GroupContract.java b/event-bus/api/src/test/java/org/apache/james/events/GroupContract.java
similarity index 100%
rename from mailbox/api/src/test/java/org/apache/james/events/GroupContract.java
rename to event-bus/api/src/test/java/org/apache/james/events/GroupContract.java
index 648b6e2..dc97bfb 100644
--- a/mailbox/api/src/test/java/org/apache/james/events/GroupContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/GroupContract.java
@@ -38,8 +38,8 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.IntStream;
 
 import org.apache.james.core.Username;
-import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.events.MailboxEvents.Added;
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.events.EventBusTestFixture.TestEvent;
diff --git a/mailbox/api/src/test/java/org/apache/james/events/GroupTest.java b/event-bus/api/src/test/java/org/apache/james/events/GroupTest.java
similarity index 96%
rename from mailbox/api/src/test/java/org/apache/james/events/GroupTest.java
rename to event-bus/api/src/test/java/org/apache/james/events/GroupTest.java
index 1b02148..5326e3f 100644
--- a/mailbox/api/src/test/java/org/apache/james/events/GroupTest.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/GroupTest.java
@@ -76,7 +76,7 @@ class GroupTest {
 
     @Test
     void asStringShouldReturnFqdnByDefault() {
-        assertThat(new EventBusTestFixture.GroupA().asString()).isEqualTo("org.apache.james.mailbox.events.EventBusTestFixture$GroupA");
+        assertThat(new EventBusTestFixture.GroupA().asString()).isEqualTo("org.apache.james.events.EventBusTestFixture$GroupA");
     }
 
     @Test
@@ -98,7 +98,7 @@ class GroupTest {
 
     @Test
     void deserializeShouldReturnGroupWhenExtendsGroup() throws Exception {
-        assertThat(Group.deserialize("org.apache.james.mailbox.events.EventBusTestFixture$GroupA"))
+        assertThat(Group.deserialize("org.apache.james.events.EventBusTestFixture$GroupA"))
             .isEqualTo(new EventBusTestFixture.GroupA());
     }
 
diff --git a/mailbox/api/src/test/java/org/apache/james/events/InsertionIdTest.java b/event-bus/api/src/test/java/org/apache/james/events/InsertionIdTest.java
similarity index 97%
rename from mailbox/api/src/test/java/org/apache/james/events/InsertionIdTest.java
rename to event-bus/api/src/test/java/org/apache/james/events/InsertionIdTest.java
index d592590..bcc5a61 100644
--- a/mailbox/api/src/test/java/org/apache/james/events/InsertionIdTest.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/InsertionIdTest.java
@@ -24,7 +24,6 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.util.UUID;
 
-import org.apache.james.events.EventDeadLetters;
 import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
diff --git a/mailbox/api/src/test/java/org/apache/james/events/KeyContract.java b/event-bus/api/src/test/java/org/apache/james/events/KeyContract.java
similarity index 100%
rename from mailbox/api/src/test/java/org/apache/james/events/KeyContract.java
rename to event-bus/api/src/test/java/org/apache/james/events/KeyContract.java
index 9eb4819..6b2ae6b 100644
--- a/mailbox/api/src/test/java/org/apache/james/events/KeyContract.java
+++ b/event-bus/api/src/test/java/org/apache/james/events/KeyContract.java
@@ -40,8 +40,8 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.IntStream;
 
 import org.apache.james.core.Username;
-import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.events.MailboxEvents.Added;
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.TestId;
 import org.junit.jupiter.api.Test;
diff --git a/mailbox/api/src/test/java/org/apache/james/events/RetryBackoffConfigurationTest.java b/event-bus/api/src/test/java/org/apache/james/events/RetryBackoffConfigurationTest.java
similarity index 100%
rename from mailbox/api/src/test/java/org/apache/james/events/RetryBackoffConfigurationTest.java
rename to event-bus/api/src/test/java/org/apache/james/events/RetryBackoffConfigurationTest.java
diff --git a/event-bus/cassandra/pom.xml b/event-bus/cassandra/pom.xml
index 12763a8..6982714 100644
--- a/event-bus/cassandra/pom.xml
+++ b/event-bus/cassandra/pom.xml
@@ -67,6 +67,16 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.testcontainers</groupId>
             <artifactId>testcontainers</artifactId>
             <scope>test</scope>
diff --git a/event-bus/distributed/pom.xml b/event-bus/distributed/pom.xml
index 9bd7f5c..be6d2a1 100644
--- a/event-bus/distributed/pom.xml
+++ b/event-bus/distributed/pom.xml
@@ -82,6 +82,16 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-in-vm</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/event-bus/in-vm/pom.xml b/event-bus/in-vm/pom.xml
index a0a178c..69208ba 100644
--- a/event-bus/in-vm/pom.xml
+++ b/event-bus/in-vm/pom.xml
@@ -53,6 +53,16 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>james-server-util</artifactId>
         </dependency>
diff --git a/mailbox/maildir/pom.xml b/mailbox/maildir/pom.xml
index 562dcca..f42b5e8 100644
--- a/mailbox/maildir/pom.xml
+++ b/mailbox/maildir/pom.xml
@@ -48,6 +48,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-in-vm</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/pom.xml b/pom.xml
index 146ba5a..dd59b37 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1156,6 +1156,12 @@
             </dependency>
             <dependency>
                 <groupId>${james.groupId}</groupId>
+                <artifactId>event-bus-api</artifactId>
+                <type>test-jar</type>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${james.groupId}</groupId>
                 <artifactId>event-bus-distributed</artifactId>
                 <version>${project.version}</version>
             </dependency>
diff --git a/protocols/imap/pom.xml b/protocols/imap/pom.xml
index 4d44ce1..91bd67c 100644
--- a/protocols/imap/pom.xml
+++ b/protocols/imap/pom.xml
@@ -50,6 +50,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-server-util</artifactId>
         </dependency>
         <dependency>


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


[james-project] 03/18: JAMES-3498 Move as is the Distributed implementation

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 4bc40387ed257212f026abc24ab52afa917488dd
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 25 13:54:40 2021 +0700

    JAMES-3498 Move as is the Distributed implementation
---
 event-bus/distributed/pom.xml                      |  86 +++++++++++++++
 .../java/org/apache/james/events/EventBusId.java   |   0
 .../org/apache/james/events/EventDispatcher.java   |   0
 .../apache/james/events/GroupConsumerRetry.java    |   0
 .../org/apache/james/events/GroupRegistration.java |   0
 .../james/events/GroupRegistrationHandler.java     |   0
 .../james/events/KeyReconnectionHandler.java       |   0
 .../org/apache/james/events/KeyRegistration.java   |   2 -
 .../james/events/KeyRegistrationHandler.java       |   0
 .../apache/james/events/LocalListenerRegistry.java |   3 -
 .../james/events/MailboxListenerExecutor.java      |   3 -
 .../org/apache/james/events/RabbitMQEventBus.java  |   0
 .../apache/james/events/RegistrationBinder.java    |   0
 .../apache/james/events/RegistrationQueueName.java |   0
 .../apache/james/events/RoutingKeyConverter.java   |   0
 .../apache/james/events/WaitDelayGenerator.java    |   0
 .../org/apache/james/events/EventBusIdTest.java    |   0
 .../james/events/LocalListenerRegistryTest.java    |   0
 .../org/apache/james/events/NetworkErrorTest.java  |   0
 ...RabbitMQEventBusDeadLetterQueueUpgradeTest.java |   0
 .../apache/james/events/RabbitMQEventBusTest.java  |  10 +-
 .../james/events/RoutingKeyConverterTest.java      |   0
 .../james/events/WaitDelayGeneratorTest.java       |   0
 mailbox/event/event-rabbitmq/pom.xml               | 120 ---------------------
 mailbox/pom.xml                                    |   1 -
 mpt/impl/imap-mailbox/rabbitmq/pom.xml             |  10 +-
 pom.xml                                            |  10 +-
 .../guice/cassandra-rabbitmq-guice/pom.xml         |   8 +-
 28 files changed, 105 insertions(+), 148 deletions(-)

diff --git a/event-bus/distributed/pom.xml b/event-bus/distributed/pom.xml
index a202f2c..9bd7f5c 100644
--- a/event-bus/distributed/pom.xml
+++ b/event-bus/distributed/pom.xml
@@ -31,4 +31,90 @@
     <name>Apache James :: Event Bus :: Distributed</name>
     <description>Distributed implementation for the eventBus</description>
 
+    <dependencies>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>apache-james-mailbox-store</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-lifecycle-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-testing</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>metrics-tests</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>testing-base</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-backends-rabbitmq</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-backends-rabbitmq</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-event-json</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-in-vm</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>metrics-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.projectreactor</groupId>
+            <artifactId>reactor-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.projectreactor.rabbitmq</groupId>
+            <artifactId>reactor-rabbitmq</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>testcontainers</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
 </project>
\ No newline at end of file
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/EventBusId.java b/event-bus/distributed/src/main/java/org/apache/james/events/EventBusId.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/EventBusId.java
rename to event-bus/distributed/src/main/java/org/apache/james/events/EventBusId.java
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/EventDispatcher.java b/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/EventDispatcher.java
rename to event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/GroupConsumerRetry.java b/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/GroupConsumerRetry.java
rename to event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/GroupRegistration.java b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/GroupRegistration.java
rename to event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/GroupRegistrationHandler.java b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
rename to event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/KeyReconnectionHandler.java b/event-bus/distributed/src/main/java/org/apache/james/events/KeyReconnectionHandler.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/KeyReconnectionHandler.java
rename to event-bus/distributed/src/main/java/org/apache/james/events/KeyReconnectionHandler.java
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/KeyRegistration.java b/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistration.java
similarity index 96%
rename from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/KeyRegistration.java
rename to event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistration.java
index b7d6c28..53e79b0 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/KeyRegistration.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistration.java
@@ -19,8 +19,6 @@
 
 package org.apache.james.events;
 
-import org.apache.james.events.Registration;
-
 class KeyRegistration implements Registration {
     private final Runnable unregister;
 
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/KeyRegistrationHandler.java b/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
rename to event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/LocalListenerRegistry.java b/event-bus/distributed/src/main/java/org/apache/james/events/LocalListenerRegistry.java
similarity index 98%
rename from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/LocalListenerRegistry.java
rename to event-bus/distributed/src/main/java/org/apache/james/events/LocalListenerRegistry.java
index 05306ae..f4e5537 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/LocalListenerRegistry.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/LocalListenerRegistry.java
@@ -26,9 +26,6 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Supplier;
 
-import org.apache.james.events.EventListener;
-import org.apache.james.events.RegistrationKey;
-
 import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableSet;
 
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/MailboxListenerExecutor.java b/event-bus/distributed/src/main/java/org/apache/james/events/MailboxListenerExecutor.java
similarity index 95%
rename from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/MailboxListenerExecutor.java
rename to event-bus/distributed/src/main/java/org/apache/james/events/MailboxListenerExecutor.java
index 7b6afef..e74e6ec 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/MailboxListenerExecutor.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/MailboxListenerExecutor.java
@@ -21,9 +21,6 @@ package org.apache.james.events;
 
 import static org.apache.james.events.EventBus.Metrics.timerName;
 
-import org.apache.james.events.Event;
-import org.apache.james.events.EventBus;
-import org.apache.james.events.EventListener;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.util.MDCBuilder;
 import org.apache.james.util.ReactorUtils;
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RabbitMQEventBus.java b/event-bus/distributed/src/main/java/org/apache/james/events/RabbitMQEventBus.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RabbitMQEventBus.java
rename to event-bus/distributed/src/main/java/org/apache/james/events/RabbitMQEventBus.java
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RegistrationBinder.java b/event-bus/distributed/src/main/java/org/apache/james/events/RegistrationBinder.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RegistrationBinder.java
rename to event-bus/distributed/src/main/java/org/apache/james/events/RegistrationBinder.java
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RegistrationQueueName.java b/event-bus/distributed/src/main/java/org/apache/james/events/RegistrationQueueName.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RegistrationQueueName.java
rename to event-bus/distributed/src/main/java/org/apache/james/events/RegistrationQueueName.java
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RoutingKeyConverter.java b/event-bus/distributed/src/main/java/org/apache/james/events/RoutingKeyConverter.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RoutingKeyConverter.java
rename to event-bus/distributed/src/main/java/org/apache/james/events/RoutingKeyConverter.java
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/WaitDelayGenerator.java b/event-bus/distributed/src/main/java/org/apache/james/events/WaitDelayGenerator.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/WaitDelayGenerator.java
rename to event-bus/distributed/src/main/java/org/apache/james/events/WaitDelayGenerator.java
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/EventBusIdTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/EventBusIdTest.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/EventBusIdTest.java
rename to event-bus/distributed/src/test/java/org/apache/james/events/EventBusIdTest.java
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/LocalListenerRegistryTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/LocalListenerRegistryTest.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/LocalListenerRegistryTest.java
rename to event-bus/distributed/src/test/java/org/apache/james/events/LocalListenerRegistryTest.java
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/NetworkErrorTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/NetworkErrorTest.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/NetworkErrorTest.java
rename to event-bus/distributed/src/test/java/org/apache/james/events/NetworkErrorTest.java
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
rename to event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
similarity index 98%
rename from mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
rename to event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
index 47e84be..6313fc6 100644
--- a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
+++ b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
@@ -185,7 +185,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
     @Test
     void eventProcessingShouldNotCrashOnInvalidMessage() {
         EventCollector listener = new EventCollector();
-        EventBusTestFixture.GroupA registeredGroup = new EventBusTestFixture.GroupA();
+        GroupA registeredGroup = new GroupA();
         eventBus.register(listener, registeredGroup);
 
         String emptyRoutingKey = "";
@@ -204,7 +204,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
     @Test
     void eventProcessingShouldNotCrashOnInvalidMessages() {
         EventCollector listener = new EventCollector();
-        EventBusTestFixture.GroupA registeredGroup = new EventBusTestFixture.GroupA();
+        GroupA registeredGroup = new GroupA();
         eventBus.register(listener, registeredGroup);
 
         String emptyRoutingKey = "";
@@ -223,7 +223,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
     @Test
     void eventProcessingShouldStoreInvalidMessagesInDeadLetterQueue() {
         EventCollector listener = new EventCollector();
-        EventBusTestFixture.GroupA registeredGroup = new EventBusTestFixture.GroupA();
+        GroupA registeredGroup = new GroupA();
         eventBus.register(listener, registeredGroup);
 
         String emptyRoutingKey = "";
@@ -287,7 +287,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
     @Test
     void registerGroupShouldCreateRetryExchange() throws Exception {
         EventListener listener = newListener();
-        EventBusTestFixture.GroupA registeredGroup = new EventBusTestFixture.GroupA();
+        GroupA registeredGroup = new GroupA();
         eventBus.register(listener, registeredGroup);
 
         GroupConsumerRetry.RetryExchangeName retryExchangeName = GroupConsumerRetry.RetryExchangeName.of(registeredGroup);
@@ -307,7 +307,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
         @Test
         void rabbitMQEventBusShouldHandleBulksGracefully() throws Exception {
             EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            eventBus().register(countingListener1, new EventBusTestFixture.GroupA());
+            eventBus().register(countingListener1, new GroupA());
             int totalGlobalRegistrations = 1; // GroupA
 
             int threadCount = 10;
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/RoutingKeyConverterTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/RoutingKeyConverterTest.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/RoutingKeyConverterTest.java
rename to event-bus/distributed/src/test/java/org/apache/james/events/RoutingKeyConverterTest.java
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/WaitDelayGeneratorTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/WaitDelayGeneratorTest.java
similarity index 100%
rename from mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/WaitDelayGeneratorTest.java
rename to event-bus/distributed/src/test/java/org/apache/james/events/WaitDelayGeneratorTest.java
diff --git a/mailbox/event/event-rabbitmq/pom.xml b/mailbox/event/event-rabbitmq/pom.xml
deleted file mode 100644
index cdb79b3..0000000
--- a/mailbox/event/event-rabbitmq/pom.xml
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-    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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.james</groupId>
-        <artifactId>apache-james-mailbox</artifactId>
-        <version>3.6.0-SNAPSHOT</version>
-        <relativePath>../../pom.xml</relativePath>
-    </parent>
-
-    <artifactId>apache-james-mailbox-event-rabbitmq</artifactId>
-    <name>Apache James :: Mailbox :: Event :: RabbitMQ implementation</name>
-    <description>RabbitMQ implementation for the eventbus API</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
-            <artifactId>apache-james-mailbox-store</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
-            <artifactId>james-server-lifecycle-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
-            <artifactId>james-server-testing</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
-            <artifactId>metrics-tests</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
-            <artifactId>testing-base</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-backends-rabbitmq</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-backends-rabbitmq</artifactId>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-mailbox-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-mailbox-api</artifactId>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-mailbox-event-json</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
-            <artifactId>event-bus-in-vm</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>metrics-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.projectreactor</groupId>
-            <artifactId>reactor-core</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.projectreactor.rabbitmq</groupId>
-            <artifactId>reactor-rabbitmq</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-pool2</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.awaitility</groupId>
-            <artifactId>awaitility</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.mockito</groupId>
-            <artifactId>mockito-core</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.testcontainers</groupId>
-            <artifactId>testcontainers</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-</project>
diff --git a/mailbox/pom.xml b/mailbox/pom.xml
index 14e92aa..f5bb377 100644
--- a/mailbox/pom.xml
+++ b/mailbox/pom.xml
@@ -41,7 +41,6 @@
         <module>elasticsearch</module>
 
         <module>event/event-cassandra</module>
-        <module>event/event-rabbitmq</module>
         <module>event/json</module>
 
         <module>jpa</module>
diff --git a/mpt/impl/imap-mailbox/rabbitmq/pom.xml b/mpt/impl/imap-mailbox/rabbitmq/pom.xml
index 533c221..e2332fd 100644
--- a/mpt/impl/imap-mailbox/rabbitmq/pom.xml
+++ b/mpt/impl/imap-mailbox/rabbitmq/pom.xml
@@ -44,11 +44,6 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>apache-james-mailbox-event-rabbitmq</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
             <artifactId>apache-james-mailbox-memory</artifactId>
             <scope>test</scope>
         </dependency>
@@ -64,6 +59,11 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-distributed</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-server-testing</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/pom.xml b/pom.xml
index 203d59d..5245d5e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -770,11 +770,6 @@
             </dependency>
             <dependency>
                 <groupId>${james.groupId}</groupId>
-                <artifactId>apache-james-mailbox-event-rabbitmq</artifactId>
-                <version>${project.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>${james.groupId}</groupId>
                 <artifactId>apache-james-mailbox-jpa</artifactId>
                 <version>${project.version}</version>
             </dependency>
@@ -1161,6 +1156,11 @@
             </dependency>
             <dependency>
                 <groupId>${james.groupId}</groupId>
+                <artifactId>event-bus-distributed</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${james.groupId}</groupId>
                 <artifactId>event-bus-in-vm</artifactId>
                 <version>${project.version}</version>
             </dependency>
diff --git a/server/container/guice/cassandra-rabbitmq-guice/pom.xml b/server/container/guice/cassandra-rabbitmq-guice/pom.xml
index a75b05e..beffba1 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/pom.xml
+++ b/server/container/guice/cassandra-rabbitmq-guice/pom.xml
@@ -71,10 +71,6 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>apache-james-mailbox-event-rabbitmq</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
             <artifactId>apache-james-mailbox-tika</artifactId>
             <type>test-jar</type>
             <scope>test</scope>
@@ -101,6 +97,10 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-distributed</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-sourcing-event-store-cassandra</artifactId>
             <type>test-jar</type>
             <scope>test</scope>


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


[james-project] 06/18: JAMES-3498 Introduce an EventSerializer API

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 48c939e28dcb44f424e5f1753de1d00b9e8dc0c6
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 25 14:37:25 2021 +0700

    JAMES-3498 Introduce an EventSerializer API
---
 .../org/apache/james/events/EventSerializer.java   | 15 ++++-----------
 .../james/events/CassandraEventDeadLettersDAO.java | 22 ++++++++++------------
 .../events/CassandraEventDeadLettersDAOTest.java   |  4 ++--
 .../CassandraEventDeadLettersHealthCheckTest.java  |  4 ++--
 .../events/CassandraEventDeadLettersTest.java      |  4 ++--
 .../org/apache/james/events/EventDispatcher.java   |  1 -
 .../apache/james/events/GroupConsumerRetry.java    |  1 -
 .../org/apache/james/events/GroupRegistration.java |  3 +--
 .../james/events/GroupRegistrationHandler.java     |  1 -
 .../james/events/KeyRegistrationHandler.java       |  3 +--
 .../org/apache/james/events/RabbitMQEventBus.java  |  1 -
 .../org/apache/james/events/NetworkErrorTest.java  |  4 ++--
 ...RabbitMQEventBusDeadLetterQueueUpgradeTest.java |  4 ++--
 .../apache/james/events/RabbitMQEventBusTest.java  |  7 +++----
 mailbox/event/json/pom.xml                         |  4 ++++
 ...rializer.scala => MailboxEventSerializer.scala} | 13 ++++++++-----
 .../apache/james/event/json/SerializerFixture.java |  2 +-
 .../rabbitmq/host/RabbitMQEventBusHostSystem.java  |  4 ++--
 .../modules/event/RabbitMQEventBusModule.java      |  6 ++++--
 .../james/modules/mailbox/DefaultEventModule.java  |  5 +++++
 .../webadmin/routes/EventDeadLettersRoutes.java    |  2 +-
 .../routes/EventDeadLettersRoutesTest.java         |  4 ++--
 22 files changed, 56 insertions(+), 58 deletions(-)

diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/SerializerFixture.java b/event-bus/api/src/main/java/org/apache/james/events/EventSerializer.java
similarity index 60%
copy from mailbox/event/json/src/test/java/org/apache/james/event/json/SerializerFixture.java
copy to event-bus/api/src/main/java/org/apache/james/events/EventSerializer.java
index a9e6deb..0016959 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/SerializerFixture.java
+++ b/event-bus/api/src/main/java/org/apache/james/events/EventSerializer.java
@@ -17,17 +17,10 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.event.json;
+package org.apache.james.events;
 
-import org.apache.james.events.Event;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.mailbox.model.TestMessageId;
-import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
+public interface EventSerializer {
+    String toJson(Event event);
 
-public interface SerializerFixture {
-    JsonSerialize DTO_JSON_SERIALIZE = new JsonSerialize(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
-    EventSerializer EVENT_SERIALIZER = new EventSerializer(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
-
-    String SERIALIZED_EVENT_ID = "6e0dd59d-660e-4d9b-b22f-0354479f47b4";
-    Event.EventId EVENT_ID = Event.EventId.of(SERIALIZED_EVENT_ID);
+    Event asEvent(String serialized);
 }
diff --git a/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java b/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java
index 4bfbd32..df1f339 100644
--- a/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java
+++ b/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java
@@ -28,12 +28,10 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
 import javax.inject.Inject;
 
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
-import org.apache.james.event.json.EventSerializer;
 import org.apache.james.events.tables.CassandraEventDeadLettersTable;
 
 import com.datastax.driver.core.PreparedStatement;
 import com.datastax.driver.core.Session;
-import com.datastax.driver.core.querybuilder.QueryBuilder;
 
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
@@ -59,7 +57,7 @@ public class CassandraEventDeadLettersDAO {
     }
 
     private PreparedStatement prepareInsertStatement(Session session) {
-        return session.prepare(QueryBuilder.insertInto(CassandraEventDeadLettersTable.TABLE_NAME)
+        return session.prepare(insertInto(CassandraEventDeadLettersTable.TABLE_NAME)
             .value(CassandraEventDeadLettersTable.GROUP, bindMarker(CassandraEventDeadLettersTable.GROUP))
             .value(CassandraEventDeadLettersTable.INSERTION_ID, bindMarker(CassandraEventDeadLettersTable.INSERTION_ID))
             .value(CassandraEventDeadLettersTable.EVENT, bindMarker(CassandraEventDeadLettersTable.EVENT)));
@@ -68,25 +66,25 @@ public class CassandraEventDeadLettersDAO {
     private PreparedStatement prepareDeleteStatement(Session session) {
         return session.prepare(delete()
             .from(CassandraEventDeadLettersTable.TABLE_NAME)
-            .where(QueryBuilder.eq(CassandraEventDeadLettersTable.GROUP, bindMarker(CassandraEventDeadLettersTable.GROUP)))
-            .and(QueryBuilder.eq(CassandraEventDeadLettersTable.INSERTION_ID, bindMarker(CassandraEventDeadLettersTable.INSERTION_ID))));
+            .where(eq(CassandraEventDeadLettersTable.GROUP, bindMarker(CassandraEventDeadLettersTable.GROUP)))
+            .and(eq(CassandraEventDeadLettersTable.INSERTION_ID, bindMarker(CassandraEventDeadLettersTable.INSERTION_ID))));
     }
 
     private PreparedStatement prepareSelectEventStatement(Session session) {
-        return session.prepare(QueryBuilder.select(CassandraEventDeadLettersTable.EVENT)
+        return session.prepare(select(CassandraEventDeadLettersTable.EVENT)
             .from(CassandraEventDeadLettersTable.TABLE_NAME)
-            .where(QueryBuilder.eq(CassandraEventDeadLettersTable.GROUP, bindMarker(CassandraEventDeadLettersTable.GROUP)))
-            .and(QueryBuilder.eq(CassandraEventDeadLettersTable.INSERTION_ID, bindMarker(CassandraEventDeadLettersTable.INSERTION_ID))));
+            .where(eq(CassandraEventDeadLettersTable.GROUP, bindMarker(CassandraEventDeadLettersTable.GROUP)))
+            .and(eq(CassandraEventDeadLettersTable.INSERTION_ID, bindMarker(CassandraEventDeadLettersTable.INSERTION_ID))));
     }
 
     private PreparedStatement prepareSelectInsertionIdsWithGroupStatement(Session session) {
-        return session.prepare(QueryBuilder.select(CassandraEventDeadLettersTable.INSERTION_ID)
+        return session.prepare(select(CassandraEventDeadLettersTable.INSERTION_ID)
             .from(CassandraEventDeadLettersTable.TABLE_NAME)
-            .where(QueryBuilder.eq(CassandraEventDeadLettersTable.GROUP, bindMarker(CassandraEventDeadLettersTable.GROUP))));
+            .where(eq(CassandraEventDeadLettersTable.GROUP, bindMarker(CassandraEventDeadLettersTable.GROUP))));
     }
 
     private PreparedStatement prepareContainEventStatement(Session session) {
-        return session.prepare(QueryBuilder.select(CassandraEventDeadLettersTable.EVENT)
+        return session.prepare(select(CassandraEventDeadLettersTable.EVENT)
             .from(CassandraEventDeadLettersTable.TABLE_NAME)
             .limit(1));
     }
@@ -122,6 +120,6 @@ public class CassandraEventDeadLettersDAO {
     }
 
     private Event deserializeEvent(String serializedEvent) {
-        return eventSerializer.fromJson(serializedEvent).get();
+        return eventSerializer.asEvent(serializedEvent);
     }
 }
diff --git a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java
index d6ba016..18fd9a6 100644
--- a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java
+++ b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java
@@ -23,7 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
-import org.apache.james.event.json.EventSerializer;
+import org.apache.james.event.json.MailboxEventSerializer;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
@@ -40,7 +40,7 @@ class CassandraEventDeadLettersDAOTest {
 
     @BeforeEach
     void setUp(CassandraCluster cassandraCluster) {
-        EventSerializer eventSerializer = new EventSerializer(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
+        MailboxEventSerializer eventSerializer = new MailboxEventSerializer(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
         cassandraEventDeadLettersDAO = new CassandraEventDeadLettersDAO(cassandraCluster.getConf(), eventSerializer);
     }
 
diff --git a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java
index dce43af..dc2e218 100644
--- a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java
+++ b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java
@@ -22,7 +22,7 @@ package org.apache.james.events;
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
 import org.apache.james.backends.cassandra.DockerCassandra;
-import org.apache.james.event.json.EventSerializer;
+import org.apache.james.event.json.MailboxEventSerializer;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
@@ -39,7 +39,7 @@ class CassandraEventDeadLettersHealthCheckTest implements EventDeadLettersHealth
 
     @BeforeEach
     void setUp(CassandraCluster cassandraCluster, DockerCassandra dockerCassandra) {
-        EventSerializer eventSerializer = new EventSerializer(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
+        MailboxEventSerializer eventSerializer = new MailboxEventSerializer(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
         eventDeadLetters = new CassandraEventDeadLetters(new CassandraEventDeadLettersDAO(cassandraCluster.getConf(), eventSerializer),
                                                          new CassandraEventDeadLettersGroupDAO(cassandraCluster.getConf()));
         testee = new EventDeadLettersHealthCheck(eventDeadLetters);
diff --git a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersTest.java b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersTest.java
index 2e3b85c..8b0dd15 100644
--- a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersTest.java
+++ b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersTest.java
@@ -21,7 +21,7 @@ package org.apache.james.events;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
-import org.apache.james.event.json.EventSerializer;
+import org.apache.james.event.json.MailboxEventSerializer;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
@@ -37,7 +37,7 @@ class CassandraEventDeadLettersTest implements EventDeadLettersContract.AllContr
 
     @BeforeEach
     void setUp(CassandraCluster cassandraCluster) {
-        EventSerializer eventSerializer = new EventSerializer(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
+        MailboxEventSerializer eventSerializer = new MailboxEventSerializer(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
         eventDeadLetters = new CassandraEventDeadLetters(new CassandraEventDeadLettersDAO(cassandraCluster.getConf(), eventSerializer),
                                                          new CassandraEventDeadLettersGroupDAO(cassandraCluster.getConf()));
     }
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java b/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
index 99d0a7d..9543179 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
@@ -36,7 +36,6 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Set;
 
-import org.apache.james.event.json.EventSerializer;
 import org.apache.james.events.RoutingKeyConverter.RoutingKey;
 import org.apache.james.util.MDCBuilder;
 import org.apache.james.util.MDCStructuredLogger;
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java b/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
index b8526f8..10d922a 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
@@ -27,7 +27,6 @@ import static org.apache.james.events.GroupRegistration.RETRY_COUNT;
 
 import java.nio.charset.StandardCharsets;
 
-import org.apache.james.event.json.EventSerializer;
 import org.apache.james.util.MDCStructuredLogger;
 import org.apache.james.util.StructuredLogger;
 import org.slf4j.Logger;
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java
index 5c6285c..ad2b7ad 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java
@@ -33,7 +33,6 @@ import java.util.function.Predicate;
 
 import org.apache.james.backends.rabbitmq.ReactorRabbitMQChannelPool;
 import org.apache.james.backends.rabbitmq.ReceiverProvider;
-import org.apache.james.event.json.EventSerializer;
 import org.apache.james.util.MDCBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -155,7 +154,7 @@ class GroupRegistration implements Registration {
     }
 
     private Mono<Event> deserializeEvent(byte[] eventAsBytes) {
-        return Mono.fromCallable(() -> eventSerializer.fromJson(new String(eventAsBytes, StandardCharsets.UTF_8)).get())
+        return Mono.fromCallable(() -> eventSerializer.asEvent(new String(eventAsBytes, StandardCharsets.UTF_8)))
             .subscribeOn(Schedulers.parallel());
     }
 
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
index c4f7814..8e00eaa 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
@@ -25,7 +25,6 @@ import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.james.backends.rabbitmq.ReactorRabbitMQChannelPool;
 import org.apache.james.backends.rabbitmq.ReceiverProvider;
-import org.apache.james.event.json.EventSerializer;
 
 import reactor.rabbitmq.Sender;
 
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java b/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
index be06184..db1e24b 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
@@ -31,7 +31,6 @@ import java.util.Optional;
 import java.util.function.Predicate;
 
 import org.apache.james.backends.rabbitmq.ReceiverProvider;
-import org.apache.james.event.json.EventSerializer;
 import org.apache.james.util.MDCBuilder;
 import org.apache.james.util.MDCStructuredLogger;
 import org.apache.james.util.StructuredLogger;
@@ -186,7 +185,7 @@ class KeyRegistrationHandler {
     }
 
     private Event toEvent(Delivery delivery) {
-        return eventSerializer.fromJson(new String(delivery.getBody(), StandardCharsets.UTF_8)).get();
+        return eventSerializer.asEvent(new String(delivery.getBody(), StandardCharsets.UTF_8));
     }
 
     private StructuredLogger structuredLogger(Event event, RegistrationKey key) {
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/RabbitMQEventBus.java b/event-bus/distributed/src/main/java/org/apache/james/events/RabbitMQEventBus.java
index 73a2209..772191b 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/RabbitMQEventBus.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/RabbitMQEventBus.java
@@ -26,7 +26,6 @@ import javax.inject.Inject;
 
 import org.apache.james.backends.rabbitmq.ReactorRabbitMQChannelPool;
 import org.apache.james.backends.rabbitmq.ReceiverProvider;
-import org.apache.james.event.json.EventSerializer;
 import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.metrics.api.MetricFactory;
 
diff --git a/event-bus/distributed/src/test/java/org/apache/james/events/NetworkErrorTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/NetworkErrorTest.java
index 2e9ec01..6584860 100644
--- a/event-bus/distributed/src/test/java/org/apache/james/events/NetworkErrorTest.java
+++ b/event-bus/distributed/src/test/java/org/apache/james/events/NetworkErrorTest.java
@@ -29,7 +29,7 @@ import static org.mockito.Mockito.verify;
 
 import org.apache.james.backends.rabbitmq.RabbitMQExtension;
 import org.apache.james.backends.rabbitmq.RabbitMQFixture;
-import org.apache.james.event.json.EventSerializer;
+import org.apache.james.event.json.MailboxEventSerializer;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
@@ -51,7 +51,7 @@ class NetworkErrorTest {
         MemoryEventDeadLetters memoryEventDeadLetters = new MemoryEventDeadLetters();
 
         TestId.Factory mailboxIdFactory = new TestId.Factory();
-        EventSerializer eventSerializer = new EventSerializer(mailboxIdFactory, new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
+        MailboxEventSerializer eventSerializer = new MailboxEventSerializer(mailboxIdFactory, new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
         RoutingKeyConverter routingKeyConverter = RoutingKeyConverter.forFactories(new MailboxIdRegistrationKey.Factory(mailboxIdFactory));
 
         eventBus = new RabbitMQEventBus(rabbitMQExtension.getSender(), rabbitMQExtension.getReceiverProvider(),
diff --git a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
index a7371d9..4f46d3f 100644
--- a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
+++ b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
@@ -26,7 +26,7 @@ import static org.apache.james.events.EventBusTestFixture.RETRY_BACKOFF_CONFIGUR
 import static org.assertj.core.api.Assertions.assertThatCode;
 
 import org.apache.james.backends.rabbitmq.RabbitMQExtension;
-import org.apache.james.event.json.EventSerializer;
+import org.apache.james.event.json.MailboxEventSerializer;
 import org.apache.james.events.EventBusTestFixture.GroupA;
 import org.apache.james.events.GroupRegistration.WorkQueueName;
 import org.apache.james.mailbox.model.TestId;
@@ -53,7 +53,7 @@ class RabbitMQEventBusDeadLetterQueueUpgradeTest {
         MemoryEventDeadLetters memoryEventDeadLetters = new MemoryEventDeadLetters();
 
         TestId.Factory mailboxIdFactory = new TestId.Factory();
-        EventSerializer eventSerializer = new EventSerializer(mailboxIdFactory, new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
+        MailboxEventSerializer eventSerializer = new MailboxEventSerializer(mailboxIdFactory, new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
         RoutingKeyConverter routingKeyConverter = RoutingKeyConverter.forFactories(new MailboxIdRegistrationKey.Factory(mailboxIdFactory));
 
         eventBus = new RabbitMQEventBus(rabbitMQExtension.getSender(), rabbitMQExtension.getReceiverProvider(),
diff --git a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
index 6313fc6..fb0e353 100644
--- a/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
+++ b/event-bus/distributed/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
@@ -63,7 +63,7 @@ import org.apache.james.backends.rabbitmq.RabbitMQExtension.DockerRestartPolicy;
 import org.apache.james.backends.rabbitmq.RabbitMQFixture;
 import org.apache.james.backends.rabbitmq.RabbitMQManagementAPI;
 import org.apache.james.backends.rabbitmq.ReceiverProvider;
-import org.apache.james.event.json.EventSerializer;
+import org.apache.james.event.json.MailboxEventSerializer;
 import org.apache.james.events.EventBusTestFixture.EventListenerCountingSuccessfulExecution;
 import org.apache.james.events.EventBusTestFixture.GroupA;
 import org.apache.james.events.EventDispatcher.DispatchingFailureGroup;
@@ -71,7 +71,6 @@ import org.apache.james.events.RoutingKeyConverter.RoutingKey;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
-import org.apache.james.mailbox.util.EventCollector;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
 import org.apache.james.util.concurrency.ConcurrentTestRunner;
 import org.assertj.core.data.Percentage;
@@ -107,7 +106,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
     private RabbitMQEventBus eventBus2;
     private RabbitMQEventBus eventBus3;
     private RabbitMQEventBus eventBusWithKeyHandlerNotStarted;
-    private EventSerializer eventSerializer;
+    private MailboxEventSerializer eventSerializer;
     private RoutingKeyConverter routingKeyConverter;
     private MemoryEventDeadLetters memoryEventDeadLetters;
 
@@ -121,7 +120,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
         memoryEventDeadLetters = new MemoryEventDeadLetters();
 
         TestId.Factory mailboxIdFactory = new TestId.Factory();
-        eventSerializer = new EventSerializer(mailboxIdFactory, new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
+        eventSerializer = new MailboxEventSerializer(mailboxIdFactory, new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
         routingKeyConverter = RoutingKeyConverter.forFactories(new MailboxIdRegistrationKey.Factory(mailboxIdFactory));
 
         eventBus = newEventBus();
diff --git a/mailbox/event/json/pom.xml b/mailbox/event/json/pom.xml
index 9ef6bbb..f0bd272 100644
--- a/mailbox/event/json/pom.xml
+++ b/mailbox/event/json/pom.xml
@@ -53,6 +53,10 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.beachape</groupId>
             <artifactId>enumeratum_${scala.base}</artifactId>
             <version>1.5.13</version>
diff --git a/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala b/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala
similarity index 96%
rename from mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala
rename to mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala
index 6708055..4a97b73 100644
--- a/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala
+++ b/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala
@@ -31,7 +31,7 @@ import org.apache.james.event.json.DTOs._
 import org.apache.james.events
 import org.apache.james.events.Event.EventId
 import org.apache.james.events.MailboxEvents.{Added => JavaAdded, Expunged => JavaExpunged, FlagsUpdated => JavaFlagsUpdated, MailboxACLUpdated => JavaMailboxACLUpdated, MailboxAdded => JavaMailboxAdded, MailboxDeletion => JavaMailboxDeletion, MailboxRenamed => JavaMailboxRenamed, QuotaUsageUpdatedEvent => JavaQuotaUsageUpdatedEvent}
-import org.apache.james.events.MessageMoveEvent
+import org.apache.james.events.{EventSerializer, MessageMoveEvent => JavaMessageMoveEvent}
 import org.apache.james.mailbox.MailboxSession.SessionId
 import org.apache.james.mailbox.model.{MailboxId, MessageId, MessageMoves, QuotaRoot, MailboxACL => JavaMailboxACL, MessageMetaData => JavaMessageMetaData, Quota => JavaQuota}
 import org.apache.james.mailbox.quota.QuotaRootDeserializer
@@ -174,7 +174,7 @@ private object ScalaConverter {
     mailboxId = event.getMailboxId,
     expunged = event.getExpunged.asScala.view.mapValues(DTOs.MessageMetaData.fromJava).toMap)
 
-  private def toScala(event: MessageMoveEvent): DTO.MessageMoveEvent = DTO.MessageMoveEvent(
+  private def toScala(event: JavaMessageMoveEvent): DTO.MessageMoveEvent = DTO.MessageMoveEvent(
     eventId = event.getEventId,
     user = event.getUsername,
     previousMailboxIds = event.getMessageMoves.getPreviousMailboxIds.asScala.toSet,
@@ -197,7 +197,7 @@ private object ScalaConverter {
     case e: JavaMailboxAdded => toScala(e)
     case e: JavaMailboxDeletion => toScala(e)
     case e: JavaMailboxRenamed => toScala(e)
-    case e: MessageMoveEvent => toScala(e)
+    case e: JavaMessageMoveEvent => toScala(e)
     case e: JavaQuotaUsageUpdatedEvent => toScala(e)
     case _ => throw new RuntimeException("no Scala conversion known")
   }
@@ -353,10 +353,13 @@ class JsonSerialize(mailboxIdFactory: MailboxId.Factory, messageIdFactory: Messa
     .map(event => event.toJava)
 }
 
-class EventSerializer @Inject() (mailboxIdFactory: MailboxId.Factory, messageIdFactory: MessageId.Factory, quotaRootDeserializer: QuotaRootDeserializer) {
+class MailboxEventSerializer @Inject()(mailboxIdFactory: MailboxId.Factory, messageIdFactory: MessageId.Factory, quotaRootDeserializer: QuotaRootDeserializer) extends EventSerializer{
   private val jsonSerialize = new JsonSerialize(mailboxIdFactory, messageIdFactory, quotaRootDeserializer)
 
-  def toJson(event: events.Event): String = jsonSerialize.toJson(event)
+  override def toJson(event: events.Event): String = jsonSerialize.toJson(event)
+
   def fromJson(json: String): JsResult[events.Event] = jsonSerialize.fromJson(json)
+
+  override def asEvent(serialized: String): events.Event = fromJson(serialized).get
 }
 
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/SerializerFixture.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/SerializerFixture.java
index a9e6deb..300549f 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/SerializerFixture.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/SerializerFixture.java
@@ -26,7 +26,7 @@ import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
 
 public interface SerializerFixture {
     JsonSerialize DTO_JSON_SERIALIZE = new JsonSerialize(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
-    EventSerializer EVENT_SERIALIZER = new EventSerializer(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
+    MailboxEventSerializer EVENT_SERIALIZER = new MailboxEventSerializer(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
 
     String SERIALIZED_EVENT_ID = "6e0dd59d-660e-4d9b-b22f-0354479f47b4";
     Event.EventId EVENT_ID = Event.EventId.of(SERIALIZED_EVENT_ID);
diff --git a/mpt/impl/imap-mailbox/rabbitmq/src/test/java/org/apache/james/mpt/imapmailbox/rabbitmq/host/RabbitMQEventBusHostSystem.java b/mpt/impl/imap-mailbox/rabbitmq/src/test/java/org/apache/james/mpt/imapmailbox/rabbitmq/host/RabbitMQEventBusHostSystem.java
index 7b6d999..7fe9406 100644
--- a/mpt/impl/imap-mailbox/rabbitmq/src/test/java/org/apache/james/mpt/imapmailbox/rabbitmq/host/RabbitMQEventBusHostSystem.java
+++ b/mpt/impl/imap-mailbox/rabbitmq/src/test/java/org/apache/james/mpt/imapmailbox/rabbitmq/host/RabbitMQEventBusHostSystem.java
@@ -30,7 +30,7 @@ import org.apache.james.backends.rabbitmq.ReactorRabbitMQChannelPool;
 import org.apache.james.backends.rabbitmq.SimpleConnectionPool;
 import org.apache.james.core.quota.QuotaCountLimit;
 import org.apache.james.core.quota.QuotaSizeLimit;
-import org.apache.james.event.json.EventSerializer;
+import org.apache.james.event.json.MailboxEventSerializer;
 import org.apache.james.events.EventBusId;
 import org.apache.james.events.MailboxIdRegistrationKey;
 import org.apache.james.events.MemoryEventDeadLetters;
@@ -115,7 +115,7 @@ public class RabbitMQEventBusHostSystem extends JamesImapHostSystem {
     private RabbitMQEventBus createEventBus() {
         InMemoryMessageId.Factory messageIdFactory = new InMemoryMessageId.Factory();
         InMemoryId.Factory mailboxIdFactory = new InMemoryId.Factory();
-        EventSerializer eventSerializer = new EventSerializer(mailboxIdFactory, messageIdFactory, new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
+        MailboxEventSerializer eventSerializer = new MailboxEventSerializer(mailboxIdFactory, messageIdFactory, new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
         RoutingKeyConverter routingKeyConverter = new RoutingKeyConverter(ImmutableSet.of(new MailboxIdRegistrationKey.Factory(mailboxIdFactory)));
         return new RabbitMQEventBus(reactorRabbitMQChannelPool.getSender(), reactorRabbitMQChannelPool::createReceiver,
             eventSerializer, RetryBackoffConfiguration.DEFAULT, routingKeyConverter, new MemoryEventDeadLetters(),
diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java
index b358074..3b83a14 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java
@@ -20,9 +20,10 @@
 package org.apache.james.modules.event;
 
 import org.apache.james.backends.rabbitmq.SimpleConnectionPool;
-import org.apache.james.event.json.EventSerializer;
+import org.apache.james.event.json.MailboxEventSerializer;
 import org.apache.james.events.EventBus;
 import org.apache.james.events.EventBusId;
+import org.apache.james.events.EventSerializer;
 import org.apache.james.events.KeyReconnectionHandler;
 import org.apache.james.events.MailboxIdRegistrationKey;
 import org.apache.james.events.RabbitMQEventBus;
@@ -40,7 +41,8 @@ public class RabbitMQEventBusModule extends AbstractModule {
 
     @Override
     protected void configure() {
-        bind(EventSerializer.class).in(Scopes.SINGLETON);
+        bind(MailboxEventSerializer.class).in(Scopes.SINGLETON);
+        bind(EventSerializer.class).to(MailboxEventSerializer.class);
 
         bind(RabbitMQEventBus.class).in(Scopes.SINGLETON);
         bind(EventBus.class).to(RabbitMQEventBus.class);
diff --git a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultEventModule.java b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultEventModule.java
index 48fd9a1..27a1c47 100644
--- a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultEventModule.java
+++ b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultEventModule.java
@@ -20,8 +20,10 @@
 package org.apache.james.modules.mailbox;
 
 import org.apache.commons.configuration2.ex.ConfigurationException;
+import org.apache.james.event.json.MailboxEventSerializer;
 import org.apache.james.events.EventBus;
 import org.apache.james.events.EventListener;
+import org.apache.james.events.EventSerializer;
 import org.apache.james.events.InVMEventBus;
 import org.apache.james.events.RetryBackoffConfiguration;
 import org.apache.james.events.delivery.EventDelivery;
@@ -42,6 +44,9 @@ import com.google.inject.multibindings.ProvidesIntoSet;
 public class DefaultEventModule extends AbstractModule {
     @Override
     protected void configure() {
+        bind(MailboxEventSerializer.class).in(Scopes.SINGLETON);
+        bind(EventSerializer.class).to(MailboxEventSerializer.class);
+
         bind(MailboxListenerFactory.class).in(Scopes.SINGLETON);
         bind(MailboxListenersLoaderImpl.class).in(Scopes.SINGLETON);
         bind(InVmEventDelivery.class).in(Scopes.SINGLETON);
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/EventDeadLettersRoutes.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/EventDeadLettersRoutes.java
index 2132992..8f9b294 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/EventDeadLettersRoutes.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/EventDeadLettersRoutes.java
@@ -28,9 +28,9 @@ import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 
-import org.apache.james.event.json.EventSerializer;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.EventSerializer;
 import org.apache.james.events.Group;
 import org.apache.james.task.TaskManager;
 import org.apache.james.webadmin.Routes;
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/EventDeadLettersRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/EventDeadLettersRoutesTest.java
index 5c5f757..84366e8 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/EventDeadLettersRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/EventDeadLettersRoutesTest.java
@@ -32,7 +32,7 @@ import static org.hamcrest.Matchers.notNullValue;
 import static org.hamcrest.Matchers.nullValue;
 
 import org.apache.james.core.Username;
-import org.apache.james.event.json.EventSerializer;
+import org.apache.james.event.json.MailboxEventSerializer;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventBus;
 import org.apache.james.events.EventBusTestFixture;
@@ -119,7 +119,7 @@ class EventDeadLettersRoutesTest {
     void beforeEach() {
         deadLetters = new MemoryEventDeadLetters();
         JsonTransformer jsonTransformer = new JsonTransformer();
-        EventSerializer eventSerializer = new EventSerializer(new InMemoryId.Factory(), new InMemoryMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
+        MailboxEventSerializer eventSerializer = new MailboxEventSerializer(new InMemoryId.Factory(), new InMemoryMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
         eventBus = new InVMEventBus(new InVmEventDelivery(new RecordingMetricFactory()), RetryBackoffConfiguration.DEFAULT, deadLetters);
         EventDeadLettersRedeliverService redeliverService = new EventDeadLettersRedeliverService(eventBus, deadLetters);
         EventDeadLettersService service = new EventDeadLettersService(redeliverService, deadLetters);


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


[james-project] 01/18: JAMES-3498 Move eventBus related classes to dedicated maven package

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 1bd539c9a22c91f98471197809edf8d44fb173b2
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 25 12:40:45 2021 +0700

    JAMES-3498 Move eventBus related classes to dedicated maven package
    
    This enables reuse
---
 event-bus/api/pom.xml                              |  52 +++
 .../main/java/org/apache/james}/events/Event.java  |   2 +-
 .../java/org/apache/james}/events/EventBus.java    |  22 +-
 .../org/apache/james}/events/EventDeadLetters.java |   2 +-
 .../james}/events/EventDeadLettersHealthCheck.java |   4 +-
 .../org/apache/james/events/EventListener.java     | 142 ++++++
 .../main/java/org/apache/james}/events/Group.java  |   4 +-
 .../james}/events/GroupAlreadyRegistered.java      |   4 +-
 .../james}/events/GroupRegistrationNotFound.java   |   4 +-
 .../org/apache/james}/events/Registration.java     |   2 +-
 .../org/apache/james}/events/RegistrationKey.java  |   2 +-
 .../apache/james/mailbox/events/GenericGroup.java  |   4 +-
 event-bus/distributed/pom.xml                      |  34 ++
 event-bus/in-vm/pom.xml                            |  34 ++
 .../org/apache/james}/events/InVMEventBus.java     |  26 +-
 .../james}/events/MemoryEventDeadLetters.java      |   6 +-
 .../james}/events/delivery/EventDelivery.java      |  32 +-
 .../james}/events/delivery/InVmEventDelivery.java  |  24 +-
 .../org/apache/james}/events/InVMEventBusTest.java |   4 +-
 .../MemoryEventDeadLettersHealthCheckTest.java     |   2 +-
 .../james}/events/MemoryEventDeadLettersTest.java  |   2 +-
 .../events/delivery/InVmEventDeliveryTest.java     | 115 +++--
 event-bus/pom.xml                                  |  39 ++
 .../listeners/SetCustomFlagOnBigMessages.java      |  13 +-
 .../listeners/SetCustomFlagOnBigMessagesTest.java  |   2 +-
 mailbox/api/pom.xml                                |   4 +
 .../MailboxEvents.java}                            | 122 +-----
 .../events/MailboxIdRegistrationKey.java           |   2 +-
 .../{mailbox => }/events/MessageMoveEvent.java     |   2 +-
 .../james/events/RetryBackoffConfiguration.java    | 125 ++++++
 .../{MailboxListener.java => MailboxEvents.java}   | 120 +----
 .../mailbox/events/MailboxIdRegistrationKey.java   |   1 +
 .../james/mailbox/events/MessageMoveEvent.java     |   1 +
 .../events/ErrorHandlingContract.java              |  24 +-
 .../events/EventBusConcurrentTestContract.java     | 106 +++--
 .../{mailbox => }/events/EventBusContract.java     |   2 +-
 .../{mailbox => }/events/EventBusTestFixture.java  |  33 +-
 .../events/EventDeadLettersContract.java           |  11 +-
 .../EventDeadLettersHealthCheckContract.java       |   7 +-
 .../org/apache/james/events/GroupContract.java     | 487 +++++++++++++++++++++
 .../james/{mailbox => }/events/GroupTest.java      |   3 +-
 .../{mailbox => }/events/InsertionIdTest.java      |   3 +-
 .../java/org/apache/james/events/KeyContract.java  | 445 +++++++++++++++++++
 .../MailboxIdRegistrationKeyTest.java}             |  38 +-
 .../events/RetryBackoffConfigurationTest.java      | 141 ++++++
 .../java/org/apache/james/mailbox/EventTest.java   |  10 +-
 .../apache/james/mailbox/MailboxListenerTest.java  |  51 ++-
 .../mailbox/MailboxManagerStressContract.java      |   6 +-
 .../apache/james/mailbox/MailboxManagerTest.java   |  55 +--
 .../mailbox/events/ErrorHandlingContract.java      |   7 +-
 .../events/EventBusConcurrentTestContract.java     |  46 +-
 .../james/mailbox/events/EventBusContract.java     |   1 +
 .../james/mailbox/events/EventBusTestFixture.java  |  33 +-
 .../mailbox/events/EventDeadLettersContract.java   |  12 +-
 .../EventDeadLettersHealthCheckContract.java       |   9 +-
 .../apache/james/mailbox/events/GroupContract.java |  89 ++--
 .../org/apache/james/mailbox/events/GroupTest.java |  10 +-
 .../james/mailbox/events/InsertionIdTest.java      |   1 +
 .../apache/james/mailbox/events/KeyContract.java   |  81 ++--
 .../apache/james/mailbox/util/EventCollector.java  |   8 +-
 .../mailbox/cassandra/CassandraMailboxManager.java |   2 +-
 .../mailbox/cassandra/CassandraMessageManager.java |   2 +-
 .../mailbox/cassandra/DeleteMessageListener.java   |  10 +-
 .../cassandra/MailboxOperationLoggingListener.java |  11 +-
 .../CassandraCombinationManagerTestSystem.java     |   2 +-
 .../CassandraMailboxManagerStressTest.java         |   2 +-
 .../cassandra/CassandraMailboxManagerTest.java     |   2 +-
 .../CassandraMessageIdManagerSideEffectTest.java   |   2 +-
 .../CassandraMessageIdManagerTestSystem.java       |   2 +-
 .../cassandra/CassandraTestSystemFixture.java      |   2 +-
 .../MailboxOperationLoggingListenerTest.java       |   2 +-
 .../cassandra/mail/CassandraMailboxMapperTest.java |   1 -
 .../ElasticSearchListeningMessageSearchIndex.java  |   2 +-
 .../ElasticSearchIntegrationTest.java              |   4 -
 ...asticSearchListeningMessageSearchIndexTest.java |   3 +-
 .../events/CassandraEventDeadLetters.java          |   2 +-
 .../events/CassandraEventDeadLettersDAO.java       |  60 ++-
 .../events/CassandraEventDeadLettersGroupDAO.java  |  18 +-
 .../events/CassandraEventDeadLettersModule.java    |  46 ++
 .../CassandraEventDeadLettersGroupTable.java}      |   9 +-
 .../tables/CassandraEventDeadLettersTable.java}    |  10 +-
 .../mailbox/events/CassandraEventDeadLetters.java  |   4 +
 .../events/CassandraEventDeadLettersDAO.java       |   3 +
 .../events/CassandraEventDeadLettersGroupDAO.java  |   1 +
 .../events/CassandraEventDeadLettersDAOTest.java   | 137 ++++++
 .../CassandraEventDeadLettersGroupDAOTest.java}    |  41 +-
 .../CassandraEventDeadLettersHealthCheckTest.java  |   2 +-
 .../events/CassandraEventDeadLettersTest.java      |   2 +-
 .../CassandraEventDeadLettersHealthCheckTest.java  |   2 +
 .../events/CassandraEventDeadLettersTest.java      |   1 +
 .../apache/james/mailbox/events/InVMEventBus.java  |  25 +-
 .../mailbox/events/MemoryEventDeadLetters.java     |   4 +
 .../mailbox/events/delivery/EventDelivery.java     |  20 +-
 .../mailbox/events/delivery/InVmEventDelivery.java |  22 +-
 .../james/mailbox/events/InVMEventBusTest.java     |   2 +
 .../MemoryEventDeadLettersHealthCheckTest.java     |   2 +
 .../mailbox/events/MemoryEventDeadLettersTest.java |   1 +
 .../events/delivery/InVmEventDeliveryTest.java     |  34 +-
 .../java/org/apache/james/events/EventBusId.java}  |  51 ++-
 .../{mailbox => }/events/EventDispatcher.java      |  16 +-
 .../{mailbox => }/events/GroupConsumerRetry.java   |   7 +-
 .../{mailbox => }/events/GroupRegistration.java    |  15 +-
 .../events/GroupRegistrationHandler.java           |   6 +-
 .../james/events/KeyReconnectionHandler.java}      |  49 ++-
 .../{mailbox => }/events/KeyRegistration.java      |   4 +-
 .../events/KeyRegistrationHandler.java             |  12 +-
 .../events/LocalListenerRegistry.java              |  25 +-
 .../events/MailboxListenerExecutor.java            |  11 +-
 .../{mailbox => }/events/RabbitMQEventBus.java     |   6 +-
 .../{mailbox => }/events/RegistrationBinder.java   |   4 +-
 .../james/events/RegistrationQueueName.java}       |  15 +-
 .../{mailbox => }/events/RoutingKeyConverter.java  |   2 +-
 .../apache/james/events/WaitDelayGenerator.java    |  83 ++++
 .../james/mailbox/events/EventDispatcher.java      |  10 +-
 .../james/mailbox/events/GroupConsumerRetry.java   |   4 +
 .../james/mailbox/events/GroupRegistration.java    |  10 +-
 .../mailbox/events/GroupRegistrationHandler.java   |  10 +-
 .../james/mailbox/events/KeyRegistration.java      |   2 +
 .../mailbox/events/KeyRegistrationHandler.java     |  13 +-
 .../mailbox/events/LocalListenerRegistry.java      |  23 +-
 .../mailbox/events/MailboxListenerExecutor.java    |   9 +-
 .../james/mailbox/events/RabbitMQEventBus.java     |  11 +-
 .../james/mailbox/events/RegistrationBinder.java   |   2 +
 .../james/mailbox/events/RoutingKeyConverter.java  |   2 +
 .../org/apache/james/events/EventBusIdTest.java}   |  26 +-
 .../events/LocalListenerRegistryTest.java          |  56 +--
 .../{mailbox => }/events/NetworkErrorTest.java     |  14 +-
 ...abbitMQEventBusDeadLetterQueueUpgradeTest.java} |  50 +--
 .../{mailbox => }/events/RabbitMQEventBusTest.java |  86 ++--
 .../events/RoutingKeyConverterTest.java            |   2 +-
 .../james/events/WaitDelayGeneratorTest.java       | 103 +++++
 .../mailbox/events/LocalListenerRegistryTest.java  |  55 +--
 .../james/mailbox/events/NetworkErrorTest.java     |   3 +-
 .../james/mailbox/events/RabbitMQEventBusTest.java |  56 +--
 .../mailbox/events/RoutingKeyConverterTest.java    |   1 +
 .../apache/james/event/json/EventSerializer.scala  |  37 +-
 .../james/event/json/AddedSerializationTest.java   |   7 +-
 .../event/json/ExpungedSerializationTest.java      |   6 +-
 .../event/json/FlagsUpdatedSerializationTest.java  |   8 +-
 .../MailboxACLUpdatedEventSerializationTest.java   |   4 +-
 .../event/json/MailboxAddedSerializationTest.java  |   4 +-
 .../json/MailboxDeletionSerializationTest.java     |   6 +-
 .../json/MailboxRenamedSerializationTest.java      |   4 +-
 .../json/MessageMoveEventSerializationTest.java    |   2 +-
 .../QuotaUsageUpdatedEventSerializationTest.java   |   4 +-
 .../apache/james/event/json/SerializerFixture.java |   2 +-
 .../mailbox/jpa/openjpa/OpenJPAMailboxManager.java |   2 +-
 .../mailbox/jpa/openjpa/OpenJPAMessageManager.java |   2 +-
 .../james/mailbox/jpa/JPAMailboxManagerTest.java   |   2 +-
 .../mailbox/jpa/JpaMailboxManagerStressTest.java   |   2 +-
 .../lucene/search/LuceneMessageSearchIndex.java    |   6 +-
 .../search/LuceneMessageSearchIndexTest.java       |  13 -
 .../DomainUserMaildirMailboxManagerStressTest.java |   2 +-
 .../DomainUserMaildirMailboxManagerTest.java       |   2 +-
 .../FullUserMaildirMailboxManagerStressTest.java   |   2 +-
 .../maildir/FullUserMaildirMailboxManagerTest.java |   2 +-
 .../UserMaildirMailboxManagerStressTest.java       |   2 +-
 .../mailbox/inmemory/InMemoryMailboxManager.java   |   2 +-
 .../mailbox/inmemory/InMemoryMessageManager.java   |   2 +-
 .../inmemory/MemoryMailboxManagerStressTest.java   |   2 +-
 .../mailbox/inmemory/MemoryMailboxManagerTest.java |   2 +-
 .../manager/InMemoryIntegrationResources.java      |   6 +-
 .../InMemoryMessageIdManagerSideEffectTest.java    |   2 +-
 .../listeners/QuotaThresholdCrossingListener.java  |   9 +-
 .../QuotaThresholdConfigurationChangesTest.java    |   2 +-
 .../QuotaThresholdCrossingListenerTest.java        |   2 +-
 .../QuotaThresholdListenersTestSystem.java         |   6 +-
 .../QuotaThresholdMailingIntegrationTest.java      |   2 +-
 .../events/ElasticSearchQuotaMailboxListener.java  |   9 +-
 .../json/QuotaRatioToElasticSearchJson.java        |   2 +-
 .../ElasticSearchQuotaMailboxListenerTest.java     |   4 +-
 .../json/QuotaRatioToElasticSearchJsonTest.java    |   4 +-
 .../mailbox/spamassassin/SpamAssassinListener.java |   5 +-
 .../spamassassin/SpamAssassinListenerTest.java     |  11 +-
 .../james/mailbox/spring/MailboxInitializer.java   |   2 +-
 .../james/mailbox/store/StoreMailboxManager.java   |   2 +-
 .../james/mailbox/store/StoreMessageIdManager.java |   2 +-
 .../james/mailbox/store/StoreMessageManager.java   |   6 +-
 .../james/mailbox/store/StoreRightManager.java     |   2 +-
 .../james/mailbox/store/event/EventFactory.java    |  43 +-
 .../store/event/MailboxAnnotationListener.java     |   9 +-
 .../mailbox/store/event/SpamEventListener.java     |   4 +-
 .../store/quota/ListeningCurrentQuotaUpdater.java  |  16 +-
 .../store/search/LazyMessageSearchIndex.java       |   2 +-
 .../store/search/ListeningMessageSearchIndex.java  |  13 +-
 .../AbstractMessageIdManagerSideEffectTest.java    |  43 +-
 .../james/mailbox/store/StoreRightManagerTest.java |   2 +-
 .../store/event/MailboxAnnotationListenerTest.java |  11 +-
 .../quota/ListeningCurrentQuotaUpdaterTest.java    |  23 +-
 .../search/AbstractMessageSearchIndexTest.java     |   2 -
 .../store/search/CombinedComparatorTest.java       |   1 -
 .../store/search/LazyMessageSearchIndexTest.java   |   2 +-
 pom.xml                                            |   6 +
 .../imap/processor/AbstractSelectionProcessor.java |   2 +-
 .../imap/processor/DefaultProcessorChain.java      |   2 +-
 .../james/imap/processor/ExamineProcessor.java     |   2 +-
 .../apache/james/imap/processor/IdleProcessor.java |  13 +-
 .../james/imap/processor/SelectProcessor.java      |   2 +-
 .../imap/processor/base/SelectedMailboxImpl.java   |  16 +-
 .../main/DefaultImapProcessorFactory.java          |   2 +-
 .../processor/base/MailboxEventAnalyserTest.java   |  23 +-
 .../processor/base/SelectedMailboxImplTest.java    |  37 +-
 .../java/org/apache/james/SearchModuleChooser.java |   2 +-
 .../modules/mailbox/CassandraDeadLetterModule.java |   4 +-
 .../modules/mailbox/CassandraMailboxModule.java    |   4 +-
 .../modules/mailbox/CassandraQuotaModule.java      |   4 +-
 .../mailbox/ElasticSearchMailboxModule.java        |   4 +-
 .../mailbox/ElasticSearchQuotaSearcherModule.java  |   4 +-
 .../modules/event/RabbitMQEventBusModule.java      |   4 +-
 .../apache/james/PeriodicalHealthChecksTest.java   |   2 +-
 .../james/modules/mailbox/JPAMailboxModule.java    |   4 +-
 .../james/modules/mailbox/JpaQuotaModule.java      |   4 +-
 .../modules/mailbox/LuceneSearchMailboxModule.java |   4 +-
 .../james/modules/EventDeadLettersProbe.java       |   2 +-
 .../james/modules/mailbox/DefaultEventModule.java  |   8 +-
 .../modules/mailbox/MailboxListenerFactory.java    |  16 +-
 .../modules/mailbox/MailboxListenersLoader.java    |   8 +-
 .../mailbox/MailboxListenersLoaderImpl.java        |  46 +-
 .../modules/mailbox/MemoryDeadLetterModule.java    |   4 +-
 .../mailbox/MailboxListenersLoaderImplTest.java    |   9 +-
 .../james/modules/mailbox/NoopMailboxListener.java |   8 +-
 .../mailbox/ReactiveNoopMailboxListener.java       |   8 +-
 .../org/apache/james/FakeMessageSearchIndex.java   |   2 +-
 .../james/modules/mailbox/MemoryMailboxModule.java |   4 +-
 .../james/modules/mailbox/MemoryQuotaModule.java   |   4 +-
 .../apache/james/DisabledGroupExecutionTest.java   |  10 +-
 .../james/modules/protocols/IMAPServerModule.java  |   2 +-
 .../apache/james/jmap/draft/JMAPCommonModule.java  |   4 +-
 .../org/apache/james/jmap/draft/JMAPModule.java    |   6 +-
 .../apache/james/jmap/draft/JmapGuiceProbe.java    |   6 +-
 .../apache/james/jmap/api/change/EmailChange.java  |   9 +-
 .../james/jmap/api/change/MailboxChange.java       |  14 +-
 .../methods/integration/SetMessagesMethodTest.java |  10 +-
 .../ComputeMessageFastViewProjectionListener.java  |   9 +-
 .../jmap/event/PopulateEmailQueryViewListener.java |  11 +-
 .../jmap/event/PropagateLookupRightListener.java   |  10 +-
 ...mputeMessageFastViewProjectionListenerTest.java |   2 +-
 .../event/PopulateEmailQueryViewListenerTest.java  |   2 +-
 .../event/PropagateLookupRightListenerTest.java    |   6 +-
 .../james/jmap/change/MailboxChangeListener.scala  |  12 +-
 .../RabbitMQEventDeadLettersIntegrationTest.java   |  11 +-
 ...dminServerTaskSerializationIntegrationTest.java |  14 +-
 .../webadmin/routes/EventDeadLettersRoutes.java    |   6 +-
 .../EventDeadLettersRedeliverGroupTask.java        |   2 +-
 .../EventDeadLettersRedeliverGroupTaskDTO.java     |   2 +-
 .../service/EventDeadLettersRedeliverOneTask.java  |   4 +-
 .../EventDeadLettersRedeliverOneTaskDTO.java       |   4 +-
 .../service/EventDeadLettersRedeliverService.java  |   8 +-
 ...LettersRedeliveryTaskAdditionalInformation.java |   4 +-
 ...tersRedeliveryTaskAdditionalInformationDTO.java |   4 +-
 .../webadmin/service/EventDeadLettersService.java  |   6 +-
 .../james/webadmin/service/EventRetriever.java     |   6 +-
 .../routes/EventDeadLettersRoutesTest.java         |  16 +-
 .../james/webadmin/routes/MailboxesRoutesTest.java |   2 -
 .../webadmin/routes/UserMailboxesRoutesTest.java   |   2 -
 .../service/EventDeadLettersRedeliverTaskTest.java |   4 +-
 256 files changed, 3365 insertions(+), 1509 deletions(-)

diff --git a/event-bus/api/pom.xml b/event-bus/api/pom.xml
new file mode 100644
index 0000000..cbf7cc8
--- /dev/null
+++ b/event-bus/api/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.james</groupId>
+        <artifactId>event-bus</artifactId>
+        <version>3.6.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>event-bus-api</artifactId>
+    <name>Apache James :: Event Bus :: API</name>
+    <description>API implementation for the eventBus, abstracting messaging patterns like workqueues and Pub/Sub</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.projectreactor</groupId>
+            <artifactId>reactor-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.inject</groupId>
+            <artifactId>javax.inject</artifactId>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/Event.java b/event-bus/api/src/main/java/org/apache/james/events/Event.java
similarity index 98%
rename from mailbox/api/src/main/java/org/apache/james/mailbox/events/Event.java
rename to event-bus/api/src/main/java/org/apache/james/events/Event.java
index 43060a6..12693e6 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/Event.java
+++ b/event-bus/api/src/main/java/org/apache/james/events/Event.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations      *
  * under the License.                                           *
  ****************************************************************/
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import java.util.Objects;
 import java.util.UUID;
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/EventBus.java b/event-bus/api/src/main/java/org/apache/james/events/EventBus.java
similarity index 70%
rename from mailbox/api/src/main/java/org/apache/james/mailbox/events/EventBus.java
rename to event-bus/api/src/main/java/org/apache/james/events/EventBus.java
index c07cfb9..2429107 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/EventBus.java
+++ b/event-bus/api/src/main/java/org/apache/james/events/EventBus.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import java.util.Set;
 
@@ -41,21 +41,21 @@ public interface EventBus {
     }
 
     interface Metrics {
-        static String timerName(MailboxListener mailboxListener) {
+        static String timerName(EventListener mailboxListener) {
             return "mailbox-listener-" + mailboxListener.getClass().getSimpleName();
         }
     }
 
-    default Publisher<Registration> register(MailboxListener listener, RegistrationKey key) {
-        return register(MailboxListener.wrapReactive(listener), key);
+    default Publisher<Registration> register(EventListener listener, RegistrationKey key) {
+        return register(EventListener.wrapReactive(listener), key);
     }
 
-    Publisher<Registration> register(MailboxListener.ReactiveMailboxListener listener, RegistrationKey key);
+    Publisher<Registration> register(EventListener.ReactiveEventListener listener, RegistrationKey key);
 
-    Registration register(MailboxListener.ReactiveMailboxListener listener, Group group) throws GroupAlreadyRegistered;
+    Registration register(EventListener.ReactiveEventListener listener, Group group) throws GroupAlreadyRegistered;
 
-    default Registration register(MailboxListener listener, Group group) throws GroupAlreadyRegistered {
-        return register(MailboxListener.wrapReactive(listener), group);
+    default Registration register(EventListener listener, Group group) throws GroupAlreadyRegistered {
+        return register(EventListener.wrapReactive(listener), group);
     }
 
     Mono<Void> dispatch(Event event, Set<RegistrationKey> key);
@@ -66,11 +66,11 @@ public interface EventBus {
         return dispatch(event, ImmutableSet.of(key));
     }
 
-    default Registration register(MailboxListener.GroupMailboxListener groupMailboxListener) {
-        return register(MailboxListener.wrapReactive(groupMailboxListener));
+    default Registration register(EventListener.GroupEventListener groupMailboxListener) {
+        return register(EventListener.wrapReactive(groupMailboxListener));
     }
 
-    default Registration register(MailboxListener.ReactiveGroupMailboxListener groupMailboxListener) {
+    default Registration register(EventListener.ReactiveGroupEventListener groupMailboxListener) {
         return register(groupMailboxListener, groupMailboxListener.getDefaultGroup());
     }
 }
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/EventDeadLetters.java b/event-bus/api/src/main/java/org/apache/james/events/EventDeadLetters.java
similarity index 98%
rename from mailbox/api/src/main/java/org/apache/james/mailbox/events/EventDeadLetters.java
rename to event-bus/api/src/main/java/org/apache/james/events/EventDeadLetters.java
index 053ba45..8987e18 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/EventDeadLetters.java
+++ b/event-bus/api/src/main/java/org/apache/james/events/EventDeadLetters.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import java.util.Objects;
 import java.util.UUID;
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/EventDeadLettersHealthCheck.java b/event-bus/api/src/main/java/org/apache/james/events/EventDeadLettersHealthCheck.java
similarity index 95%
copy from mailbox/api/src/main/java/org/apache/james/mailbox/events/EventDeadLettersHealthCheck.java
copy to event-bus/api/src/main/java/org/apache/james/events/EventDeadLettersHealthCheck.java
index 27d33d6..98ccc0f 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/EventDeadLettersHealthCheck.java
+++ b/event-bus/api/src/main/java/org/apache/james/events/EventDeadLettersHealthCheck.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import javax.inject.Inject;
 
@@ -33,7 +33,7 @@ public class EventDeadLettersHealthCheck implements HealthCheck {
     private final EventDeadLetters eventDeadLetters;
 
     @Inject
-    EventDeadLettersHealthCheck(EventDeadLetters eventDeadLetters) {
+    public EventDeadLettersHealthCheck(EventDeadLetters eventDeadLetters) {
         this.eventDeadLetters = eventDeadLetters;
     }
 
diff --git a/event-bus/api/src/main/java/org/apache/james/events/EventListener.java b/event-bus/api/src/main/java/org/apache/james/events/EventListener.java
new file mode 100644
index 0000000..be50c12
--- /dev/null
+++ b/event-bus/api/src/main/java/org/apache/james/events/EventListener.java
@@ -0,0 +1,142 @@
+/****************************************************************
+ * 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.events;
+
+import java.util.Objects;
+
+import org.reactivestreams.Publisher;
+
+import com.github.fge.lambdas.Throwing;
+
+import reactor.core.publisher.Mono;
+import reactor.core.scheduler.Schedulers;
+
+/**
+ * Listens to events.<br>
+ */
+public interface EventListener {
+
+    interface ReactiveEventListener extends EventListener {
+        Publisher<Void> reactiveEvent(Event event);
+
+        default void event(Event event) throws Exception {
+            Mono.from(reactiveEvent(event))
+                .subscribeOn(Schedulers.elastic())
+                .block();
+        }
+    }
+
+    interface GroupEventListener extends EventListener {
+        Group getDefaultGroup();
+    }
+
+    interface ReactiveGroupEventListener extends ReactiveEventListener, GroupEventListener {
+        default void event(Event event) throws Exception {
+            Mono.from(reactiveEvent(event))
+                .subscribeOn(Schedulers.elastic())
+                .block();
+        }
+    }
+
+    class ReactiveWrapper<T extends EventListener> implements ReactiveEventListener {
+        protected final T delegate;
+
+        private ReactiveWrapper(T delegate) {
+            this.delegate = delegate;
+        }
+
+        @Override
+        public Publisher<Void> reactiveEvent(Event event) {
+            return Mono.fromRunnable(Throwing.runnable(() -> delegate.event(event)))
+                .subscribeOn(Schedulers.elastic())
+                .then();
+        }
+
+        @Override
+        public void event(Event event) throws Exception {
+            delegate.event(event);
+        }
+
+        @Override
+        public ExecutionMode getExecutionMode() {
+            return delegate.getExecutionMode();
+        }
+
+        @Override
+        public boolean isHandling(Event event) {
+            return delegate.isHandling(event);
+        }
+
+        @Override
+        public final boolean equals(Object o) {
+            if (o instanceof ReactiveWrapper) {
+                ReactiveWrapper<?> that = (ReactiveWrapper<?>) o;
+
+                return Objects.equals(this.delegate, that.delegate);
+            }
+            return false;
+        }
+
+        @Override
+        public final int hashCode() {
+            return Objects.hash(delegate);
+        }
+    }
+
+    class ReactiveGroupWrapper extends ReactiveWrapper<GroupEventListener> implements GroupEventListener, ReactiveGroupEventListener {
+        private ReactiveGroupWrapper(GroupEventListener delegate) {
+            super(delegate);
+        }
+
+        @Override
+        public Group getDefaultGroup() {
+            return delegate.getDefaultGroup();
+        }
+    }
+
+    enum ExecutionMode {
+        SYNCHRONOUS,
+        ASYNCHRONOUS
+    }
+
+    static ReactiveEventListener wrapReactive(EventListener listener) {
+        return new ReactiveWrapper<>(listener);
+    }
+
+    static ReactiveGroupEventListener wrapReactive(GroupEventListener groupMailboxListener) {
+        return new ReactiveGroupWrapper(groupMailboxListener);
+    }
+
+    default ExecutionMode getExecutionMode() {
+        return ExecutionMode.SYNCHRONOUS;
+    }
+
+
+    default boolean isHandling(Event event) {
+        return true;
+    }
+
+    /**
+     * Informs this listener about the given event.
+     *
+     * @param event not null
+     */
+    void event(Event event) throws Exception;
+}
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/Group.java b/event-bus/api/src/main/java/org/apache/james/events/Group.java
similarity index 97%
rename from mailbox/api/src/main/java/org/apache/james/mailbox/events/Group.java
rename to event-bus/api/src/main/java/org/apache/james/events/Group.java
index ee3d049..50b1685 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/Group.java
+++ b/event-bus/api/src/main/java/org/apache/james/events/Group.java
@@ -17,11 +17,13 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import java.lang.reflect.InvocationTargetException;
 import java.util.Objects;
 
+import org.apache.james.mailbox.events.GenericGroup;
+
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/GroupAlreadyRegistered.java b/event-bus/api/src/main/java/org/apache/james/events/GroupAlreadyRegistered.java
similarity index 95%
rename from mailbox/api/src/main/java/org/apache/james/mailbox/events/GroupAlreadyRegistered.java
rename to event-bus/api/src/main/java/org/apache/james/events/GroupAlreadyRegistered.java
index 736fc66..40bfc40 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/GroupAlreadyRegistered.java
+++ b/event-bus/api/src/main/java/org/apache/james/events/GroupAlreadyRegistered.java
@@ -17,7 +17,9 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
+
+import org.apache.james.events.Group;
 
 public class GroupAlreadyRegistered extends RuntimeException {
     private final Group group;
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/GroupRegistrationNotFound.java b/event-bus/api/src/main/java/org/apache/james/events/GroupRegistrationNotFound.java
similarity index 95%
rename from mailbox/api/src/main/java/org/apache/james/mailbox/events/GroupRegistrationNotFound.java
rename to event-bus/api/src/main/java/org/apache/james/events/GroupRegistrationNotFound.java
index a268fc0..786132a 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/GroupRegistrationNotFound.java
+++ b/event-bus/api/src/main/java/org/apache/james/events/GroupRegistrationNotFound.java
@@ -17,7 +17,9 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
+
+import org.apache.james.events.Group;
 
 public class GroupRegistrationNotFound extends RuntimeException {
     private final Group group;
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/Registration.java b/event-bus/api/src/main/java/org/apache/james/events/Registration.java
similarity index 96%
copy from mailbox/api/src/main/java/org/apache/james/mailbox/events/Registration.java
copy to event-bus/api/src/main/java/org/apache/james/events/Registration.java
index c5a3a53..99cf17e 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/Registration.java
+++ b/event-bus/api/src/main/java/org/apache/james/events/Registration.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 public interface Registration {
     void unregister();
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/RegistrationKey.java b/event-bus/api/src/main/java/org/apache/james/events/RegistrationKey.java
similarity index 97%
copy from mailbox/api/src/main/java/org/apache/james/mailbox/events/RegistrationKey.java
copy to event-bus/api/src/main/java/org/apache/james/events/RegistrationKey.java
index 1d0e320..bff0203 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/RegistrationKey.java
+++ b/event-bus/api/src/main/java/org/apache/james/events/RegistrationKey.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 public interface RegistrationKey {
 
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/GenericGroup.java b/event-bus/api/src/main/java/org/apache/james/mailbox/events/GenericGroup.java
similarity index 95%
copy from mailbox/api/src/main/java/org/apache/james/mailbox/events/GenericGroup.java
copy to event-bus/api/src/main/java/org/apache/james/mailbox/events/GenericGroup.java
index a679682..7b93ba6 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/GenericGroup.java
+++ b/event-bus/api/src/main/java/org/apache/james/mailbox/events/GenericGroup.java
@@ -21,8 +21,10 @@ package org.apache.james.mailbox.events;
 
 import java.util.Objects;
 
+import org.apache.james.events.Group;
+
 public class GenericGroup extends Group {
-    static final String DELIMITER = "-";
+    public static final String DELIMITER = "-";
     private final String groupName;
 
     public GenericGroup(String groupName) {
diff --git a/event-bus/distributed/pom.xml b/event-bus/distributed/pom.xml
new file mode 100644
index 0000000..a202f2c
--- /dev/null
+++ b/event-bus/distributed/pom.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.james</groupId>
+        <artifactId>event-bus</artifactId>
+        <version>3.6.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>event-bus-distributed</artifactId>
+    <name>Apache James :: Event Bus :: Distributed</name>
+    <description>Distributed implementation for the eventBus</description>
+
+</project>
\ No newline at end of file
diff --git a/event-bus/in-vm/pom.xml b/event-bus/in-vm/pom.xml
new file mode 100644
index 0000000..99fc5c2
--- /dev/null
+++ b/event-bus/in-vm/pom.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.james</groupId>
+        <artifactId>event-bus</artifactId>
+        <version>3.6.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>event-bus-in-vm</artifactId>
+    <name>Apache James :: Event Bus :: In VM</name>
+    <description>In VM (non distributed) implementation for the eventBus</description>
+
+</project>
\ No newline at end of file
diff --git a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/InVMEventBus.java b/event-bus/in-vm/src/main/java/org/apache/james/events/InVMEventBus.java
similarity index 77%
copy from mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/InVMEventBus.java
copy to event-bus/in-vm/src/main/java/org/apache/james/events/InVMEventBus.java
index 6e73b0f..a3360c5 100644
--- a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/InVMEventBus.java
+++ b/event-bus/in-vm/src/main/java/org/apache/james/events/InVMEventBus.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import java.util.Optional;
 import java.util.Set;
@@ -25,9 +25,7 @@ import java.util.concurrent.ConcurrentHashMap;
 
 import javax.inject.Inject;
 
-import org.apache.james.mailbox.events.delivery.EventDelivery;
-import org.apache.james.mailbox.events.delivery.EventDelivery.PermanentFailureHandler.StoreToDeadLetters;
-import org.apache.james.mailbox.events.delivery.EventDelivery.Retryer.BackoffRetryer;
+import org.apache.james.events.delivery.EventDelivery;
 
 import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.HashMultimap;
@@ -39,8 +37,8 @@ import reactor.core.publisher.Mono;
 
 public class InVMEventBus implements EventBus {
 
-    private final Multimap<RegistrationKey, MailboxListener.ReactiveMailboxListener> registrations;
-    private final ConcurrentHashMap<Group, MailboxListener.ReactiveMailboxListener> groups;
+    private final Multimap<RegistrationKey, EventListener.ReactiveEventListener> registrations;
+    private final ConcurrentHashMap<Group, EventListener.ReactiveEventListener> groups;
     private final EventDelivery eventDelivery;
     private final RetryBackoffConfiguration retryBackoff;
     private final EventDeadLetters eventDeadLetters;
@@ -55,14 +53,14 @@ public class InVMEventBus implements EventBus {
     }
 
     @Override
-    public Mono<Registration> register(MailboxListener.ReactiveMailboxListener listener, RegistrationKey key) {
+    public Mono<Registration> register(EventListener.ReactiveEventListener listener, RegistrationKey key) {
         registrations.put(key, listener);
         return Mono.just(() -> registrations.remove(key, listener));
     }
 
     @Override
-    public Registration register(MailboxListener.ReactiveMailboxListener listener, Group group) {
-        MailboxListener previous = groups.putIfAbsent(group, listener);
+    public Registration register(EventListener.ReactiveEventListener listener, Group group) {
+        EventListener previous = groups.putIfAbsent(group, listener);
         if (previous == null) {
             return () -> groups.remove(group, listener);
         }
@@ -87,7 +85,7 @@ public class InVMEventBus implements EventBus {
         return Mono.empty();
     }
 
-    private MailboxListener.ReactiveMailboxListener retrieveListenerFromGroup(Group group) {
+    private EventListener.ReactiveEventListener retrieveListenerFromGroup(Group group) {
         return Optional.ofNullable(groups.get(group))
             .orElseThrow(() -> new GroupRegistrationNotFound(group));
     }
@@ -104,20 +102,20 @@ public class InVMEventBus implements EventBus {
             .then();
     }
 
-    private Mono<Void> groupDelivery(Event event, MailboxListener.ReactiveMailboxListener mailboxListener, Group group) {
+    private Mono<Void> groupDelivery(Event event, EventListener.ReactiveEventListener mailboxListener, Group group) {
         return eventDelivery.deliver(
             mailboxListener,
             event,
             EventDelivery.DeliveryOption.of(
-                BackoffRetryer.of(retryBackoff, mailboxListener),
-                StoreToDeadLetters.of(group, eventDeadLetters)));
+                EventDelivery.Retryer.BackoffRetryer.of(retryBackoff, mailboxListener),
+                EventDelivery.PermanentFailureHandler.StoreToDeadLetters.of(group, eventDeadLetters)));
     }
 
     public Set<Group> registeredGroups() {
         return groups.keySet();
     }
 
-    private Set<MailboxListener.ReactiveMailboxListener> registeredListenersByKeys(Set<RegistrationKey> keys) {
+    private Set<EventListener.ReactiveEventListener> registeredListenersByKeys(Set<RegistrationKey> keys) {
         return keys.stream()
             .flatMap(registrationKey -> registrations.get(registrationKey).stream())
             .collect(Guavate.toImmutableSet());
diff --git a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/MemoryEventDeadLetters.java b/event-bus/in-vm/src/main/java/org/apache/james/events/MemoryEventDeadLetters.java
similarity index 95%
copy from mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/MemoryEventDeadLetters.java
copy to event-bus/in-vm/src/main/java/org/apache/james/events/MemoryEventDeadLetters.java
index 5f8af25..d96ef55 100644
--- a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/MemoryEventDeadLetters.java
+++ b/event-bus/in-vm/src/main/java/org/apache/james/events/MemoryEventDeadLetters.java
@@ -17,7 +17,11 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
+
+import org.apache.james.events.Event;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.Group;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.HashBasedTable;
diff --git a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/EventDelivery.java b/event-bus/in-vm/src/main/java/org/apache/james/events/delivery/EventDelivery.java
similarity index 80%
copy from mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/EventDelivery.java
copy to event-bus/in-vm/src/main/java/org/apache/james/events/delivery/EventDelivery.java
index d0f06dd..11f6593 100644
--- a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/EventDelivery.java
+++ b/event-bus/in-vm/src/main/java/org/apache/james/events/delivery/EventDelivery.java
@@ -17,16 +17,16 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events.delivery;
+package org.apache.james.events.delivery;
 
-import static org.apache.james.mailbox.events.delivery.EventDelivery.PermanentFailureHandler.NO_HANDLER;
-import static org.apache.james.mailbox.events.delivery.EventDelivery.Retryer.NO_RETRYER;
+import static org.apache.james.events.delivery.EventDelivery.PermanentFailureHandler.NO_HANDLER;
+import static org.apache.james.events.delivery.EventDelivery.Retryer.NO_RETRYER;
 
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.EventDeadLetters;
-import org.apache.james.mailbox.events.Group;
-import org.apache.james.mailbox.events.MailboxListener;
-import org.apache.james.mailbox.events.RetryBackoffConfiguration;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
+import org.apache.james.events.RetryBackoffConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -67,18 +67,18 @@ public interface EventDelivery {
 
         Retryer NO_RETRYER = (executionResult, event) -> executionResult;
 
-        class BackoffRetryer implements EventDelivery.Retryer {
+        class BackoffRetryer implements Retryer {
 
-            public static BackoffRetryer of(RetryBackoffConfiguration retryBackoff, MailboxListener mailboxListener) {
+            public static BackoffRetryer of(RetryBackoffConfiguration retryBackoff, EventListener mailboxListener) {
                 return new BackoffRetryer(retryBackoff, mailboxListener);
             }
 
             private static final Logger LOGGER = LoggerFactory.getLogger(BackoffRetryer.class);
 
             private final RetryBackoffConfiguration retryBackoff;
-            private final MailboxListener mailboxListener;
+            private final EventListener mailboxListener;
 
-            public BackoffRetryer(RetryBackoffConfiguration retryBackoff, MailboxListener mailboxListener) {
+            public BackoffRetryer(RetryBackoffConfiguration retryBackoff, EventListener mailboxListener) {
                 this.retryBackoff = retryBackoff;
                 this.mailboxListener = mailboxListener;
             }
@@ -103,7 +103,7 @@ public interface EventDelivery {
 
         PermanentFailureHandler NO_HANDLER = event -> Mono.error(new UnsupportedOperationException("doesn't handle error"));
 
-        class StoreToDeadLetters implements EventDelivery.PermanentFailureHandler {
+        class StoreToDeadLetters implements PermanentFailureHandler {
 
             public static StoreToDeadLetters of(Group group, EventDeadLetters eventDeadLetters) {
                 return new StoreToDeadLetters(group, eventDeadLetters);
@@ -126,9 +126,9 @@ public interface EventDelivery {
         Mono<Void> handle(Event event);
     }
 
-    Mono<Void> deliver(MailboxListener.ReactiveMailboxListener listener, Event event, DeliveryOption option);
+    Mono<Void> deliver(EventListener.ReactiveEventListener listener, Event event, DeliveryOption option);
 
-    default Mono<Void> deliver(MailboxListener listener, Event event, DeliveryOption option) {
-        return deliver(MailboxListener.wrapReactive(listener), event, option);
+    default Mono<Void> deliver(EventListener listener, Event event, DeliveryOption option) {
+        return deliver(EventListener.wrapReactive(listener), event, option);
     }
 }
diff --git a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/InVmEventDelivery.java b/event-bus/in-vm/src/main/java/org/apache/james/events/delivery/InVmEventDelivery.java
similarity index 79%
copy from mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/InVmEventDelivery.java
copy to event-bus/in-vm/src/main/java/org/apache/james/events/delivery/InVmEventDelivery.java
index f4f7036..f67c022 100644
--- a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/InVmEventDelivery.java
+++ b/event-bus/in-vm/src/main/java/org/apache/james/events/delivery/InVmEventDelivery.java
@@ -17,16 +17,16 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events.delivery;
+package org.apache.james.events.delivery;
 
-import static org.apache.james.mailbox.events.EventBus.Metrics.timerName;
+import static org.apache.james.events.EventBus.Metrics.timerName;
 import static org.apache.james.util.ReactorUtils.context;
 
 import javax.inject.Inject;
 
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.EventBus;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventBus;
+import org.apache.james.events.EventListener;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.util.MDCBuilder;
 import org.apache.james.util.MDCStructuredLogger;
@@ -51,14 +51,14 @@ public class InVmEventDelivery implements EventDelivery {
     }
 
     @Override
-    public Mono<Void> deliver(MailboxListener.ReactiveMailboxListener listener, Event event, DeliveryOption option) {
+    public Mono<Void> deliver(EventListener.ReactiveEventListener listener, Event event, DeliveryOption option) {
         Mono<Void> executionResult = deliverByOption(listener, event, option);
 
         return waitForResultIfNeeded(listener.getExecutionMode(), executionResult);
     }
 
-    private Mono<Void> waitForResultIfNeeded(MailboxListener.ExecutionMode executionMode, Mono<Void> executionResult) {
-        if (executionMode.equals(MailboxListener.ExecutionMode.SYNCHRONOUS)) {
+    private Mono<Void> waitForResultIfNeeded(EventListener.ExecutionMode executionMode, Mono<Void> executionResult) {
+        if (executionMode.equals(EventListener.ExecutionMode.SYNCHRONOUS)) {
             return executionResult;
         }
         return Flux.merge(executionResult, Mono.empty())
@@ -66,7 +66,7 @@ public class InVmEventDelivery implements EventDelivery {
             .onErrorResume(throwable -> Mono.empty());
     }
 
-    private Mono<Void> deliverByOption(MailboxListener.ReactiveMailboxListener listener, Event event, DeliveryOption deliveryOption) {
+    private Mono<Void> deliverByOption(EventListener.ReactiveEventListener listener, Event event, DeliveryOption deliveryOption) {
         Mono<Void> deliveryToListener = doDeliverToListener(listener, event)
             .doOnError(throwable -> structuredLogger(event, listener)
                 .log(logger -> logger.error("Error while processing listener", throwable)))
@@ -77,7 +77,7 @@ public class InVmEventDelivery implements EventDelivery {
             .then();
     }
 
-    private Mono<Void> doDeliverToListener(MailboxListener.ReactiveMailboxListener mailboxListener, Event event) {
+    private Mono<Void> doDeliverToListener(EventListener.ReactiveEventListener mailboxListener, Event event) {
         if (mailboxListener.isHandling(event)) {
             return Mono.defer(() -> Mono.from(metricFactory.decoratePublisherWithTimerMetric(timerName(mailboxListener),
                     mailboxListener.reactiveEvent(event))))
@@ -86,7 +86,7 @@ public class InVmEventDelivery implements EventDelivery {
         return Mono.empty();
     }
 
-    private MDCBuilder buildMDC(MailboxListener mailboxListener, Event event) {
+    private MDCBuilder buildMDC(EventListener mailboxListener, Event event) {
         return MDCBuilder.create()
             .addContext(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
             .addContext(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
@@ -94,7 +94,7 @@ public class InVmEventDelivery implements EventDelivery {
             .addContext(EventBus.StructuredLoggingFields.LISTENER_CLASS, mailboxListener.getClass());
     }
 
-    private StructuredLogger structuredLogger(Event event, MailboxListener mailboxListener) {
+    private StructuredLogger structuredLogger(Event event, EventListener mailboxListener) {
         return MDCStructuredLogger.forLogger(LOGGER)
             .addField(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
             .addField(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
diff --git a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/InVMEventBusTest.java b/event-bus/in-vm/src/test/java/org/apache/james/events/InVMEventBusTest.java
similarity index 95%
copy from mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/InVMEventBusTest.java
copy to event-bus/in-vm/src/test/java/org/apache/james/events/InVMEventBusTest.java
index 5a6a6ea..7705203 100644
--- a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/InVMEventBusTest.java
+++ b/event-bus/in-vm/src/test/java/org/apache/james/events/InVMEventBusTest.java
@@ -17,9 +17,9 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
-import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
+import org.apache.james.events.delivery.InVmEventDelivery;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
 import org.junit.jupiter.api.BeforeEach;
 
diff --git a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersHealthCheckTest.java b/event-bus/in-vm/src/test/java/org/apache/james/events/MemoryEventDeadLettersHealthCheckTest.java
similarity index 98%
copy from mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersHealthCheckTest.java
copy to event-bus/in-vm/src/test/java/org/apache/james/events/MemoryEventDeadLettersHealthCheckTest.java
index c05deb0..bc4e5c3 100644
--- a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersHealthCheckTest.java
+++ b/event-bus/in-vm/src/test/java/org/apache/james/events/MemoryEventDeadLettersHealthCheckTest.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import org.apache.commons.lang3.NotImplementedException;
 import org.junit.jupiter.api.Disabled;
diff --git a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersTest.java b/event-bus/in-vm/src/test/java/org/apache/james/events/MemoryEventDeadLettersTest.java
similarity index 97%
copy from mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersTest.java
copy to event-bus/in-vm/src/test/java/org/apache/james/events/MemoryEventDeadLettersTest.java
index 2ef0996..c6facc9 100644
--- a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersTest.java
+++ b/event-bus/in-vm/src/test/java/org/apache/james/events/MemoryEventDeadLettersTest.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import org.junit.jupiter.api.BeforeEach;
 
diff --git a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/delivery/InVmEventDeliveryTest.java b/event-bus/in-vm/src/test/java/org/apache/james/events/delivery/InVmEventDeliveryTest.java
similarity index 60%
copy from mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/delivery/InVmEventDeliveryTest.java
copy to event-bus/in-vm/src/test/java/org/apache/james/events/delivery/InVmEventDeliveryTest.java
index dd210a9..a0536a0 100644
--- a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/delivery/InVmEventDeliveryTest.java
+++ b/event-bus/in-vm/src/test/java/org/apache/james/events/delivery/InVmEventDeliveryTest.java
@@ -17,12 +17,8 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events.delivery;
+package org.apache.james.events.delivery;
 
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT;
-import static org.apache.james.mailbox.events.EventBusTestFixture.GROUP_A;
-import static org.apache.james.mailbox.events.EventBusTestFixture.MailboxListenerCountingSuccessfulExecution;
-import static org.apache.james.mailbox.events.delivery.EventDelivery.Retryer;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -32,21 +28,20 @@ import static org.mockito.Mockito.when;
 
 import java.time.Duration;
 
-import org.apache.james.mailbox.events.MailboxListener;
-import org.apache.james.mailbox.events.MemoryEventDeadLetters;
-import org.apache.james.mailbox.events.RetryBackoffConfiguration;
-import org.apache.james.mailbox.events.delivery.EventDelivery.DeliveryOption;
-import org.apache.james.mailbox.events.delivery.EventDelivery.PermanentFailureHandler;
-import org.apache.james.mailbox.events.delivery.EventDelivery.Retryer.BackoffRetryer;
+import org.apache.james.events.EventBusTestFixture;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.MemoryEventDeadLetters;
+import org.apache.james.events.RetryBackoffConfiguration;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
 import org.assertj.core.api.SoftAssertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
 
 class InVmEventDeliveryTest {
     private InVmEventDelivery inVmEventDelivery;
-    private MailboxListenerCountingSuccessfulExecution listener;
+    private EventBusTestFixture.EventListenerCountingSuccessfulExecution listener;
 
     @BeforeEach
     void setUp() {
@@ -54,8 +49,8 @@ class InVmEventDeliveryTest {
         inVmEventDelivery = new InVmEventDelivery(new RecordingMetricFactory());
     }
 
-    MailboxListenerCountingSuccessfulExecution newListener() {
-        return spy(new MailboxListenerCountingSuccessfulExecution());
+    EventBusTestFixture.EventListenerCountingSuccessfulExecution newListener() {
+        return Mockito.spy(new EventBusTestFixture.EventListenerCountingSuccessfulExecution());
     }
 
     @Nested
@@ -63,8 +58,8 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldDeliverEvent() {
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.SYNCHRONOUS);
-            inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
+            inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT, EventDelivery.DeliveryOption.none())
                 .block();
 
             assertThat(listener.numberOfEventCalls())
@@ -73,19 +68,19 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldReturnSuccessSynchronousMono() {
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.SYNCHRONOUS);
-            assertThatCode(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
+            assertThatCode(() -> inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT, EventDelivery.DeliveryOption.none())
                     .block())
                 .doesNotThrowAnyException();
         }
 
         @Test
         void deliverShouldNotDeliverWhenListenerGetException() {
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.SYNCHRONOUS);
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
             doThrow(new RuntimeException())
-                .when(listener).event(EVENT);
+                .when(listener).event(EventBusTestFixture.EVENT);
 
-            assertThatThrownBy(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
+            assertThatThrownBy(() -> inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT, EventDelivery.DeliveryOption.none())
                 .block())
             .isInstanceOf(RuntimeException.class);
 
@@ -95,11 +90,11 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldReturnAnErrorMonoWhenListenerGetException() {
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.SYNCHRONOUS);
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
             doThrow(new RuntimeException())
-                .when(listener).event(EVENT);
+                .when(listener).event(EventBusTestFixture.EVENT);
 
-            assertThatThrownBy(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
+            assertThatThrownBy(() -> inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT, EventDelivery.DeliveryOption.none())
                 .block())
             .isInstanceOf(RuntimeException.class);
         }
@@ -110,8 +105,8 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldDeliverEvent() {
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
-            inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
+            inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT, EventDelivery.DeliveryOption.none())
                 .block();
 
             assertThat(listener.numberOfEventCalls())
@@ -120,30 +115,30 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldReturnSuccessSynchronousMono() {
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
-            assertThatCode(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
+            assertThatCode(() -> inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT, EventDelivery.DeliveryOption.none())
                     .block())
                 .doesNotThrowAnyException();
         }
 
         @Test
         void deliverShouldNotFailWhenListenerGetException() {
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
             doThrow(new RuntimeException())
-                .when(listener).event(EVENT);
+                .when(listener).event(EventBusTestFixture.EVENT);
 
-            assertThatCode(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
+            assertThatCode(() -> inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT, EventDelivery.DeliveryOption.none())
                 .block())
             .doesNotThrowAnyException();
         }
 
         @Test
         void deliverShouldReturnAnSuccessSyncMonoWhenListenerGetException() {
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
             doThrow(new RuntimeException())
-                .when(listener).event(EVENT);
+                .when(listener).event(EventBusTestFixture.EVENT);
 
-            assertThatCode(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
+            assertThatCode(() -> inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT, EventDelivery.DeliveryOption.none())
                 .block())
             .doesNotThrowAnyException();
         }
@@ -154,17 +149,17 @@ class InVmEventDeliveryTest {
 
         @Test
         void retryShouldWorkWhenDeliverWithRetry() {
-            MailboxListenerCountingSuccessfulExecution listener = newListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution listener = newListener();
             doThrow(new RuntimeException())
                 .doThrow(new RuntimeException())
                 .doThrow(new RuntimeException())
                 .doCallRealMethod()
-                .when(listener).event(EVENT);
+                .when(listener).event(EventBusTestFixture.EVENT);
 
-            inVmEventDelivery.deliver(listener, EVENT,
-                DeliveryOption.of(
-                    BackoffRetryer.of(RetryBackoffConfiguration.DEFAULT, listener),
-                    PermanentFailureHandler.NO_HANDLER))
+            inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT,
+                EventDelivery.DeliveryOption.of(
+                    EventDelivery.Retryer.BackoffRetryer.of(RetryBackoffConfiguration.DEFAULT, listener),
+                    EventDelivery.PermanentFailureHandler.NO_HANDLER))
                 .block();
 
             assertThat(listener.numberOfEventCalls())
@@ -173,36 +168,36 @@ class InVmEventDeliveryTest {
 
         @Test
         void failureHandlerShouldWorkWhenDeliverWithFailureHandler() {
-            MailboxListenerCountingSuccessfulExecution listener = newListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution listener = newListener();
             doThrow(new RuntimeException())
-                .when(listener).event(EVENT);
+                .when(listener).event(EventBusTestFixture.EVENT);
 
             MemoryEventDeadLetters deadLetter = new MemoryEventDeadLetters();
 
-            inVmEventDelivery.deliver(listener, EVENT,
-                DeliveryOption.of(
-                    Retryer.NO_RETRYER,
-                    PermanentFailureHandler.StoreToDeadLetters.of(GROUP_A, deadLetter)))
+            inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT,
+                EventDelivery.DeliveryOption.of(
+                    EventDelivery.Retryer.NO_RETRYER,
+                    EventDelivery.PermanentFailureHandler.StoreToDeadLetters.of(EventBusTestFixture.GROUP_A, deadLetter)))
                 .block();
 
             assertThat(deadLetter.groupsWithFailedEvents().toStream())
-                .containsOnly(GROUP_A);
+                .containsOnly(EventBusTestFixture.GROUP_A);
         }
 
         @Test
         void failureHandlerShouldNotWorkWhenRetrySuccess() {
-            MailboxListenerCountingSuccessfulExecution listener = newListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution listener = newListener();
             doThrow(new RuntimeException())
                 .doThrow(new RuntimeException())
                 .doCallRealMethod()
-                .when(listener).event(EVENT);
+                .when(listener).event(EventBusTestFixture.EVENT);
 
             MemoryEventDeadLetters deadLetter = new MemoryEventDeadLetters();
 
-            inVmEventDelivery.deliver(listener, EVENT,
-                DeliveryOption.of(
-                    BackoffRetryer.of(RetryBackoffConfiguration.DEFAULT, listener),
-                    PermanentFailureHandler.StoreToDeadLetters.of(GROUP_A, deadLetter)))
+            inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT,
+                EventDelivery.DeliveryOption.of(
+                    EventDelivery.Retryer.BackoffRetryer.of(RetryBackoffConfiguration.DEFAULT, listener),
+                    EventDelivery.PermanentFailureHandler.StoreToDeadLetters.of(EventBusTestFixture.GROUP_A, deadLetter)))
                 .block();
 
             SoftAssertions.assertSoftly(softy -> {
@@ -216,7 +211,7 @@ class InVmEventDeliveryTest {
 
         @Test
         void failureHandlerShouldWorkWhenRetryFails() {
-            MailboxListenerCountingSuccessfulExecution listener = newListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution listener = newListener();
             //do throw  RetryBackoffConfiguration.DEFAULT.DEFAULT_MAX_RETRIES + 1 times
             doThrow(new RuntimeException())
                 .doThrow(new RuntimeException())
@@ -228,25 +223,25 @@ class InVmEventDeliveryTest {
                 .doThrow(new RuntimeException())
                 .doThrow(new RuntimeException())
                 .doCallRealMethod()
-                .when(listener).event(EVENT);
+                .when(listener).event(EventBusTestFixture.EVENT);
 
             MemoryEventDeadLetters deadLetter = new MemoryEventDeadLetters();
 
-            inVmEventDelivery.deliver(listener, EVENT,
-                DeliveryOption.of(
-                    BackoffRetryer.of(RetryBackoffConfiguration.builder()
+            inVmEventDelivery.deliver(listener, EventBusTestFixture.EVENT,
+                EventDelivery.DeliveryOption.of(
+                    EventDelivery.Retryer.BackoffRetryer.of(RetryBackoffConfiguration.builder()
                             .maxRetries(8)
                             .firstBackoff(Duration.ofMillis(1))
                             .jitterFactor(0.2)
                             .build(), listener),
-                    PermanentFailureHandler.StoreToDeadLetters.of(GROUP_A, deadLetter)))
+                    EventDelivery.PermanentFailureHandler.StoreToDeadLetters.of(EventBusTestFixture.GROUP_A, deadLetter)))
                 .block();
 
             SoftAssertions.assertSoftly(softy -> {
                 softy.assertThat(listener.numberOfEventCalls())
                     .isEqualTo(0);
                 assertThat(deadLetter.groupsWithFailedEvents().toStream())
-                    .containsOnly(GROUP_A);
+                    .containsOnly(EventBusTestFixture.GROUP_A);
             });
         }
     }
diff --git a/event-bus/pom.xml b/event-bus/pom.xml
new file mode 100644
index 0000000..4e36b39
--- /dev/null
+++ b/event-bus/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.james</groupId>
+        <artifactId>james-project</artifactId>
+        <version>3.6.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>event-bus</artifactId>
+    <packaging>pom</packaging>
+    <name>Apache James :: Event Bus</name>
+
+    <modules>
+        <module>api</module>
+        <module>distributed</module>
+        <module>in-vm</module>
+    </modules>
+</project>
\ No newline at end of file
diff --git a/examples/custom-listeners/src/main/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessages.java b/examples/custom-listeners/src/main/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessages.java
index 1d1b08d..d541029 100644
--- a/examples/custom-listeners/src/main/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessages.java
+++ b/examples/custom-listeners/src/main/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessages.java
@@ -22,14 +22,15 @@ package org.apache.james.examples.custom.listeners;
 import javax.inject.Inject;
 import javax.mail.Flags;
 
+import org.apache.james.events.EventListener;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageManager.FlagsUpdateMode;
 import org.apache.james.mailbox.MessageUid;
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.Group;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.events.Event;
+import org.apache.james.events.Group;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MessageRange;
 import org.slf4j.Logger;
@@ -42,7 +43,7 @@ import org.slf4j.LoggerFactory;
  * Then it will be considered as a big message and added BIG_MESSAGE {@value BIG_MESSAGE} flag
  *
  */
-class SetCustomFlagOnBigMessages implements MailboxListener.GroupMailboxListener {
+class SetCustomFlagOnBigMessages implements EventListener.GroupEventListener {
     public static class PositionCustomFlagOnBigMessagesGroup extends Group {
 
     }
@@ -63,8 +64,8 @@ class SetCustomFlagOnBigMessages implements MailboxListener.GroupMailboxListener
 
     @Override
     public void event(Event event) {
-        if (event instanceof MailboxListener.Added) {
-            MailboxListener.Added addedEvent = (MailboxListener.Added) event;
+        if (event instanceof Added) {
+            Added addedEvent = (Added) event;
             addedEvent.getUids().stream()
                 .filter(messageUid -> isBig(addedEvent, messageUid))
                 .forEach(messageUid -> setBigMessageFlag(addedEvent, messageUid));
diff --git a/examples/custom-listeners/src/test/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessagesTest.java b/examples/custom-listeners/src/test/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessagesTest.java
index 8972fff..0ccbeca 100644
--- a/examples/custom-listeners/src/test/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessagesTest.java
+++ b/examples/custom-listeners/src/test/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessagesTest.java
@@ -33,7 +33,7 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
-import org.apache.james.mailbox.events.Event;
+import org.apache.james.events.Event;
 import org.apache.james.mailbox.inmemory.InMemoryMailboxManager;
 import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
 import org.apache.james.mailbox.model.ComposedMessageId;
diff --git a/mailbox/api/pom.xml b/mailbox/api/pom.xml
index a6146c3..ff31374 100644
--- a/mailbox/api/pom.xml
+++ b/mailbox/api/pom.xml
@@ -34,6 +34,10 @@
     <dependencies>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-core</artifactId>
         </dependency>
         <dependency>
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxListener.java b/mailbox/api/src/main/java/org/apache/james/events/MailboxEvents.java
similarity index 85%
copy from mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxListener.java
copy to mailbox/api/src/main/java/org/apache/james/events/MailboxEvents.java
index 11bb4e6..20dbe89 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxListener.java
+++ b/mailbox/api/src/main/java/org/apache/james/events/MailboxEvents.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import java.time.Instant;
 import java.util.Collection;
@@ -32,6 +32,7 @@ import org.apache.james.core.quota.QuotaCountLimit;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
+import org.apache.james.events.Event;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.acl.ACLDiff;
@@ -43,130 +44,13 @@ import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.mailbox.model.QuotaRoot;
 import org.apache.james.mailbox.model.UpdatedFlags;
-import org.reactivestreams.Publisher;
 
-import com.github.fge.lambdas.Throwing;
 import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 
-import reactor.core.publisher.Mono;
-import reactor.core.scheduler.Schedulers;
-
-
-/**
- * Listens to <code>Mailbox</code> events.<br>
- * Note that listeners may be removed asynchronously.
- */
-public interface MailboxListener {
-
-    interface ReactiveMailboxListener extends MailboxListener {
-        Publisher<Void> reactiveEvent(Event event);
-
-        default void event(Event event) throws Exception {
-            Mono.from(reactiveEvent(event))
-                .subscribeOn(Schedulers.elastic())
-                .block();
-        }
-    }
-
-    interface GroupMailboxListener extends MailboxListener {
-        Group getDefaultGroup();
-    }
-
-    interface ReactiveGroupMailboxListener extends ReactiveMailboxListener, GroupMailboxListener {
-        default void event(Event event) throws Exception {
-            Mono.from(reactiveEvent(event))
-                .subscribeOn(Schedulers.elastic())
-                .block();
-        }
-    }
-
-    class ReactiveWrapper<T extends MailboxListener> implements ReactiveMailboxListener {
-        protected final T delegate;
-
-        private ReactiveWrapper(T delegate) {
-            this.delegate = delegate;
-        }
-
-        @Override
-        public Publisher<Void> reactiveEvent(Event event) {
-            return Mono.fromRunnable(Throwing.runnable(() -> delegate.event(event)))
-                .subscribeOn(Schedulers.elastic())
-                .then();
-        }
-
-        @Override
-        public void event(Event event) throws Exception {
-            delegate.event(event);
-        }
-
-        @Override
-        public ExecutionMode getExecutionMode() {
-            return delegate.getExecutionMode();
-        }
-
-        @Override
-        public boolean isHandling(Event event) {
-            return delegate.isHandling(event);
-        }
-
-        @Override
-        public final boolean equals(Object o) {
-            if (o instanceof ReactiveWrapper) {
-                ReactiveWrapper<?> that = (ReactiveWrapper<?>) o;
-
-                return Objects.equals(this.delegate, that.delegate);
-            }
-            return false;
-        }
-
-        @Override
-        public final int hashCode() {
-            return Objects.hash(delegate);
-        }
-    }
-
-    class ReactiveGroupWrapper extends ReactiveWrapper<GroupMailboxListener> implements GroupMailboxListener, ReactiveGroupMailboxListener {
-        private ReactiveGroupWrapper(GroupMailboxListener delegate) {
-            super(delegate);
-        }
-
-        @Override
-        public Group getDefaultGroup() {
-            return delegate.getDefaultGroup();
-        }
-    }
-
-    enum ExecutionMode {
-        SYNCHRONOUS,
-        ASYNCHRONOUS
-    }
-
-    static ReactiveMailboxListener wrapReactive(MailboxListener listener) {
-        return new ReactiveWrapper<>(listener);
-    }
-
-    static ReactiveGroupMailboxListener wrapReactive(GroupMailboxListener groupMailboxListener) {
-        return new ReactiveGroupWrapper(groupMailboxListener);
-    }
-
-    default ExecutionMode getExecutionMode() {
-        return ExecutionMode.SYNCHRONOUS;
-    }
-
-
-    default boolean isHandling(Event event) {
-        return true;
-    }
-
-    /**
-     * Informs this listener about the given event.
-     *
-     * @param event not null
-     */
-    void event(Event event) throws Exception;
+public interface MailboxEvents {
 
     interface QuotaEvent extends Event {
         QuotaRoot getQuotaRoot();
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxIdRegistrationKey.java b/mailbox/api/src/main/java/org/apache/james/events/MailboxIdRegistrationKey.java
similarity index 98%
copy from mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxIdRegistrationKey.java
copy to mailbox/api/src/main/java/org/apache/james/events/MailboxIdRegistrationKey.java
index e132429..44387cb 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxIdRegistrationKey.java
+++ b/mailbox/api/src/main/java/org/apache/james/events/MailboxIdRegistrationKey.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import java.util.Objects;
 
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MessageMoveEvent.java b/mailbox/api/src/main/java/org/apache/james/events/MessageMoveEvent.java
similarity index 99%
copy from mailbox/api/src/main/java/org/apache/james/mailbox/events/MessageMoveEvent.java
copy to mailbox/api/src/main/java/org/apache/james/events/MessageMoveEvent.java
index b149f25..2c2f89f 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MessageMoveEvent.java
+++ b/mailbox/api/src/main/java/org/apache/james/events/MessageMoveEvent.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations      *
  * under the License.                                           *
  ****************************************************************/
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import java.util.Collection;
 import java.util.Objects;
diff --git a/mailbox/api/src/main/java/org/apache/james/events/RetryBackoffConfiguration.java b/mailbox/api/src/main/java/org/apache/james/events/RetryBackoffConfiguration.java
new file mode 100644
index 0000000..aafeb2c
--- /dev/null
+++ b/mailbox/api/src/main/java/org/apache/james/events/RetryBackoffConfiguration.java
@@ -0,0 +1,125 @@
+/****************************************************************
+ * 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.events;
+
+import java.time.Duration;
+import java.util.Objects;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+
+public class RetryBackoffConfiguration {
+
+    @FunctionalInterface
+    public interface RequireMaxRetries {
+        RequireFirstBackoff maxRetries(int maxRetries);
+    }
+
+    @FunctionalInterface
+    public interface RequireFirstBackoff {
+        RequireJitterFactor firstBackoff(Duration firstBackoff);
+    }
+
+    @FunctionalInterface
+    public interface RequireJitterFactor {
+        ReadyToBuild jitterFactor(double jitterFactor);
+    }
+
+    public static class ReadyToBuild {
+        private final int maxRetries;
+        private final Duration firstBackoff;
+        private final double jitterFactor;
+
+        private ReadyToBuild(int maxRetries, Duration firstBackoff, double jitterFactor) {
+            this.maxRetries = maxRetries;
+            this.firstBackoff = firstBackoff;
+            this.jitterFactor = jitterFactor;
+        }
+
+        public RetryBackoffConfiguration build() {
+            return new RetryBackoffConfiguration(maxRetries, firstBackoff, jitterFactor);
+        }
+    }
+
+    public static RequireMaxRetries builder() {
+        return maxRetries -> firstBackoff -> jitterFactor -> new ReadyToBuild(maxRetries, firstBackoff, jitterFactor);
+    }
+
+    static final double DEFAULT_JITTER_FACTOR = 0.5;
+    static final int DEFAULT_MAX_RETRIES = 8;
+    static final Duration DEFAULT_FIRST_BACKOFF = Duration.ofMillis(100);
+    public static final RetryBackoffConfiguration DEFAULT = new RetryBackoffConfiguration(
+        DEFAULT_MAX_RETRIES,
+        DEFAULT_FIRST_BACKOFF,
+        DEFAULT_JITTER_FACTOR);
+
+    private final int maxRetries;
+    private final Duration firstBackoff;
+    private final double jitterFactor;
+
+    private RetryBackoffConfiguration(int maxRetries, Duration firstBackoff, double jitterFactor) {
+        Preconditions.checkArgument(!firstBackoff.isNegative(), "firstBackoff is not allowed to be negative");
+        Preconditions.checkArgument(maxRetries >= 0, "maxRetries is not allowed to be negative");
+        Preconditions.checkArgument(jitterFactor >= 0 && jitterFactor <= 1.0, "jitterFactor is not " +
+            "allowed to be negative or greater than 1");
+
+        this.maxRetries = maxRetries;
+        this.firstBackoff = firstBackoff;
+        this.jitterFactor = jitterFactor;
+    }
+
+    public int getMaxRetries() {
+        return maxRetries;
+    }
+
+    public Duration getFirstBackoff() {
+        return firstBackoff;
+    }
+
+    public double getJitterFactor() {
+        return jitterFactor;
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof RetryBackoffConfiguration) {
+            RetryBackoffConfiguration that = (RetryBackoffConfiguration) o;
+
+            return Objects.equals(this.maxRetries, that.maxRetries)
+                && Objects.equals(this.jitterFactor, that.jitterFactor)
+                && Objects.equals(this.firstBackoff, that.firstBackoff);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(maxRetries, firstBackoff, jitterFactor);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+            .add("maxRetries", maxRetries)
+            .add("firstBackoff", firstBackoff)
+            .add("jitterFactor", jitterFactor)
+            .toString();
+    }
+}
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxListener.java b/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxEvents.java
similarity index 85%
rename from mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxListener.java
rename to mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxEvents.java
index 11bb4e6..d544e35 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxListener.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxEvents.java
@@ -32,6 +32,7 @@ import org.apache.james.core.quota.QuotaCountLimit;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
+import org.apache.james.events.Event;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.acl.ACLDiff;
@@ -43,130 +44,13 @@ import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.mailbox.model.QuotaRoot;
 import org.apache.james.mailbox.model.UpdatedFlags;
-import org.reactivestreams.Publisher;
 
-import com.github.fge.lambdas.Throwing;
 import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 
-import reactor.core.publisher.Mono;
-import reactor.core.scheduler.Schedulers;
-
-
-/**
- * Listens to <code>Mailbox</code> events.<br>
- * Note that listeners may be removed asynchronously.
- */
-public interface MailboxListener {
-
-    interface ReactiveMailboxListener extends MailboxListener {
-        Publisher<Void> reactiveEvent(Event event);
-
-        default void event(Event event) throws Exception {
-            Mono.from(reactiveEvent(event))
-                .subscribeOn(Schedulers.elastic())
-                .block();
-        }
-    }
-
-    interface GroupMailboxListener extends MailboxListener {
-        Group getDefaultGroup();
-    }
-
-    interface ReactiveGroupMailboxListener extends ReactiveMailboxListener, GroupMailboxListener {
-        default void event(Event event) throws Exception {
-            Mono.from(reactiveEvent(event))
-                .subscribeOn(Schedulers.elastic())
-                .block();
-        }
-    }
-
-    class ReactiveWrapper<T extends MailboxListener> implements ReactiveMailboxListener {
-        protected final T delegate;
-
-        private ReactiveWrapper(T delegate) {
-            this.delegate = delegate;
-        }
-
-        @Override
-        public Publisher<Void> reactiveEvent(Event event) {
-            return Mono.fromRunnable(Throwing.runnable(() -> delegate.event(event)))
-                .subscribeOn(Schedulers.elastic())
-                .then();
-        }
-
-        @Override
-        public void event(Event event) throws Exception {
-            delegate.event(event);
-        }
-
-        @Override
-        public ExecutionMode getExecutionMode() {
-            return delegate.getExecutionMode();
-        }
-
-        @Override
-        public boolean isHandling(Event event) {
-            return delegate.isHandling(event);
-        }
-
-        @Override
-        public final boolean equals(Object o) {
-            if (o instanceof ReactiveWrapper) {
-                ReactiveWrapper<?> that = (ReactiveWrapper<?>) o;
-
-                return Objects.equals(this.delegate, that.delegate);
-            }
-            return false;
-        }
-
-        @Override
-        public final int hashCode() {
-            return Objects.hash(delegate);
-        }
-    }
-
-    class ReactiveGroupWrapper extends ReactiveWrapper<GroupMailboxListener> implements GroupMailboxListener, ReactiveGroupMailboxListener {
-        private ReactiveGroupWrapper(GroupMailboxListener delegate) {
-            super(delegate);
-        }
-
-        @Override
-        public Group getDefaultGroup() {
-            return delegate.getDefaultGroup();
-        }
-    }
-
-    enum ExecutionMode {
-        SYNCHRONOUS,
-        ASYNCHRONOUS
-    }
-
-    static ReactiveMailboxListener wrapReactive(MailboxListener listener) {
-        return new ReactiveWrapper<>(listener);
-    }
-
-    static ReactiveGroupMailboxListener wrapReactive(GroupMailboxListener groupMailboxListener) {
-        return new ReactiveGroupWrapper(groupMailboxListener);
-    }
-
-    default ExecutionMode getExecutionMode() {
-        return ExecutionMode.SYNCHRONOUS;
-    }
-
-
-    default boolean isHandling(Event event) {
-        return true;
-    }
-
-    /**
-     * Informs this listener about the given event.
-     *
-     * @param event not null
-     */
-    void event(Event event) throws Exception;
+public interface MailboxEvents {
 
     interface QuotaEvent extends Event {
         QuotaRoot getQuotaRoot();
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxIdRegistrationKey.java b/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxIdRegistrationKey.java
index e132429..cbbd20b 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxIdRegistrationKey.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxIdRegistrationKey.java
@@ -23,6 +23,7 @@ import java.util.Objects;
 
 import javax.inject.Inject;
 
+import org.apache.james.events.RegistrationKey;
 import org.apache.james.mailbox.model.MailboxId;
 
 public class MailboxIdRegistrationKey implements RegistrationKey {
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MessageMoveEvent.java b/mailbox/api/src/main/java/org/apache/james/mailbox/events/MessageMoveEvent.java
index b149f25..69173d2 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MessageMoveEvent.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/events/MessageMoveEvent.java
@@ -23,6 +23,7 @@ import java.util.Objects;
 import java.util.Optional;
 
 import org.apache.james.core.Username;
+import org.apache.james.events.Event;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageId;
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/ErrorHandlingContract.java b/mailbox/api/src/test/java/org/apache/james/events/ErrorHandlingContract.java
similarity index 94%
copy from mailbox/api/src/test/java/org/apache/james/mailbox/events/ErrorHandlingContract.java
copy to mailbox/api/src/test/java/org/apache/james/events/ErrorHandlingContract.java
index 18bcb18..3d20090 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/ErrorHandlingContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/events/ErrorHandlingContract.java
@@ -17,16 +17,16 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
-
-import static org.apache.james.mailbox.events.EventBusTestFixture.DEFAULT_FIRST_BACKOFF;
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT;
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT_2;
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT_ID;
-import static org.apache.james.mailbox.events.EventBusTestFixture.GROUP_A;
-import static org.apache.james.mailbox.events.EventBusTestFixture.KEY_1;
-import static org.apache.james.mailbox.events.EventBusTestFixture.NO_KEYS;
-import static org.apache.james.mailbox.events.EventBusTestFixture.RETRY_BACKOFF_CONFIGURATION;
+package org.apache.james.events;
+
+import static org.apache.james.events.EventBusTestFixture.DEFAULT_FIRST_BACKOFF;
+import static org.apache.james.events.EventBusTestFixture.EVENT;
+import static org.apache.james.events.EventBusTestFixture.EVENT_2;
+import static org.apache.james.events.EventBusTestFixture.EVENT_ID;
+import static org.apache.james.events.EventBusTestFixture.GROUP_A;
+import static org.apache.james.events.EventBusTestFixture.KEY_1;
+import static org.apache.james.events.EventBusTestFixture.NO_KEYS;
+import static org.apache.james.events.EventBusTestFixture.RETRY_BACKOFF_CONFIGURATION;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.spy;
@@ -48,7 +48,7 @@ import reactor.core.publisher.Mono;
 
 interface ErrorHandlingContract extends EventBusContract {
 
-    class ThrowingListener implements MailboxListener {
+    class ThrowingListener implements EventListener {
         private final List<Instant> timeElapsed;
 
         private ThrowingListener() {
@@ -200,7 +200,7 @@ interface ErrorHandlingContract extends EventBusContract {
     default void retryingListenerCallingDispatchShouldNotFail() {
         AtomicBoolean firstExecution = new AtomicBoolean(true);
         AtomicBoolean successfulRetry = new AtomicBoolean(false);
-        MailboxListener listener = event -> {
+        EventListener listener = event -> {
             if (event.getEventId().equals(EVENT_ID)) {
                 if (firstExecution.get()) {
                     firstExecution.set(false);
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusConcurrentTestContract.java b/mailbox/api/src/test/java/org/apache/james/events/EventBusConcurrentTestContract.java
similarity index 64%
copy from mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusConcurrentTestContract.java
copy to mailbox/api/src/test/java/org/apache/james/events/EventBusConcurrentTestContract.java
index 1aa3c2e..6648458 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusConcurrentTestContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/events/EventBusConcurrentTestContract.java
@@ -17,14 +17,8 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
-
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT;
-import static org.apache.james.mailbox.events.EventBusTestFixture.KEY_1;
-import static org.apache.james.mailbox.events.EventBusTestFixture.KEY_2;
-import static org.apache.james.mailbox.events.EventBusTestFixture.KEY_3;
-import static org.apache.james.mailbox.events.EventBusTestFixture.NO_KEYS;
-import static org.apache.james.mailbox.events.EventDeadLettersContract.GROUP_A;
+package org.apache.james.events;
+
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.awaitility.Awaitility.await;
 
@@ -50,15 +44,15 @@ public interface EventBusConcurrentTestContract {
     int OPERATION_COUNT = 30;
     int TOTAL_DISPATCH_OPERATIONS = THREAD_COUNT * OPERATION_COUNT;
 
-    Set<RegistrationKey> ALL_KEYS = ImmutableSet.of(KEY_1, KEY_2, KEY_3);
+    Set<RegistrationKey> ALL_KEYS = ImmutableSet.of(EventBusTestFixture.KEY_1, EventBusTestFixture.KEY_2, EventBusTestFixture.KEY_3);
 
-    static EventBusTestFixture.MailboxListenerCountingSuccessfulExecution newCountingListener() {
-        return new EventBusTestFixture.MailboxListenerCountingSuccessfulExecution();
+    static EventBusTestFixture.EventListenerCountingSuccessfulExecution newCountingListener() {
+        return new EventBusTestFixture.EventListenerCountingSuccessfulExecution();
     }
 
-    static int totalEventsReceived(ImmutableList<EventBusTestFixture.MailboxListenerCountingSuccessfulExecution> allListeners) {
+    static int totalEventsReceived(ImmutableList<EventBusTestFixture.EventListenerCountingSuccessfulExecution> allListeners) {
         return allListeners.stream()
-            .mapToInt(EventBusTestFixture.MailboxListenerCountingSuccessfulExecution::numberOfEventCalls)
+            .mapToInt(EventBusTestFixture.EventListenerCountingSuccessfulExecution::numberOfEventCalls)
             .sum();
     }
 
@@ -66,9 +60,9 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchGroupShouldDeliverAllEventsToListenersWithSingleEventBus() throws Exception {
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
 
             eventBus().register(countingListener1, new EventBusTestFixture.GroupA());
             eventBus().register(countingListener2, new EventBusTestFixture.GroupB());
@@ -76,7 +70,7 @@ public interface EventBusConcurrentTestContract {
             int totalGlobalRegistrations = 3; // GroupA + GroupB + GroupC
 
             ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, NO_KEYS).block())
+                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block())
                 .threadCount(THREAD_COUNT)
                 .operationCount(OPERATION_COUNT)
                 .runSuccessfullyWithin(FIVE_SECONDS);
@@ -88,18 +82,18 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchKeyShouldDeliverAllEventsToListenersWithSingleEventBus() throws Exception {
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
-            Mono.from(eventBus().register(countingListener1, KEY_1)).block();
-            Mono.from(eventBus().register(countingListener2, KEY_2)).block();
-            Mono.from(eventBus().register(countingListener3, KEY_3)).block();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            Mono.from(eventBus().register(countingListener1, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(countingListener2, EventBusTestFixture.KEY_2)).block();
+            Mono.from(eventBus().register(countingListener3, EventBusTestFixture.KEY_3)).block();
 
             int totalKeyListenerRegistrations = 3; // KEY1 + KEY2 + KEY3
             int totalEventBus = 1;
 
             ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, ALL_KEYS).block())
+                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EventBusTestFixture.EVENT, ALL_KEYS).block())
                 .threadCount(THREAD_COUNT)
                 .operationCount(OPERATION_COUNT)
                 .runSuccessfullyWithin(FIVE_SECONDS);
@@ -111,9 +105,9 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchShouldDeliverAllEventsToListenersWithSingleEventBus() throws Exception {
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
 
             eventBus().register(countingListener1, new EventBusTestFixture.GroupA());
             eventBus().register(countingListener2, new EventBusTestFixture.GroupB());
@@ -122,14 +116,14 @@ public interface EventBusConcurrentTestContract {
             int totalGlobalRegistrations = 3; // GroupA + GroupB + GroupC
             int totalEventDeliveredGlobally = totalGlobalRegistrations * TOTAL_DISPATCH_OPERATIONS;
 
-            Mono.from(eventBus().register(countingListener1, KEY_1)).block();
-            Mono.from(eventBus().register(countingListener2, KEY_2)).block();
-            Mono.from(eventBus().register(countingListener3, KEY_3)).block();
+            Mono.from(eventBus().register(countingListener1, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(countingListener2, EventBusTestFixture.KEY_2)).block();
+            Mono.from(eventBus().register(countingListener3, EventBusTestFixture.KEY_3)).block();
             int totalKeyListenerRegistrations = 3; // KEY1 + KEY2 + KEY3
             int totalEventDeliveredByKeys = totalKeyListenerRegistrations * TOTAL_DISPATCH_OPERATIONS;
 
             ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, ALL_KEYS).block())
+                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EventBusTestFixture.EVENT, ALL_KEYS).block())
                 .threadCount(THREAD_COUNT)
                 .operationCount(OPERATION_COUNT)
                 .runSuccessfullyWithin(FIVE_SECONDS);
@@ -146,9 +140,9 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchGroupShouldDeliverAllEventsToListenersWithMultipleEventBus() throws Exception {
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
 
             eventBus().register(countingListener1, new EventBusTestFixture.GroupA());
             eventBus().register(countingListener2, new EventBusTestFixture.GroupB());
@@ -161,7 +155,7 @@ public interface EventBusConcurrentTestContract {
             int totalGlobalRegistrations = 3; // GroupA + GroupB + GroupC
 
             ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, NO_KEYS).block())
+                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block())
                 .threadCount(THREAD_COUNT)
                 .operationCount(OPERATION_COUNT)
                 .runSuccessfullyWithin(FIVE_SECONDS);
@@ -173,23 +167,23 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchKeyShouldDeliverAllEventsToListenersWithMultipleEventBus() throws Exception {
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
 
-            Mono.from(eventBus().register(countingListener1, KEY_1)).block();
-            Mono.from(eventBus().register(countingListener2, KEY_2)).block();
-            Mono.from(eventBus().register(countingListener3, KEY_3)).block();
+            Mono.from(eventBus().register(countingListener1, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(countingListener2, EventBusTestFixture.KEY_2)).block();
+            Mono.from(eventBus().register(countingListener3, EventBusTestFixture.KEY_3)).block();
 
-            Mono.from(eventBus2().register(countingListener1, KEY_1)).block();
-            Mono.from(eventBus2().register(countingListener2, KEY_2)).block();
-            Mono.from(eventBus2().register(countingListener3, KEY_3)).block();
+            Mono.from(eventBus2().register(countingListener1, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus2().register(countingListener2, EventBusTestFixture.KEY_2)).block();
+            Mono.from(eventBus2().register(countingListener3, EventBusTestFixture.KEY_3)).block();
 
             int totalKeyListenerRegistrations = 3; // KEY1 + KEY2 + KEY3
             int totalEventBus = 2; // eventBus1 + eventBus2
 
             ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, ALL_KEYS).block())
+                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EventBusTestFixture.EVENT, ALL_KEYS).block())
                 .threadCount(THREAD_COUNT)
                 .operationCount(OPERATION_COUNT)
                 .runSuccessfullyWithin(FIVE_SECONDS);
@@ -201,31 +195,31 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchShouldDeliverAllEventsToListenersWithMultipleEventBus() throws Exception {
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
 
-            eventBus2().register(countingListener1, GROUP_A);
+            eventBus2().register(countingListener1, EventDeadLettersContract.GROUP_A);
             eventBus2().register(countingListener2, new EventBusTestFixture.GroupB());
             eventBus2().register(countingListener3, new EventBusTestFixture.GroupC());
             int totalGlobalRegistrations = 3; // GroupA + GroupB + GroupC
             int totalEventDeliveredGlobally = totalGlobalRegistrations * TOTAL_DISPATCH_OPERATIONS;
 
-            Mono.from(eventBus().register(countingListener1, KEY_1)).block();
-            Mono.from(eventBus().register(countingListener2, KEY_2)).block();
+            Mono.from(eventBus().register(countingListener1, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(countingListener2, EventBusTestFixture.KEY_2)).block();
 
-            Mono.from(eventBus2().register(countingListener1, KEY_1)).block();
-            Mono.from(eventBus2().register(countingListener2, KEY_2)).block();
+            Mono.from(eventBus2().register(countingListener1, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus2().register(countingListener2, EventBusTestFixture.KEY_2)).block();
 
-            Mono.from(eventBus3().register(countingListener3, KEY_1)).block();
-            Mono.from(eventBus3().register(countingListener3, KEY_2)).block();
+            Mono.from(eventBus3().register(countingListener3, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus3().register(countingListener3, EventBusTestFixture.KEY_2)).block();
 
             int totalKeyListenerRegistrations = 2; // KEY1 + KEY2
             int totalEventBus = 3; // eventBus1 + eventBus2 + eventBus3
             int totalEventDeliveredByKeys = totalKeyListenerRegistrations * totalEventBus * TOTAL_DISPATCH_OPERATIONS;
 
             ConcurrentTestRunner.builder()
-                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EVENT, ALL_KEYS).block())
+                .operation((threadNumber, operationNumber) -> eventBus().dispatch(EventBusTestFixture.EVENT, ALL_KEYS).block())
                 .threadCount(THREAD_COUNT)
                 .operationCount(OPERATION_COUNT)
                 .runSuccessfullyWithin(FIVE_SECONDS);
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusContract.java b/mailbox/api/src/test/java/org/apache/james/events/EventBusContract.java
similarity index 98%
copy from mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusContract.java
copy to mailbox/api/src/test/java/org/apache/james/events/EventBusContract.java
index 577697e..c1b52f9 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/events/EventBusContract.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import static org.awaitility.Awaitility.await;
 
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusTestFixture.java b/mailbox/api/src/test/java/org/apache/james/events/EventBusTestFixture.java
similarity index 76%
copy from mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusTestFixture.java
copy to mailbox/api/src/test/java/org/apache/james/events/EventBusTestFixture.java
index b0bd987..e415382 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusTestFixture.java
+++ b/mailbox/api/src/test/java/org/apache/james/events/EventBusTestFixture.java
@@ -17,9 +17,9 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
-import static org.apache.james.mailbox.events.RetryBackoffConfiguration.DEFAULT_JITTER_FACTOR;
+import static org.apache.james.events.RetryBackoffConfiguration.DEFAULT_JITTER_FACTOR;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -29,6 +29,9 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.events.MailboxEvents.MailboxAdded;
+import org.apache.james.events.MailboxEvents.MailboxEvent;
+import org.apache.james.events.MailboxEvents.MailboxRenamed;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
@@ -39,7 +42,7 @@ import com.google.common.collect.ImmutableSet;
 
 public interface EventBusTestFixture {
 
-    class MailboxListenerCountingSuccessfulExecution implements MailboxListener {
+    class EventListenerCountingSuccessfulExecution implements EventListener {
         private final AtomicInteger calls = new AtomicInteger(0);
 
         @Override
@@ -57,7 +60,7 @@ public interface EventBusTestFixture {
         }
     }
 
-    class EventMatcherThrowingListener extends MailboxListenerCountingSuccessfulExecution {
+    class EventMatcherThrowingListener extends EventListenerCountingSuccessfulExecution {
         private final ImmutableSet<Event> eventsCauseThrowing;
 
         EventMatcherThrowingListener(ImmutableSet<Event> eventsCauseThrowing) {
@@ -96,9 +99,9 @@ public interface EventBusTestFixture {
     TestId TEST_ID = TestId.of(18);
     Event.EventId EVENT_ID = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
     Event.EventId EVENT_ID_2 = Event.EventId.of("5a7a9f3f-5f03-44be-b457-a51e93760645");
-    MailboxListener.MailboxEvent EVENT = new MailboxListener.MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, EVENT_ID);
-    MailboxListener.MailboxEvent EVENT_2 = new MailboxListener.MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, EVENT_ID_2);
-    MailboxListener.MailboxRenamed EVENT_UNSUPPORTED_BY_LISTENER = new MailboxListener.MailboxRenamed(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, MAILBOX_PATH, EVENT_ID_2);
+    MailboxEvent EVENT = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, EVENT_ID);
+    MailboxEvent EVENT_2 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, EVENT_ID_2);
+    MailboxRenamed EVENT_UNSUPPORTED_BY_LISTENER = new MailboxRenamed(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, MAILBOX_PATH, EVENT_ID_2);
 
     java.time.Duration ONE_SECOND = java.time.Duration.ofSeconds(1);
     java.time.Duration FIVE_HUNDRED_MS = java.time.Duration.ofMillis(500);
@@ -122,17 +125,17 @@ public interface EventBusTestFixture {
         .jitterFactor(DEFAULT_JITTER_FACTOR)
         .build();
 
-    static MailboxListener newListener() {
-        MailboxListener listener = mock(MailboxListener.class);
-        when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.SYNCHRONOUS);
-        when(listener.isHandling(any(MailboxListener.MailboxAdded.class))).thenReturn(true);
+    static EventListener newListener() {
+        EventListener listener = mock(EventListener.class);
+        when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
+        when(listener.isHandling(any(MailboxAdded.class))).thenReturn(true);
         return listener;
     }
 
-    static MailboxListener newAsyncListener() {
-        MailboxListener listener = mock(MailboxListener.class);
-        when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
-        when(listener.isHandling(any(MailboxListener.MailboxAdded.class))).thenReturn(true);
+    static EventListener newAsyncListener() {
+        EventListener listener = mock(EventListener.class);
+        when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
+        when(listener.isHandling(any(MailboxAdded.class))).thenReturn(true);
         return listener;
     }
 }
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersContract.java b/mailbox/api/src/test/java/org/apache/james/events/EventDeadLettersContract.java
similarity index 97%
copy from mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersContract.java
copy to mailbox/api/src/test/java/org/apache/james/events/EventDeadLettersContract.java
index ebbbdbc..c8f158c 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/events/EventDeadLettersContract.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
@@ -32,6 +32,7 @@ import java.util.stream.Stream;
 
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.events.MailboxEvents.MailboxAdded;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.TestId;
@@ -93,7 +94,7 @@ interface EventDeadLettersContract {
     }
 
     static Event event(Event.EventId eventId) {
-        return new MailboxListener.MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, eventId);
+        return new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, eventId);
     }
 
     List<Group> CONCURRENT_GROUPS = ImmutableList.of(new Group0(), new Group1(), new Group2(), new Group3(), new Group4(), new Group5(),
@@ -109,9 +110,9 @@ interface EventDeadLettersContract {
     Event.EventId EVENT_ID_1 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
     Event.EventId EVENT_ID_2 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b5");
     Event.EventId EVENT_ID_3 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b6");
-    MailboxListener.MailboxAdded EVENT_1 = new MailboxListener.MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_1);
-    MailboxListener.MailboxAdded EVENT_2 = new MailboxListener.MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_2);
-    MailboxListener.MailboxAdded EVENT_3 = new MailboxListener.MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_3);
+    MailboxAdded EVENT_1 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_1);
+    MailboxAdded EVENT_2 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_2);
+    MailboxAdded EVENT_3 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_3);
     EventDeadLetters.InsertionId INSERTION_ID_1 = EventDeadLetters.InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b7");
     EventDeadLetters.InsertionId INSERTION_ID_2 = EventDeadLetters.InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b8");
     EventDeadLetters.InsertionId INSERTION_ID_3 = EventDeadLetters.InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b9");
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersHealthCheckContract.java b/mailbox/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java
similarity index 94%
copy from mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersHealthCheckContract.java
copy to mailbox/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java
index 7c16b7b..6e4dc63 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersHealthCheckContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -25,6 +25,7 @@ import org.apache.james.core.Username;
 import org.apache.james.core.healthcheck.ComponentName;
 import org.apache.james.core.healthcheck.Result;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.events.MailboxEvents.MailboxAdded;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.TestId;
@@ -41,8 +42,8 @@ interface EventDeadLettersHealthCheckContract {
     TestId MAILBOX_ID = TestId.of(563);
     Event.EventId EVENT_ID_1 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
     Event.EventId EVENT_ID_2 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b5");
-    MailboxListener.MailboxAdded EVENT_1 = new MailboxListener.MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_1);
-    MailboxListener.MailboxAdded EVENT_2 = new MailboxListener.MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_2);
+    MailboxAdded EVENT_1 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_1);
+    MailboxAdded EVENT_2 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_2);
 
     Group GROUP_A = new EventBusTestFixture.GroupA();
     Group GROUP_B = new EventBusTestFixture.GroupB();
diff --git a/mailbox/api/src/test/java/org/apache/james/events/GroupContract.java b/mailbox/api/src/test/java/org/apache/james/events/GroupContract.java
new file mode 100644
index 0000000..648b6e2
--- /dev/null
+++ b/mailbox/api/src/test/java/org/apache/james/events/GroupContract.java
@@ -0,0 +1,487 @@
+/****************************************************************
+ * 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.events;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.after;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.time.Duration;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.IntStream;
+
+import org.apache.james.core.Username;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.events.MailboxEvents.Added;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.TestId;
+import org.apache.james.events.EventBusTestFixture.TestEvent;
+import org.apache.james.mailbox.events.GenericGroup;
+import org.junit.jupiter.api.Test;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSortedMap;
+
+import reactor.core.scheduler.Schedulers;
+
+public interface GroupContract {
+
+    interface SingleEventBusGroupContract extends EventBusContract {
+
+        @Test
+        default void groupDeliveryShouldNotExceedRate() {
+            int eventCount = 50;
+            AtomicInteger nbCalls = new AtomicInteger(0);
+            AtomicInteger finishedExecutions = new AtomicInteger(0);
+            AtomicBoolean rateExceeded = new AtomicBoolean(false);
+
+            eventBus().register(new EventListener.GroupEventListener() {
+                @Override
+                public Group getDefaultGroup() {
+                    return new GenericGroup("group");
+                }
+
+                @Override
+                public boolean isHandling(Event event) {
+                    return true;
+                }
+
+                @Override
+                public void event(Event event) throws Exception {
+                    if (nbCalls.get() - finishedExecutions.get() > EventBus.EXECUTION_RATE) {
+                        rateExceeded.set(true);
+                    }
+                    nbCalls.incrementAndGet();
+                    Thread.sleep(Duration.ofMillis(20).toMillis());
+                    finishedExecutions.incrementAndGet();
+
+                }
+            }, EventBusTestFixture.GROUP_A);
+
+            IntStream.range(0, eventCount)
+                .forEach(i -> eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block());
+
+            getSpeedProfile().shortWaitCondition().atMost(org.awaitility.Duration.TEN_MINUTES)
+                .untilAsserted(() -> assertThat(finishedExecutions.get()).isEqualTo(eventCount));
+            assertThat(rateExceeded).isFalse();
+        }
+
+        @Test
+        default void groupNotificationShouldDeliverASingleEventToAllListenersAtTheSameTime() {
+            CountDownLatch countDownLatch = new CountDownLatch(1);
+            try {
+                ConcurrentLinkedQueue<String> threads = new ConcurrentLinkedQueue<>();
+                eventBus().register(new EventListener.GroupEventListener() {
+                    @Override
+                    public Group getDefaultGroup() {
+                        return new GenericGroup("groupA");
+                    }
+
+                    @Override
+                    public void event(Event event) throws Exception {
+                        threads.add(Thread.currentThread().getName());
+                        countDownLatch.await();
+                    }
+                }, EventBusTestFixture.GROUP_A);
+                eventBus().register(new EventListener.GroupEventListener() {
+                    @Override
+                    public Group getDefaultGroup() {
+                        return new GenericGroup("groupB");
+                    }
+
+                    @Override
+                    public void event(Event event) throws Exception {
+                        threads.add(Thread.currentThread().getName());
+                        countDownLatch.await();
+                    }
+                }, EventBusTestFixture.GROUP_B);
+                eventBus().register(new EventListener.GroupEventListener() {
+                    @Override
+                    public Group getDefaultGroup() {
+                        return new GenericGroup("groupC");
+                    }
+
+                    @Override
+                    public void event(Event event) throws Exception {
+                        threads.add(Thread.currentThread().getName());
+                        countDownLatch.await();
+                    }
+                }, EventBusTestFixture.GROUP_C);
+
+                eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).subscribeOn(Schedulers.elastic()).subscribe();
+
+
+                getSpeedProfile().shortWaitCondition().atMost(org.awaitility.Duration.TEN_SECONDS)
+                    .untilAsserted(() -> assertThat(threads).hasSize(3));
+                assertThat(threads).doesNotHaveDuplicates();
+            } finally {
+                countDownLatch.countDown();
+            }
+        }
+
+        @Test
+        default void listenersShouldBeAbleToDispatch() {
+            AtomicBoolean successfulRetry = new AtomicBoolean(false);
+            EventListener listener = event -> {
+                if (event.getEventId().equals(EventBusTestFixture.EVENT_ID)) {
+                    eventBus().dispatch(EventBusTestFixture.EVENT_2, EventBusTestFixture.NO_KEYS)
+                        .subscribeOn(Schedulers.elastic())
+                        .block();
+                    successfulRetry.set(true);
+                }
+            };
+
+            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+
+            getSpeedProfile().shortWaitCondition().until(successfulRetry::get);
+        }
+
+        @Test
+        default void registerShouldNotDispatchPastEventsForGroups() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+
+            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+
+            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+                .event(any());
+        }
+
+        @Test
+        default void listenerGroupShouldReceiveEvents() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+
+            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void groupListenersShouldNotReceiveNoopEvents() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+
+            Username bob = Username.of("bob");
+            Added noopEvent = new Added(MailboxSession.SessionId.of(18), bob, MailboxPath.forUser(bob, "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
+            eventBus().dispatch(noopEvent, EventBusTestFixture.NO_KEYS).block();
+
+            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+                .event(any());
+        }
+
+        @Test
+        default void groupListenersShouldReceiveOnlyHandledEvents() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+
+            eventBus().dispatch(EventBusTestFixture.EVENT_UNSUPPORTED_BY_LISTENER, EventBusTestFixture.NO_KEYS).block();
+
+            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+                .event(any());
+        }
+
+        @Test
+        default void dispatchShouldNotThrowWhenAGroupListenerFails() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            doThrow(new RuntimeException()).when(listener).event(any());
+
+            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+
+            assertThatCode(() -> eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block())
+                .doesNotThrowAnyException();
+        }
+
+        @Test
+        default void eachListenerGroupShouldReceiveEvents() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            EventListener listener2 = EventBusTestFixture.newListener();
+            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            eventBus().register(listener2, EventBusTestFixture.GROUP_B);
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+
+            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener2, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void unregisteredGroupListenerShouldNotReceiveEvents() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            Registration registration = eventBus().register(listener, EventBusTestFixture.GROUP_A);
+
+            registration.unregister();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+                .event(any());
+        }
+
+        @Test
+        default void registerShouldThrowWhenAGroupIsAlreadyUsed() {
+            EventListener listener = EventBusTestFixture.newListener();
+            EventListener listener2 = EventBusTestFixture.newListener();
+
+            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+
+            assertThatThrownBy(() -> eventBus().register(listener2, EventBusTestFixture.GROUP_A))
+                .isInstanceOf(GroupAlreadyRegistered.class);
+        }
+
+        @Test
+        default void registerShouldNotThrowOnAnUnregisteredGroup() {
+            EventListener listener = EventBusTestFixture.newListener();
+            EventListener listener2 = EventBusTestFixture.newListener();
+
+            eventBus().register(listener, EventBusTestFixture.GROUP_A).unregister();
+
+            assertThatCode(() -> eventBus().register(listener2, EventBusTestFixture.GROUP_A))
+                .doesNotThrowAnyException();
+        }
+
+        @Test
+        default void unregisterShouldBeIdempotentForGroups() {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            Registration registration = eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            registration.unregister();
+
+            assertThatCode(registration::unregister)
+                .doesNotThrowAnyException();
+        }
+
+        @Test
+        default void registerShouldAcceptAlreadyUnregisteredGroups() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            eventBus().register(listener, EventBusTestFixture.GROUP_A).unregister();
+            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+
+            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void dispatchShouldCallSynchronousListener() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+
+            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void failingGroupListenersShouldNotAbortGroupDelivery() {
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution listener = new EventBusTestFixture.EventMatcherThrowingListener(ImmutableSet.of(EventBusTestFixture.EVENT));
+            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+            eventBus().dispatch(EventBusTestFixture.EVENT_2, EventBusTestFixture.NO_KEYS).block();
+
+            getSpeedProfile().shortWaitCondition()
+                .untilAsserted(() -> assertThat(listener.numberOfEventCalls()).isEqualTo(1));
+        }
+
+        @Test
+        default void allGroupListenersShouldBeExecutedWhenAGroupListenerFails() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            EventListener failingListener = mock(EventListener.class);
+            when(failingListener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
+            doThrow(new RuntimeException()).when(failingListener).event(any());
+
+            eventBus().register(failingListener, EventBusTestFixture.GROUP_A);
+            eventBus().register(listener, EventBusTestFixture.GROUP_B);
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+
+            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void allGroupListenersShouldBeExecutedWhenGenericGroups() throws Exception {
+            EventListener listener1 = EventBusTestFixture.newListener();
+            EventListener listener2 = EventBusTestFixture.newListener();
+
+            eventBus().register(listener1, new GenericGroup("a"));
+            eventBus().register(listener2, new GenericGroup("b"));
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+
+            verify(listener1, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener2, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void groupListenerShouldReceiveEventWhenRedeliver() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+
+            eventBus().reDeliver(EventBusTestFixture.GROUP_A, EventBusTestFixture.EVENT).block();
+
+            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void redeliverShouldNotThrowWhenAGroupListenerFails() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            doThrow(new RuntimeException()).when(listener).event(any());
+
+            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+
+            assertThatCode(() -> eventBus().reDeliver(EventBusTestFixture.GROUP_A, EventBusTestFixture.EVENT).block())
+                .doesNotThrowAnyException();
+        }
+
+        @Test
+        default void redeliverShouldThrowWhenGroupNotRegistered() {
+            assertThatThrownBy(() -> eventBus().reDeliver(EventBusTestFixture.GROUP_A, EventBusTestFixture.EVENT).block())
+                .isInstanceOf(GroupRegistrationNotFound.class);
+        }
+
+        @Test
+        default void redeliverShouldThrowAfterGroupIsUnregistered() {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            eventBus().register(listener, EventBusTestFixture.GROUP_A).unregister();
+
+            assertThatThrownBy(() -> eventBus().reDeliver(EventBusTestFixture.GROUP_A, EventBusTestFixture.EVENT).block())
+                .isInstanceOf(GroupRegistrationNotFound.class);
+        }
+
+        @Test
+        default void redeliverShouldOnlySendEventToDefinedGroup() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            EventListener listener2 = EventBusTestFixture.newListener();
+            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+            eventBus().register(listener2, EventBusTestFixture.GROUP_B);
+
+            eventBus().reDeliver(EventBusTestFixture.GROUP_A, EventBusTestFixture.EVENT).block();
+
+            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener2, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never()).event(any());
+        }
+
+        @Test
+        default void groupListenersShouldNotReceiveNoopRedeliveredEvents() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            eventBus().register(listener, EventBusTestFixture.GROUP_A);
+
+            Username bob = Username.of("bob");
+            Added noopEvent = new Added(MailboxSession.SessionId.of(18), bob, MailboxPath.forUser(bob, "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
+            eventBus().reDeliver(EventBusTestFixture.GROUP_A, noopEvent).block();
+
+            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never()).event(any());
+        }
+    }
+
+    interface MultipleEventBusGroupContract extends EventBusContract.MultipleEventBusContract {
+
+        @Test
+        default void groupsDefinedOnlyOnSomeNodesShouldBeNotifiedWhenDispatch() throws Exception {
+            EventListener mailboxListener = EventBusTestFixture.newListener();
+
+            eventBus().register(mailboxListener, EventBusTestFixture.GROUP_A);
+
+            eventBus2().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+
+            verify(mailboxListener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void groupsDefinedOnlyOnSomeNodesShouldNotBeNotifiedWhenRedeliver() {
+            EventListener mailboxListener = EventBusTestFixture.newListener();
+
+            eventBus().register(mailboxListener, EventBusTestFixture.GROUP_A);
+
+            assertThatThrownBy(() -> eventBus2().reDeliver(EventBusTestFixture.GROUP_A, EventBusTestFixture.EVENT).block())
+                .isInstanceOf(GroupRegistrationNotFound.class);
+        }
+
+        @Test
+        default void groupListenersShouldBeExecutedOnceWhenRedeliverInADistributedEnvironment() throws Exception {
+            EventListener mailboxListener = EventBusTestFixture.newListener();
+
+            eventBus().register(mailboxListener, EventBusTestFixture.GROUP_A);
+            eventBus2().register(mailboxListener, EventBusTestFixture.GROUP_A);
+
+            eventBus2().reDeliver(EventBusTestFixture.GROUP_A, EventBusTestFixture.EVENT).block();
+
+            verify(mailboxListener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void groupListenersShouldBeExecutedOnceInAControlledEnvironment() throws Exception {
+            EventListener mailboxListener = EventBusTestFixture.newListener();
+
+            eventBus().register(mailboxListener, EventBusTestFixture.GROUP_A);
+            eventBus2().register(mailboxListener, EventBusTestFixture.GROUP_A);
+
+            eventBus2().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+
+            verify(mailboxListener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void unregisterShouldStopNotificationForDistantGroups() throws Exception {
+            EventListener mailboxListener = EventBusTestFixture.newListener();
+
+            eventBus().register(mailboxListener, EventBusTestFixture.GROUP_A).unregister();
+
+            eventBus2().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+
+
+            verify(mailboxListener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+                .event(any());
+        }
+
+        @Test
+        default void registerShouldNotDispatchPastEventsForGroupsInADistributedContext() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+
+            eventBus2().register(listener, EventBusTestFixture.GROUP_A);
+
+            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+                .event(any());
+        }
+    }
+}
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupTest.java b/mailbox/api/src/test/java/org/apache/james/events/GroupTest.java
similarity index 98%
copy from mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupTest.java
copy to mailbox/api/src/test/java/org/apache/james/events/GroupTest.java
index 617e191..1b02148 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/events/GroupTest.java
@@ -17,11 +17,12 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
+import org.apache.james.mailbox.events.GenericGroup;
 import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/InsertionIdTest.java b/mailbox/api/src/test/java/org/apache/james/events/InsertionIdTest.java
similarity index 96%
copy from mailbox/api/src/test/java/org/apache/james/mailbox/events/InsertionIdTest.java
copy to mailbox/api/src/test/java/org/apache/james/events/InsertionIdTest.java
index f8a1e0e..d592590 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/InsertionIdTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/events/InsertionIdTest.java
@@ -17,13 +17,14 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.util.UUID;
 
+import org.apache.james.events.EventDeadLetters;
 import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
diff --git a/mailbox/api/src/test/java/org/apache/james/events/KeyContract.java b/mailbox/api/src/test/java/org/apache/james/events/KeyContract.java
new file mode 100644
index 0000000..9eb4819
--- /dev/null
+++ b/mailbox/api/src/test/java/org/apache/james/events/KeyContract.java
@@ -0,0 +1,445 @@
+/****************************************************************
+ * 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.events;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.junit.jupiter.api.Assertions.assertTimeout;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.after;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.time.Duration;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.IntStream;
+
+import org.apache.james.core.Username;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.events.MailboxEvents.Added;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.TestId;
+import org.junit.jupiter.api.Test;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSortedMap;
+
+import reactor.core.publisher.Mono;
+import reactor.core.scheduler.Schedulers;
+
+public interface KeyContract extends EventBusContract {
+
+    interface SingleEventBusKeyContract extends EventBusContract {
+        @Test
+        default void notificationShouldNotExceedRate() {
+            int eventCount = 50;
+            AtomicInteger nbCalls = new AtomicInteger(0);
+            AtomicInteger finishedExecutions = new AtomicInteger(0);
+            AtomicBoolean rateExceeded = new AtomicBoolean(false);
+
+            Mono.from(eventBus().register(event -> {
+                if (nbCalls.get() - finishedExecutions.get() > EventBus.EXECUTION_RATE) {
+                    rateExceeded.set(true);
+                }
+                nbCalls.incrementAndGet();
+                Thread.sleep(Duration.ofMillis(20).toMillis());
+                finishedExecutions.incrementAndGet();
+
+            }, EventBusTestFixture.KEY_1)).block();
+
+            IntStream.range(0, eventCount)
+                .forEach(i -> eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.KEY_1).block());
+
+            getSpeedProfile().shortWaitCondition().atMost(org.awaitility.Duration.TEN_MINUTES)
+                .untilAsserted(() -> assertThat(finishedExecutions.get()).isEqualTo(eventCount));
+            assertThat(rateExceeded).isFalse();
+        }
+
+        @Test
+        default void notificationShouldDeliverASingleEventToAllListenersAtTheSameTime() {
+            CountDownLatch countDownLatch = new CountDownLatch(1);
+            try {
+                ConcurrentLinkedQueue<String> threads = new ConcurrentLinkedQueue<>();
+                Mono.from(eventBus().register(event -> {
+                    threads.add(Thread.currentThread().getName());
+                    countDownLatch.await();
+                }, EventBusTestFixture.KEY_1)).block();
+                Mono.from(eventBus().register(event -> {
+                    threads.add(Thread.currentThread().getName());
+                    countDownLatch.await();
+                }, EventBusTestFixture.KEY_1)).block();
+                Mono.from(eventBus().register(event -> {
+                    threads.add(Thread.currentThread().getName());
+                    countDownLatch.await();
+                }, EventBusTestFixture.KEY_1)).block();
+
+                eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.KEY_1).subscribeOn(Schedulers.elastic()).subscribe();
+
+
+                getSpeedProfile().shortWaitCondition().atMost(org.awaitility.Duration.TEN_SECONDS)
+                    .untilAsserted(() -> assertThat(threads).hasSize(3));
+                assertThat(threads).doesNotHaveDuplicates();
+            } finally {
+                countDownLatch.countDown();
+            }
+        }
+
+
+        @Test
+        default void registeredListenersShouldNotReceiveNoopEvents() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+
+            Username bob = Username.of("bob");
+            Added noopEvent = new Added(MailboxSession.SessionId.of(18), bob, MailboxPath.forUser(bob, "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
+            eventBus().dispatch(noopEvent, EventBusTestFixture.KEY_1).block();
+
+            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+                .event(any());
+        }
+
+       @Test
+        default void registeredListenersShouldReceiveOnlyHandledEvents() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT_UNSUPPORTED_BY_LISTENER, EventBusTestFixture.KEY_1).block();
+
+            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+                .event(any());
+        }
+
+        @Test
+        default void dispatchShouldNotThrowWhenARegisteredListenerFails() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            doThrow(new RuntimeException()).when(listener).event(any());
+
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+
+            assertThatCode(() -> eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block())
+                .doesNotThrowAnyException();
+        }
+
+        @Test
+        default void dispatchShouldNotNotifyRegisteredListenerWhenEmptyKeySet() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+
+            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+                .event(any());
+        }
+
+        @Test
+        default void dispatchShouldNotNotifyListenerRegisteredOnOtherKeys() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_2)).block();
+
+            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+                .event(any());
+        }
+
+        @Test
+        default void dispatchShouldNotifyRegisteredListeners() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+
+            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void dispatchShouldNotifyLocalRegisteredListenerWithoutDelay() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+
+            verify(listener, times(1)).event(any());
+        }
+
+        @Test
+        default void dispatchShouldNotifyOnlyRegisteredListener() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            EventListener listener2 = EventBusTestFixture.newListener();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener2, EventBusTestFixture.KEY_2)).block();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+
+            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener2, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+                .event(any());
+        }
+
+        @Test
+        default void dispatchShouldNotifyAllListenersRegisteredOnAKey() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            EventListener listener2 = EventBusTestFixture.newListener();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener2, EventBusTestFixture.KEY_1)).block();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+
+            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(listener2, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void registerShouldAllowDuplicatedRegistration() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+
+            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void unregisterShouldRemoveDoubleRegisteredListener() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block().unregister();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+
+            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+                .event(any());
+        }
+
+        @Test
+        default void registerShouldNotDispatchPastEvents() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+
+            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+                .event(any());
+        }
+
+        @Test
+        default void callingAllUnregisterMethodShouldUnregisterTheListener() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            Registration registration = Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block().unregister();
+            registration.unregister();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+
+            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+                .event(any());
+        }
+
+        @Test
+        default void unregisterShouldHaveNotNotifyWhenCalledOnDifferentKeys() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_2)).block().unregister();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+
+            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void unregisterShouldBeIdempotentForKeyRegistrations() {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            Registration registration = Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            registration.unregister();
+
+            assertThatCode(registration::unregister)
+                .doesNotThrowAnyException();
+        }
+
+        @Test
+        default void dispatchShouldAcceptSeveralKeys() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1, EventBusTestFixture.KEY_2)).block();
+
+            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void dispatchShouldCallListenerOnceWhenSeveralKeysMatching() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_2)).block();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1, EventBusTestFixture.KEY_2)).block();
+
+            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void dispatchShouldNotNotifyUnregisteredListener() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block().unregister();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+
+            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+                .event(any());
+        }
+
+
+        @Test
+        default void dispatchShouldNotifyAsynchronousListener() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.KEY_1).block();
+
+            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis())).event(EventBusTestFixture.EVENT);
+        }
+
+        @Test
+        default void dispatchShouldNotBlockAsynchronousListener() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
+            CountDownLatch latch = new CountDownLatch(1);
+            doAnswer(invocation -> {
+                latch.await();
+                return null;
+            }).when(listener).event(EventBusTestFixture.EVENT);
+
+            assertTimeout(Duration.ofSeconds(2),
+                () -> {
+                    eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.NO_KEYS).block();
+                    latch.countDown();
+                });
+        }
+
+        @Test
+        default void failingRegisteredListenersShouldNotAbortRegisteredDelivery() {
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution listener = new EventBusTestFixture.EventMatcherThrowingListener(ImmutableSet.of(EventBusTestFixture.EVENT));
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.KEY_1).block();
+            eventBus().dispatch(EventBusTestFixture.EVENT_2, EventBusTestFixture.KEY_1).block();
+
+            getSpeedProfile().shortWaitCondition()
+                .untilAsserted(() -> assertThat(listener.numberOfEventCalls()).isEqualTo(1));
+        }
+
+        @Test
+        default void allRegisteredListenersShouldBeExecutedWhenARegisteredListenerFails() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            EventListener failingListener = mock(EventListener.class);
+            when(failingListener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
+            doThrow(new RuntimeException()).when(failingListener).event(any());
+
+            Mono.from(eventBus().register(failingListener, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+
+            eventBus().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+
+            verify(listener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+    }
+
+    interface MultipleEventBusKeyContract extends MultipleEventBusContract {
+
+        @Test
+        default void crossEventBusRegistrationShouldBeAllowed() throws Exception {
+            EventListener mailboxListener = EventBusTestFixture.newListener();
+
+            Mono.from(eventBus().register(mailboxListener, EventBusTestFixture.KEY_1)).block();
+
+            eventBus2().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.KEY_1).block();
+
+            verify(mailboxListener, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void unregisteredDistantListenersShouldNotBeNotified() throws Exception {
+            EventListener eventListener = EventBusTestFixture.newListener();
+
+            Mono.from(eventBus().register(eventListener, EventBusTestFixture.KEY_1)).block().unregister();
+
+            eventBus2().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+
+            verify(eventListener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+                .event(any());
+        }
+
+        @Test
+        default void allRegisteredListenersShouldBeDispatched() throws Exception {
+            EventListener mailboxListener1 = EventBusTestFixture.newListener();
+            EventListener mailboxListener2 = EventBusTestFixture.newListener();
+
+            Mono.from(eventBus().register(mailboxListener1, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus2().register(mailboxListener2, EventBusTestFixture.KEY_1)).block();
+
+            eventBus2().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.KEY_1).block();
+
+            verify(mailboxListener1, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+            verify(mailboxListener2, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+        @Test
+        default void registerShouldNotDispatchPastEventsInDistributedContext() throws Exception {
+            EventListener listener = EventBusTestFixture.newListener();
+
+            eventBus2().dispatch(EventBusTestFixture.EVENT, ImmutableSet.of(EventBusTestFixture.KEY_1)).block();
+
+            Mono.from(eventBus().register(listener, EventBusTestFixture.KEY_1)).block();
+
+            verify(listener, after(EventBusTestFixture.FIVE_HUNDRED_MS.toMillis()).never())
+                .event(any());
+        }
+
+        @Test
+        default void localDispatchedListenersShouldBeDispatchedWithoutDelay() throws Exception {
+            EventListener mailboxListener1 = EventBusTestFixture.newListener();
+            EventListener mailboxListener2 = EventBusTestFixture.newListener();
+
+            Mono.from(eventBus().register(mailboxListener1, EventBusTestFixture.KEY_1)).block();
+            Mono.from(eventBus2().register(mailboxListener2, EventBusTestFixture.KEY_1)).block();
+
+            eventBus2().dispatch(EventBusTestFixture.EVENT, EventBusTestFixture.KEY_1).block();
+
+            verify(mailboxListener2, times(1)).event(any());
+            verify(mailboxListener1, timeout(EventBusTestFixture.ONE_SECOND.toMillis()).times(1)).event(any());
+        }
+
+    }
+}
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/InsertionIdTest.java b/mailbox/api/src/test/java/org/apache/james/events/MailboxIdRegistrationKeyTest.java
similarity index 59%
copy from mailbox/api/src/test/java/org/apache/james/mailbox/events/InsertionIdTest.java
copy to mailbox/api/src/test/java/org/apache/james/events/MailboxIdRegistrationKeyTest.java
index f8a1e0e..0fb1de2 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/InsertionIdTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/events/MailboxIdRegistrationKeyTest.java
@@ -17,40 +17,44 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
-import java.util.UUID;
-
+import org.apache.james.mailbox.model.TestId;
 import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
 
-class InsertionIdTest {
-    private static final UUID UUID_1 = UUID.fromString("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
+class MailboxIdRegistrationKeyTest {
+    private static final String ID = "42";
+
+    private static final MailboxIdRegistrationKey.Factory FACTORY = new MailboxIdRegistrationKey.Factory(new TestId.Factory());
+
+    private static final MailboxIdRegistrationKey MAILBOX_ID_REGISTRATION_KEY = new MailboxIdRegistrationKey((TestId.of(42)));
 
     @Test
-    void eventIdShouldMatchBeanContract() {
-        EqualsVerifier.forClass(EventDeadLetters.InsertionId.class).verify();
+    void shouldRespectBeanContract() {
+        EqualsVerifier.forClass(MailboxIdRegistrationKey.class)
+            .verify();
     }
 
     @Test
-    void ofShouldDeserializeUUIDs() {
-        assertThat(EventDeadLetters.InsertionId.of(UUID_1.toString()))
-            .isEqualTo(EventDeadLetters.InsertionId.of(UUID_1));
+    void asStringShouldReturnSerializedMailboxId() {
+        assertThat(MAILBOX_ID_REGISTRATION_KEY.asString())
+            .isEqualTo(ID);
     }
 
     @Test
-    void ofStringShouldThrowOnNullValue() {
-        assertThatThrownBy(() -> EventDeadLetters.InsertionId.of((String) null))
-            .isInstanceOf(NullPointerException.class);
+    void fromStringShouldReturnCorrespondingRegistrationKey() {
+        assertThat(FACTORY.fromString(ID))
+            .isEqualTo(MAILBOX_ID_REGISTRATION_KEY);
     }
 
     @Test
-    void ofUuidShouldThrowOnNullValue() {
-        assertThatThrownBy(() -> EventDeadLetters.InsertionId.of((UUID) null))
-            .isInstanceOf(NullPointerException.class);
+    void fromStringShouldThrowOnInvalidValues() {
+        assertThatThrownBy(() -> FACTORY.fromString("invalid"))
+            .isInstanceOf(IllegalArgumentException.class);
     }
-}
+}
\ No newline at end of file
diff --git a/mailbox/api/src/test/java/org/apache/james/events/RetryBackoffConfigurationTest.java b/mailbox/api/src/test/java/org/apache/james/events/RetryBackoffConfigurationTest.java
new file mode 100644
index 0000000..5718e63
--- /dev/null
+++ b/mailbox/api/src/test/java/org/apache/james/events/RetryBackoffConfigurationTest.java
@@ -0,0 +1,141 @@
+/****************************************************************
+ * 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.events;
+
+import static org.apache.james.events.RetryBackoffConfiguration.DEFAULT_FIRST_BACKOFF;
+import static org.apache.james.events.RetryBackoffConfiguration.DEFAULT_JITTER_FACTOR;
+import static org.apache.james.events.RetryBackoffConfiguration.DEFAULT_MAX_RETRIES;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.time.Duration;
+
+import org.assertj.core.api.SoftAssertions;
+import org.junit.jupiter.api.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+class RetryBackoffConfigurationTest {
+
+    @Test
+    void shouldMatchBeanContract() {
+        EqualsVerifier.forClass(RetryBackoffConfiguration.class)
+            .verify();
+    }
+
+    @Test
+    void buildShouldThrowWhenNegativeFirstBackoff() {
+        assertThatThrownBy(() -> RetryBackoffConfiguration.builder()
+            .maxRetries(DEFAULT_MAX_RETRIES)
+            .firstBackoff(Duration.ofMillis(-1000L))
+            .jitterFactor(DEFAULT_JITTER_FACTOR)
+            .build())
+        .isInstanceOf(IllegalArgumentException.class)
+        .hasMessage("firstBackoff is not allowed to be negative");
+    }
+
+    @Test
+    void buildShouldThrowWhenNegativeMaxRetries() {
+        assertThatThrownBy(() -> RetryBackoffConfiguration.builder()
+            .maxRetries(-6)
+            .firstBackoff(DEFAULT_FIRST_BACKOFF)
+            .jitterFactor(DEFAULT_JITTER_FACTOR)
+            .build())
+        .isInstanceOf(IllegalArgumentException.class)
+        .hasMessage("maxRetries is not allowed to be negative");
+    }
+
+    @Test
+    void buildShouldThrowWhenNegativeJitterFactor() {
+        assertThatThrownBy(() -> RetryBackoffConfiguration.builder()
+            .maxRetries(DEFAULT_MAX_RETRIES)
+            .firstBackoff(DEFAULT_FIRST_BACKOFF)
+            .jitterFactor(-2.5)
+            .build())
+        .isInstanceOf(IllegalArgumentException.class)
+        .hasMessage("jitterFactor is not allowed to be negative or greater than 1");
+    }
+
+    @Test
+    void buildShouldThrowWhenGreaterThanOneJitterFactor() {
+        assertThatThrownBy(() -> RetryBackoffConfiguration.builder()
+            .maxRetries(DEFAULT_MAX_RETRIES)
+            .firstBackoff(DEFAULT_FIRST_BACKOFF)
+            .jitterFactor(1.000001)
+            .build())
+        .isInstanceOf(IllegalArgumentException.class)
+        .hasMessage("jitterFactor is not allowed to be negative or greater than 1");
+    }
+
+    @Test
+    void buildShouldSuccessWhenZeroFirstBackoff() {
+        RetryBackoffConfiguration retryBackoff = RetryBackoffConfiguration.builder()
+            .maxRetries(DEFAULT_MAX_RETRIES)
+            .firstBackoff(Duration.ZERO)
+            .jitterFactor(DEFAULT_JITTER_FACTOR)
+            .build();
+
+        assertThat(retryBackoff.getFirstBackoff().toMillis())
+            .isEqualTo(0L);
+    }
+
+    @Test
+    void buildShouldSuccessWhenZeroMaxRetries() {
+        RetryBackoffConfiguration retryBackoff = RetryBackoffConfiguration.builder()
+            .maxRetries(0)
+            .firstBackoff(DEFAULT_FIRST_BACKOFF)
+            .jitterFactor(DEFAULT_JITTER_FACTOR)
+            .build();
+
+        assertThat(retryBackoff.getMaxRetries())
+            .isEqualTo(0L);
+    }
+
+    @Test
+    void buildShouldSuccessWhenZeroJitterFactor() {
+        RetryBackoffConfiguration retryBackoff = RetryBackoffConfiguration.builder()
+            .maxRetries(DEFAULT_MAX_RETRIES)
+            .firstBackoff(DEFAULT_FIRST_BACKOFF)
+            .jitterFactor(0)
+            .build();
+
+        assertThat(retryBackoff.getJitterFactor())
+            .isEqualTo(0);
+    }
+
+    @Test
+    void buildShouldReturnCorrespondingValues() {
+        RetryBackoffConfiguration retryBackoff = RetryBackoffConfiguration.builder()
+            .maxRetries(5)
+            .firstBackoff(Duration.ofMillis(200))
+            .jitterFactor(0.6)
+            .build();
+
+        SoftAssertions.assertSoftly(softly -> {
+            softly.assertThat(retryBackoff.getJitterFactor())
+                .isEqualTo(0.6);
+            softly.assertThat(retryBackoff.getMaxRetries())
+                .isEqualTo(5);
+            softly.assertThat(retryBackoff.getFirstBackoff())
+                .isEqualTo(Duration.ofMillis(200));
+        });
+    }
+
+}
\ No newline at end of file
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/EventTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/EventTest.java
index 6c1c687..c25f7df 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/EventTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/EventTest.java
@@ -27,8 +27,8 @@ import java.util.UUID;
 import javax.mail.Flags;
 
 import org.apache.james.core.Username;
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.events.Event;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.TestId;
@@ -56,7 +56,7 @@ class EventTest {
 
     @Test
     void getMessageIdsShouldReturnEmptyWhenAddedEmpty() {
-        MailboxListener.Added added = new MailboxListener.Added(MailboxSession.SessionId.of(36), BOB, MailboxPath.inbox(BOB), TestId.of(48), ImmutableSortedMap.of(), Event.EventId.of(UUID_1));
+        Added added = new Added(MailboxSession.SessionId.of(36), BOB, MailboxPath.inbox(BOB), TestId.of(48), ImmutableSortedMap.of(), Event.EventId.of(UUID_1));
 
         assertThat(added.getMessageIds()).isEmpty();
     }
@@ -70,7 +70,7 @@ class EventTest {
         MessageMetaData metaData1 = new MessageMetaData(uid1, ModSeq.of(85), new Flags(), 36, new Date(), messageId1);
         MessageMetaData metaData2 = new MessageMetaData(uid2, ModSeq.of(85), new Flags(), 36, new Date(), messageId2);
 
-        MailboxListener.Added added = new MailboxListener.Added(MailboxSession.SessionId.of(36), BOB, MailboxPath.inbox(BOB), TestId.of(48),
+        Added added = new Added(MailboxSession.SessionId.of(36), BOB, MailboxPath.inbox(BOB), TestId.of(48),
             ImmutableSortedMap.of(
                 uid1, metaData1,
                 uid2, metaData2),
@@ -87,7 +87,7 @@ class EventTest {
         MessageMetaData metaData1 = new MessageMetaData(uid1, ModSeq.of(85), new Flags(), 36, new Date(), messageId);
         MessageMetaData metaData2 = new MessageMetaData(uid2, ModSeq.of(85), new Flags(), 36, new Date(), messageId);
 
-        MailboxListener.Added added = new MailboxListener.Added(MailboxSession.SessionId.of(36), BOB, MailboxPath.inbox(BOB), TestId.of(48),
+        Added added = new Added(MailboxSession.SessionId.of(36), BOB, MailboxPath.inbox(BOB), TestId.of(48),
             ImmutableSortedMap.of(
                 uid1, metaData1,
                 uid2, metaData2),
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxListenerTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxListenerTest.java
index 646af57..13fa417 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxListenerTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxListenerTest.java
@@ -33,9 +33,16 @@ import org.apache.james.core.quota.QuotaCountLimit;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
+import org.apache.james.events.Event;
 import org.apache.james.mailbox.acl.ACLDiff;
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxACLUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxRenamed;
+import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageMetaData;
@@ -69,42 +76,42 @@ class MailboxListenerTest {
 
     @Test
     void mailboxAddedShouldMatchBeanContract() {
-        EqualsVerifier.forClass(MailboxListener.MailboxAdded.class).verify();
+        EqualsVerifier.forClass(MailboxAdded.class).verify();
     }
 
     @Test
     void mailboxRenamedShouldMatchBeanContract() {
-        EqualsVerifier.forClass(MailboxListener.MailboxRenamed.class).verify();
+        EqualsVerifier.forClass(MailboxRenamed.class).verify();
     }
 
     @Test
     void mailboxDeletionShouldMatchBeanContract() {
-        EqualsVerifier.forClass(MailboxListener.MailboxDeletion.class).verify();
+        EqualsVerifier.forClass(MailboxDeletion.class).verify();
     }
 
     @Test
     void mailboxACLUpdatedShouldMatchBeanContract() {
-        EqualsVerifier.forClass(MailboxListener.MailboxACLUpdated.class).verify();
+        EqualsVerifier.forClass(MailboxACLUpdated.class).verify();
     }
 
     @Test
     void addedShouldMatchBeanContract() {
-        EqualsVerifier.forClass(MailboxListener.Added.class).verify();
+        EqualsVerifier.forClass(Added.class).verify();
     }
 
     @Test
     void expungedShouldMatchBeanContract() {
-        EqualsVerifier.forClass(MailboxListener.Expunged.class).verify();
+        EqualsVerifier.forClass(Expunged.class).verify();
     }
 
     @Test
     void flagUpdatedShouldMatchBeanContract() {
-        EqualsVerifier.forClass(MailboxListener.FlagsUpdated.class).verify();
+        EqualsVerifier.forClass(FlagsUpdated.class).verify();
     }
 
     @Test
     void renameWithSameNameShouldBeNoop() {
-        MailboxListener.MailboxRenamed mailboxRenamed = new MailboxListener.MailboxRenamed(SESSION_ID, BOB, PATH, MAILBOX_ID, PATH,
+        MailboxRenamed mailboxRenamed = new MailboxRenamed(SESSION_ID, BOB, PATH, MAILBOX_ID, PATH,
             Event.EventId.random());
 
         assertThat(mailboxRenamed.isNoop()).isTrue();
@@ -112,7 +119,7 @@ class MailboxListenerTest {
 
     @Test
     void renameWithDifferentNameShouldNotBeNoop() {
-        MailboxListener.MailboxRenamed mailboxRenamed = new MailboxListener.MailboxRenamed(SESSION_ID, BOB, PATH, MAILBOX_ID, OTHER_PATH,
+        MailboxRenamed mailboxRenamed = new MailboxRenamed(SESSION_ID, BOB, PATH, MAILBOX_ID, OTHER_PATH,
             Event.EventId.random());
 
         assertThat(mailboxRenamed.isNoop()).isFalse();
@@ -120,7 +127,7 @@ class MailboxListenerTest {
 
     @Test
     void addedShouldNotBeNoop() {
-        MailboxListener.MailboxAdded added = new MailboxListener.MailboxAdded(SESSION_ID, BOB, PATH, MAILBOX_ID,
+        MailboxAdded added = new MailboxAdded(SESSION_ID, BOB, PATH, MAILBOX_ID,
             Event.EventId.random());
 
         assertThat(added.isNoop()).isFalse();
@@ -128,7 +135,7 @@ class MailboxListenerTest {
 
     @Test
     void removedShouldNotBeNoop() {
-        MailboxListener.MailboxDeletion deletion = new MailboxListener.MailboxDeletion(SESSION_ID, BOB, PATH, new MailboxACL(), QUOTA_ROOT,
+        MailboxDeletion deletion = new MailboxDeletion(SESSION_ID, BOB, PATH, new MailboxACL(), QUOTA_ROOT,
             QUOTA_COUNT, QUOTA_SIZE, MAILBOX_ID, Event.EventId.random());
 
         assertThat(deletion.isNoop()).isFalse();
@@ -136,7 +143,7 @@ class MailboxListenerTest {
 
     @Test
     void aclDiffWithSameAclShouldBeNoop() {
-        MailboxListener.MailboxACLUpdated aclUpdated = new MailboxListener.MailboxACLUpdated(SESSION_ID, BOB, PATH, ACLDiff.computeDiff(ACL_1, ACL_1), MAILBOX_ID,
+        MailboxACLUpdated aclUpdated = new MailboxACLUpdated(SESSION_ID, BOB, PATH, ACLDiff.computeDiff(ACL_1, ACL_1), MAILBOX_ID,
             Event.EventId.random());
 
         assertThat(aclUpdated.isNoop()).isTrue();
@@ -144,7 +151,7 @@ class MailboxListenerTest {
 
     @Test
     void aclDiffWithDifferentAclShouldNotBeNoop() {
-        MailboxListener.MailboxACLUpdated aclUpdated = new MailboxListener.MailboxACLUpdated(SESSION_ID, BOB, PATH, ACLDiff.computeDiff(ACL_1, ACL_2), MAILBOX_ID,
+        MailboxACLUpdated aclUpdated = new MailboxACLUpdated(SESSION_ID, BOB, PATH, ACLDiff.computeDiff(ACL_1, ACL_2), MAILBOX_ID,
             Event.EventId.random());
 
         assertThat(aclUpdated.isNoop()).isFalse();
@@ -152,7 +159,7 @@ class MailboxListenerTest {
 
     @Test
     void addedShouldBeNoopWhenEmpty() {
-        MailboxListener.Added added = new MailboxListener.Added(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableSortedMap.of(),
+        Added added = new Added(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableSortedMap.of(),
             Event.EventId.random());
 
         assertThat(added.isNoop()).isTrue();
@@ -160,7 +167,7 @@ class MailboxListenerTest {
 
     @Test
     void addedShouldNotBeNoopWhenNotEmpty() {
-        MailboxListener.Added added = new MailboxListener.Added(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableSortedMap.of(UID, META_DATA),
+        Added added = new Added(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableSortedMap.of(UID, META_DATA),
             Event.EventId.random());
 
         assertThat(added.isNoop()).isFalse();
@@ -168,7 +175,7 @@ class MailboxListenerTest {
 
     @Test
     void expungedShouldBeNoopWhenEmpty() {
-        MailboxListener.Expunged expunged = new MailboxListener.Expunged(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableSortedMap.of(),
+        Expunged expunged = new Expunged(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableSortedMap.of(),
             Event.EventId.random());
 
         assertThat(expunged.isNoop()).isTrue();
@@ -176,7 +183,7 @@ class MailboxListenerTest {
 
     @Test
     void expungedShouldNotBeNoopWhenNotEmpty() {
-        MailboxListener.Expunged expunged = new MailboxListener.Expunged(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableSortedMap.of(UID, META_DATA),
+        Expunged expunged = new Expunged(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableSortedMap.of(UID, META_DATA),
             Event.EventId.random());
 
         assertThat(expunged.isNoop()).isFalse();
@@ -184,14 +191,14 @@ class MailboxListenerTest {
 
     @Test
     void flagsUpdatedShouldBeNoopWhenEmpty() {
-        MailboxListener.FlagsUpdated flagsUpdated = new MailboxListener.FlagsUpdated(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableList.of(), Event.EventId.random());
+        FlagsUpdated flagsUpdated = new FlagsUpdated(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableList.of(), Event.EventId.random());
 
         assertThat(flagsUpdated.isNoop()).isTrue();
     }
 
     @Test
     void flagsUpdatedShouldNotBeNoopWhenNotEmpty() {
-        MailboxListener.FlagsUpdated flagsUpdated = new MailboxListener.FlagsUpdated(SESSION_ID, BOB, PATH, MAILBOX_ID,
+        FlagsUpdated flagsUpdated = new FlagsUpdated(SESSION_ID, BOB, PATH, MAILBOX_ID,
             ImmutableList.of(UpdatedFlags.builder()
                 .uid(UID)
                 .modSeq(ModSeq.of(45))
@@ -205,7 +212,7 @@ class MailboxListenerTest {
 
     @Test
     void quotaUsageUpdatedEventShouldNotBeNoop() {
-        MailboxListener.QuotaUsageUpdatedEvent event = new MailboxListener.QuotaUsageUpdatedEvent(Event.EventId.random(), BOB, QUOTA_ROOT,
+        QuotaUsageUpdatedEvent event = new QuotaUsageUpdatedEvent(Event.EventId.random(), BOB, QUOTA_ROOT,
             Quota.<QuotaCountLimit, QuotaCountUsage>builder()
                 .used(QUOTA_COUNT)
                 .computedLimit(QuotaCountLimit.unlimited())
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java
index 192140f..d8667e2 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java
@@ -32,9 +32,9 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.james.core.Username;
-import org.apache.james.mailbox.events.EventBus;
+import org.apache.james.events.EventBus;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
 import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
-import org.apache.james.mailbox.events.MailboxListener;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.MailboxId;
@@ -69,7 +69,7 @@ public interface MailboxManagerStressContract<T extends MailboxManager> {
         MailboxId mailboxId = getManager().createMailbox(path, session).get();
         Mono.from(retrieveEventBus()
             .register(event -> {
-                MessageUid u = ((MailboxListener.Added) event).getUids().iterator().next();
+                MessageUid u = ((Added) event).getUids().iterator().next();
                 uList.add(u);
             }, new MailboxIdRegistrationKey(mailboxId)))
             .block();
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
index c9a5f9f..7a23c69 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
@@ -46,12 +46,17 @@ import org.apache.james.core.quota.QuotaCountLimit;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxManager.MailboxCapabilities;
 import org.apache.james.mailbox.MailboxManager.MailboxRenamedResult;
 import org.apache.james.mailbox.MessageManager.AppendCommand;
-import org.apache.james.mailbox.events.EventBus;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
+import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
-import org.apache.james.mailbox.events.MailboxListener;
 import org.apache.james.mailbox.events.MessageMoveEvent;
 import org.apache.james.mailbox.exception.AnnotationException;
 import org.apache.james.mailbox.exception.HasEmptyMailboxNameInHierarchyException;
@@ -731,9 +736,9 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             mailboxManager.deleteMailbox(inbox, session);
 
             assertThat(listener.getEvents())
-                .filteredOn(event -> event instanceof MailboxListener.MailboxDeletion)
+                .filteredOn(event -> event instanceof MailboxDeletion)
                 .hasSize(1)
-                .extracting(event -> (MailboxListener.MailboxDeletion) event)
+                .extracting(event -> (MailboxDeletion) event)
                 .element(0)
                 .satisfies(event -> assertThat(event.getMailboxId()).isEqualTo(inboxId))
                 .satisfies(event -> assertThat(event.getQuotaRoot()).isEqualTo(quotaRoot))
@@ -749,9 +754,9 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             mailboxManager.deleteMailbox(inboxId, session);
 
             assertThat(listener.getEvents())
-                .filteredOn(event -> event instanceof MailboxListener.MailboxDeletion)
+                .filteredOn(event -> event instanceof MailboxDeletion)
                 .hasSize(1)
-                .extracting(event -> (MailboxListener.MailboxDeletion) event)
+                .extracting(event -> (MailboxDeletion) event)
                 .element(0)
                 .satisfies(event -> assertThat(event.getMailboxId()).isEqualTo(inboxId))
                 .satisfies(event -> assertThat(event.getQuotaRoot()).isEqualTo(quotaRoot))
@@ -766,9 +771,9 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             Optional<MailboxId> newId = mailboxManager.createMailbox(newPath, session);
 
             assertThat(listener.getEvents())
-                .filteredOn(event -> event instanceof MailboxListener.MailboxAdded)
+                .filteredOn(event -> event instanceof MailboxAdded)
                 .hasSize(1)
-                .extracting(event -> (MailboxListener.MailboxAdded) event)
+                .extracting(event -> (MailboxAdded) event)
                 .element(0)
                 .satisfies(event -> assertThat(event.getMailboxId()).isEqualTo(newId.get()));
         }
@@ -782,9 +787,9 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
                     .build(message), session);
 
             assertThat(listener.getEvents())
-                .filteredOn(event -> event instanceof MailboxListener.QuotaUsageUpdatedEvent)
+                .filteredOn(event -> event instanceof QuotaUsageUpdatedEvent)
                 .hasSize(1)
-                .extracting(event -> (MailboxListener.QuotaUsageUpdatedEvent) event)
+                .extracting(event -> (QuotaUsageUpdatedEvent) event)
                 .element(0)
                 .satisfies(event -> assertThat(event.getQuotaRoot()).isEqualTo(quotaRoot))
                 .satisfies(event -> assertThat(event.getSizeQuota()).isEqualTo(Quota.<QuotaSizeLimit, QuotaSizeUsage>builder()
@@ -804,9 +809,9 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
                     .build(message), session);
 
             assertThat(listener.getEvents())
-                .filteredOn(event -> event instanceof MailboxListener.Added)
+                .filteredOn(event -> event instanceof Added)
                 .hasSize(1)
-                .extracting(event -> (MailboxListener.Added) event)
+                .extracting(event -> (Added) event)
                 .element(0)
                 .satisfies(event -> assertThat(event.getMailboxId()).isEqualTo(inboxId))
                 .satisfies(event -> assertThat(event.getUids()).hasSize(1));
@@ -821,9 +826,9 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             inboxManager.expunge(MessageRange.all(), session);
 
             assertThat(listener.getEvents())
-                .filteredOn(event -> event instanceof MailboxListener.Expunged)
+                .filteredOn(event -> event instanceof Expunged)
                 .hasSize(1)
-                .extracting(event -> (MailboxListener.Expunged) event)
+                .extracting(event -> (Expunged) event)
                 .element(0)
                 .satisfies(event -> assertThat(event.getMailboxId()).isEqualTo(inboxId))
                 .satisfies(event -> assertThat(event.getUids()).hasSize(1));
@@ -838,9 +843,9 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             inboxManager.delete(ImmutableList.of(messageId.getUid()), session);
 
             assertThat(listener.getEvents())
-                .filteredOn(event -> event instanceof MailboxListener.Expunged)
+                .filteredOn(event -> event instanceof Expunged)
                 .hasSize(1)
-                .extracting(event -> (MailboxListener.Expunged) event)
+                .extracting(event -> (Expunged) event)
                 .element(0)
                 .satisfies(event -> assertThat(event.getMailboxId()).isEqualTo(inboxId))
                 .satisfies(event -> assertThat(event.getUids()).hasSize(1));
@@ -854,9 +859,9 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             inboxManager.setFlags(new Flags(Flags.Flag.FLAGGED), MessageManager.FlagsUpdateMode.ADD, MessageRange.all(), session);
 
             assertThat(listener.getEvents())
-                .filteredOn(event -> event instanceof MailboxListener.FlagsUpdated)
+                .filteredOn(event -> event instanceof FlagsUpdated)
                 .hasSize(1)
-                .extracting(event -> (MailboxListener.FlagsUpdated) event)
+                .extracting(event -> (FlagsUpdated) event)
                 .element(0)
                 .satisfies(event -> assertThat(event.getMailboxId()).isEqualTo(inboxId))
                 .satisfies(event -> assertThat(event.getUids()).hasSize(1));
@@ -872,9 +877,9 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             mailboxManager.moveMessages(MessageRange.all(), inbox, newPath, session);
 
             assertThat(listener.getEvents())
-                .filteredOn(event -> event instanceof MailboxListener.Added)
+                .filteredOn(event -> event instanceof Added)
                 .hasSize(1)
-                .extracting(event -> (MailboxListener.Added) event)
+                .extracting(event -> (Added) event)
                 .element(0)
                 .satisfies(event -> assertThat(event.getMailboxId()).isEqualTo(targetMailboxId.get()))
                 .satisfies(event -> assertThat(event.getUids()).hasSize(1));
@@ -890,9 +895,9 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             mailboxManager.moveMessages(MessageRange.all(), inbox, newPath, session);
 
             assertThat(listener.getEvents())
-                .filteredOn(event -> event instanceof MailboxListener.Expunged)
+                .filteredOn(event -> event instanceof Expunged)
                 .hasSize(1)
-                .extracting(event -> (MailboxListener.Expunged) event)
+                .extracting(event -> (Expunged) event)
                 .element(0)
                 .satisfies(event -> assertThat(event.getMailboxId()).isEqualTo(inboxId))
                 .satisfies(event -> assertThat(event.getUids()).hasSize(1));
@@ -907,9 +912,9 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             mailboxManager.copyMessages(MessageRange.all(), inbox, newPath, session);
 
             assertThat(listener.getEvents())
-                .filteredOn(event -> event instanceof MailboxListener.Added)
+                .filteredOn(event -> event instanceof Added)
                 .hasSize(1)
-                .extracting(event -> (MailboxListener.Added) event)
+                .extracting(event -> (Added) event)
                 .element(0)
                 .satisfies(event -> assertThat(event.getMailboxId()).isEqualTo(targetMailboxId.get()))
                 .satisfies(event -> assertThat(event.getUids()).hasSize(1));
@@ -993,7 +998,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             mailboxManager.copyMessages(MessageRange.all(), inbox, newPath, session);
 
             assertThat(listener.getEvents())
-                .filteredOn(event -> event instanceof MailboxListener.Expunged)
+                .filteredOn(event -> event instanceof Expunged)
                 .isEmpty();
         }
     }
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/ErrorHandlingContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/ErrorHandlingContract.java
index 18bcb18..226f1bb 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/ErrorHandlingContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/events/ErrorHandlingContract.java
@@ -37,6 +37,9 @@ import java.util.List;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import org.apache.james.events.Event;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.EventListener;
 import org.apache.james.mailbox.util.EventCollector;
 import org.assertj.core.api.SoftAssertions;
 import org.junit.jupiter.api.Disabled;
@@ -48,7 +51,7 @@ import reactor.core.publisher.Mono;
 
 interface ErrorHandlingContract extends EventBusContract {
 
-    class ThrowingListener implements MailboxListener {
+    class ThrowingListener implements EventListener {
         private final List<Instant> timeElapsed;
 
         private ThrowingListener() {
@@ -200,7 +203,7 @@ interface ErrorHandlingContract extends EventBusContract {
     default void retryingListenerCallingDispatchShouldNotFail() {
         AtomicBoolean firstExecution = new AtomicBoolean(true);
         AtomicBoolean successfulRetry = new AtomicBoolean(false);
-        MailboxListener listener = event -> {
+        EventListener listener = event -> {
             if (event.getEventId().equals(EVENT_ID)) {
                 if (firstExecution.get()) {
                     firstExecution.set(false);
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusConcurrentTestContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusConcurrentTestContract.java
index 1aa3c2e..8b73023 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusConcurrentTestContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusConcurrentTestContract.java
@@ -32,6 +32,8 @@ import java.time.Duration;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.james.events.EventBus;
+import org.apache.james.events.RegistrationKey;
 import org.apache.james.util.concurrency.ConcurrentTestRunner;
 import org.awaitility.core.ConditionFactory;
 import org.junit.jupiter.api.Test;
@@ -52,13 +54,13 @@ public interface EventBusConcurrentTestContract {
 
     Set<RegistrationKey> ALL_KEYS = ImmutableSet.of(KEY_1, KEY_2, KEY_3);
 
-    static EventBusTestFixture.MailboxListenerCountingSuccessfulExecution newCountingListener() {
-        return new EventBusTestFixture.MailboxListenerCountingSuccessfulExecution();
+    static EventBusTestFixture.EventListenerCountingSuccessfulExecution newCountingListener() {
+        return new EventBusTestFixture.EventListenerCountingSuccessfulExecution();
     }
 
-    static int totalEventsReceived(ImmutableList<EventBusTestFixture.MailboxListenerCountingSuccessfulExecution> allListeners) {
+    static int totalEventsReceived(ImmutableList<EventBusTestFixture.EventListenerCountingSuccessfulExecution> allListeners) {
         return allListeners.stream()
-            .mapToInt(EventBusTestFixture.MailboxListenerCountingSuccessfulExecution::numberOfEventCalls)
+            .mapToInt(EventBusTestFixture.EventListenerCountingSuccessfulExecution::numberOfEventCalls)
             .sum();
     }
 
@@ -66,9 +68,9 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchGroupShouldDeliverAllEventsToListenersWithSingleEventBus() throws Exception {
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
 
             eventBus().register(countingListener1, new EventBusTestFixture.GroupA());
             eventBus().register(countingListener2, new EventBusTestFixture.GroupB());
@@ -88,9 +90,9 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchKeyShouldDeliverAllEventsToListenersWithSingleEventBus() throws Exception {
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
             Mono.from(eventBus().register(countingListener1, KEY_1)).block();
             Mono.from(eventBus().register(countingListener2, KEY_2)).block();
             Mono.from(eventBus().register(countingListener3, KEY_3)).block();
@@ -111,9 +113,9 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchShouldDeliverAllEventsToListenersWithSingleEventBus() throws Exception {
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
 
             eventBus().register(countingListener1, new EventBusTestFixture.GroupA());
             eventBus().register(countingListener2, new EventBusTestFixture.GroupB());
@@ -146,9 +148,9 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchGroupShouldDeliverAllEventsToListenersWithMultipleEventBus() throws Exception {
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
 
             eventBus().register(countingListener1, new EventBusTestFixture.GroupA());
             eventBus().register(countingListener2, new EventBusTestFixture.GroupB());
@@ -173,9 +175,9 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchKeyShouldDeliverAllEventsToListenersWithMultipleEventBus() throws Exception {
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
 
             Mono.from(eventBus().register(countingListener1, KEY_1)).block();
             Mono.from(eventBus().register(countingListener2, KEY_2)).block();
@@ -201,9 +203,9 @@ public interface EventBusConcurrentTestContract {
 
         @Test
         default void concurrentDispatchShouldDeliverAllEventsToListenersWithMultipleEventBus() throws Exception {
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener2 = newCountingListener();
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution countingListener3 = newCountingListener();
 
             eventBus2().register(countingListener1, GROUP_A);
             eventBus2().register(countingListener2, new EventBusTestFixture.GroupB());
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusContract.java
index 577697e..c94c5a3 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusContract.java
@@ -24,6 +24,7 @@ import static org.awaitility.Awaitility.await;
 import java.time.Duration;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.james.events.EventBus;
 import org.awaitility.core.ConditionFactory;
 
 public interface EventBusContract {
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusTestFixture.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusTestFixture.java
index b0bd987..dccec61 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusTestFixture.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusTestFixture.java
@@ -28,7 +28,14 @@ import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.james.core.Username;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
+import org.apache.james.events.RegistrationKey;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxEvent;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxRenamed;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
@@ -39,7 +46,7 @@ import com.google.common.collect.ImmutableSet;
 
 public interface EventBusTestFixture {
 
-    class MailboxListenerCountingSuccessfulExecution implements MailboxListener {
+    class EventListenerCountingSuccessfulExecution implements EventListener {
         private final AtomicInteger calls = new AtomicInteger(0);
 
         @Override
@@ -57,7 +64,7 @@ public interface EventBusTestFixture {
         }
     }
 
-    class EventMatcherThrowingListener extends MailboxListenerCountingSuccessfulExecution {
+    class EventMatcherThrowingListener extends EventListenerCountingSuccessfulExecution {
         private final ImmutableSet<Event> eventsCauseThrowing;
 
         EventMatcherThrowingListener(ImmutableSet<Event> eventsCauseThrowing) {
@@ -96,9 +103,9 @@ public interface EventBusTestFixture {
     TestId TEST_ID = TestId.of(18);
     Event.EventId EVENT_ID = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
     Event.EventId EVENT_ID_2 = Event.EventId.of("5a7a9f3f-5f03-44be-b457-a51e93760645");
-    MailboxListener.MailboxEvent EVENT = new MailboxListener.MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, EVENT_ID);
-    MailboxListener.MailboxEvent EVENT_2 = new MailboxListener.MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, EVENT_ID_2);
-    MailboxListener.MailboxRenamed EVENT_UNSUPPORTED_BY_LISTENER = new MailboxListener.MailboxRenamed(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, MAILBOX_PATH, EVENT_ID_2);
+    MailboxEvent EVENT = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, EVENT_ID);
+    MailboxEvent EVENT_2 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, EVENT_ID_2);
+    MailboxRenamed EVENT_UNSUPPORTED_BY_LISTENER = new MailboxRenamed(SESSION_ID, USERNAME, MAILBOX_PATH, TEST_ID, MAILBOX_PATH, EVENT_ID_2);
 
     java.time.Duration ONE_SECOND = java.time.Duration.ofSeconds(1);
     java.time.Duration FIVE_HUNDRED_MS = java.time.Duration.ofMillis(500);
@@ -122,17 +129,17 @@ public interface EventBusTestFixture {
         .jitterFactor(DEFAULT_JITTER_FACTOR)
         .build();
 
-    static MailboxListener newListener() {
-        MailboxListener listener = mock(MailboxListener.class);
-        when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.SYNCHRONOUS);
-        when(listener.isHandling(any(MailboxListener.MailboxAdded.class))).thenReturn(true);
+    static EventListener newListener() {
+        EventListener listener = mock(EventListener.class);
+        when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
+        when(listener.isHandling(any(MailboxAdded.class))).thenReturn(true);
         return listener;
     }
 
-    static MailboxListener newAsyncListener() {
-        MailboxListener listener = mock(MailboxListener.class);
-        when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
-        when(listener.isHandling(any(MailboxListener.MailboxAdded.class))).thenReturn(true);
+    static EventListener newAsyncListener() {
+        EventListener listener = mock(EventListener.class);
+        when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
+        when(listener.isHandling(any(MailboxAdded.class))).thenReturn(true);
         return listener;
     }
 }
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersContract.java
index ebbbdbc..1e8f003 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersContract.java
@@ -31,7 +31,11 @@ import java.util.stream.IntStream;
 import java.util.stream.Stream;
 
 import org.apache.james.core.Username;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.Group;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.TestId;
@@ -93,7 +97,7 @@ interface EventDeadLettersContract {
     }
 
     static Event event(Event.EventId eventId) {
-        return new MailboxListener.MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, eventId);
+        return new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, eventId);
     }
 
     List<Group> CONCURRENT_GROUPS = ImmutableList.of(new Group0(), new Group1(), new Group2(), new Group3(), new Group4(), new Group5(),
@@ -109,9 +113,9 @@ interface EventDeadLettersContract {
     Event.EventId EVENT_ID_1 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
     Event.EventId EVENT_ID_2 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b5");
     Event.EventId EVENT_ID_3 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b6");
-    MailboxListener.MailboxAdded EVENT_1 = new MailboxListener.MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_1);
-    MailboxListener.MailboxAdded EVENT_2 = new MailboxListener.MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_2);
-    MailboxListener.MailboxAdded EVENT_3 = new MailboxListener.MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_3);
+    MailboxAdded EVENT_1 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_1);
+    MailboxAdded EVENT_2 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_2);
+    MailboxAdded EVENT_3 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_3);
     EventDeadLetters.InsertionId INSERTION_ID_1 = EventDeadLetters.InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b7");
     EventDeadLetters.InsertionId INSERTION_ID_2 = EventDeadLetters.InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b8");
     EventDeadLetters.InsertionId INSERTION_ID_3 = EventDeadLetters.InsertionId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b9");
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersHealthCheckContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersHealthCheckContract.java
index 7c16b7b..4479714 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersHealthCheckContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersHealthCheckContract.java
@@ -24,7 +24,12 @@ import static org.assertj.core.api.Assertions.assertThat;
 import org.apache.james.core.Username;
 import org.apache.james.core.healthcheck.ComponentName;
 import org.apache.james.core.healthcheck.Result;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.EventDeadLettersHealthCheck;
+import org.apache.james.events.Group;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.TestId;
@@ -41,8 +46,8 @@ interface EventDeadLettersHealthCheckContract {
     TestId MAILBOX_ID = TestId.of(563);
     Event.EventId EVENT_ID_1 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
     Event.EventId EVENT_ID_2 = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b5");
-    MailboxListener.MailboxAdded EVENT_1 = new MailboxListener.MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_1);
-    MailboxListener.MailboxAdded EVENT_2 = new MailboxListener.MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_2);
+    MailboxAdded EVENT_1 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_1);
+    MailboxAdded EVENT_2 = new MailboxAdded(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_2);
 
     Group GROUP_A = new EventBusTestFixture.GroupA();
     Group GROUP_B = new EventBusTestFixture.GroupB();
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupContract.java
index 24046a1..fb5131d 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupContract.java
@@ -49,7 +49,16 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.IntStream;
 
 import org.apache.james.core.Username;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventBus;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.GenericGroup;
+import org.apache.james.events.Group;
+import org.apache.james.events.GroupAlreadyRegistered;
+import org.apache.james.events.GroupRegistrationNotFound;
+import org.apache.james.events.Registration;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.TestId;
 import org.junit.jupiter.api.Test;
@@ -70,7 +79,7 @@ public interface GroupContract {
             AtomicInteger finishedExecutions = new AtomicInteger(0);
             AtomicBoolean rateExceeded = new AtomicBoolean(false);
 
-            eventBus().register(new MailboxListener.GroupMailboxListener() {
+            eventBus().register(new EventListener.GroupEventListener() {
                 @Override
                 public Group getDefaultGroup() {
                     return new GenericGroup("group");
@@ -106,7 +115,7 @@ public interface GroupContract {
             CountDownLatch countDownLatch = new CountDownLatch(1);
             try {
                 ConcurrentLinkedQueue<String> threads = new ConcurrentLinkedQueue<>();
-                eventBus().register(new MailboxListener.GroupMailboxListener() {
+                eventBus().register(new EventListener.GroupEventListener() {
                     @Override
                     public Group getDefaultGroup() {
                         return new GenericGroup("groupA");
@@ -118,7 +127,7 @@ public interface GroupContract {
                         countDownLatch.await();
                     }
                 }, GROUP_A);
-                eventBus().register(new MailboxListener.GroupMailboxListener() {
+                eventBus().register(new EventListener.GroupEventListener() {
                     @Override
                     public Group getDefaultGroup() {
                         return new GenericGroup("groupB");
@@ -130,7 +139,7 @@ public interface GroupContract {
                         countDownLatch.await();
                     }
                 }, GROUP_B);
-                eventBus().register(new MailboxListener.GroupMailboxListener() {
+                eventBus().register(new EventListener.GroupEventListener() {
                     @Override
                     public Group getDefaultGroup() {
                         return new GenericGroup("groupC");
@@ -157,7 +166,7 @@ public interface GroupContract {
         @Test
         default void listenersShouldBeAbleToDispatch() {
             AtomicBoolean successfulRetry = new AtomicBoolean(false);
-            MailboxListener listener = event -> {
+            EventListener listener = event -> {
                 if (event.getEventId().equals(EVENT_ID)) {
                     eventBus().dispatch(EVENT_2, NO_KEYS)
                         .subscribeOn(Schedulers.elastic())
@@ -174,7 +183,7 @@ public interface GroupContract {
 
         @Test
         default void registerShouldNotDispatchPastEventsForGroups() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
             eventBus().dispatch(EVENT, NO_KEYS).block();
 
@@ -186,7 +195,7 @@ public interface GroupContract {
 
         @Test
         default void listenerGroupShouldReceiveEvents() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
             eventBus().register(listener, GROUP_A);
 
@@ -197,12 +206,12 @@ public interface GroupContract {
 
         @Test
         default void groupListenersShouldNotReceiveNoopEvents() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
             eventBus().register(listener, GROUP_A);
 
             Username bob = Username.of("bob");
-            MailboxListener.Added noopEvent = new MailboxListener.Added(MailboxSession.SessionId.of(18), bob, MailboxPath.forUser(bob, "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
+            Added noopEvent = new Added(MailboxSession.SessionId.of(18), bob, MailboxPath.forUser(bob, "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
             eventBus().dispatch(noopEvent, NO_KEYS).block();
 
             verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
@@ -211,7 +220,7 @@ public interface GroupContract {
 
         @Test
         default void groupListenersShouldReceiveOnlyHandledEvents() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
             eventBus().register(listener, GROUP_A);
 
@@ -223,7 +232,7 @@ public interface GroupContract {
 
         @Test
         default void dispatchShouldNotThrowWhenAGroupListenerFails() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
             doThrow(new RuntimeException()).when(listener).event(any());
 
             eventBus().register(listener, GROUP_A);
@@ -234,8 +243,8 @@ public interface GroupContract {
 
         @Test
         default void eachListenerGroupShouldReceiveEvents() throws Exception {
-            MailboxListener listener = newListener();
-            MailboxListener listener2 = newListener();
+            EventListener listener = newListener();
+            EventListener listener2 = newListener();
             eventBus().register(listener, GROUP_A);
             eventBus().register(listener2, GROUP_B);
 
@@ -247,7 +256,7 @@ public interface GroupContract {
 
         @Test
         default void unregisteredGroupListenerShouldNotReceiveEvents() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
             Registration registration = eventBus().register(listener, GROUP_A);
 
             registration.unregister();
@@ -259,8 +268,8 @@ public interface GroupContract {
 
         @Test
         default void registerShouldThrowWhenAGroupIsAlreadyUsed() {
-            MailboxListener listener = newListener();
-            MailboxListener listener2 = newListener();
+            EventListener listener = newListener();
+            EventListener listener2 = newListener();
 
             eventBus().register(listener, GROUP_A);
 
@@ -270,8 +279,8 @@ public interface GroupContract {
 
         @Test
         default void registerShouldNotThrowOnAnUnregisteredGroup() {
-            MailboxListener listener = newListener();
-            MailboxListener listener2 = newListener();
+            EventListener listener = newListener();
+            EventListener listener2 = newListener();
 
             eventBus().register(listener, GROUP_A).unregister();
 
@@ -281,7 +290,7 @@ public interface GroupContract {
 
         @Test
         default void unregisterShouldBeIdempotentForGroups() {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
             Registration registration = eventBus().register(listener, GROUP_A);
             registration.unregister();
@@ -292,7 +301,7 @@ public interface GroupContract {
 
         @Test
         default void registerShouldAcceptAlreadyUnregisteredGroups() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
             eventBus().register(listener, GROUP_A).unregister();
             eventBus().register(listener, GROUP_A);
@@ -304,7 +313,7 @@ public interface GroupContract {
 
         @Test
         default void dispatchShouldCallSynchronousListener() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
             eventBus().register(listener, GROUP_A);
 
@@ -315,7 +324,7 @@ public interface GroupContract {
 
         @Test
         default void failingGroupListenersShouldNotAbortGroupDelivery() {
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution listener = new EventBusTestFixture.EventMatcherThrowingListener(ImmutableSet.of(EVENT));
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution listener = new EventBusTestFixture.EventMatcherThrowingListener(ImmutableSet.of(EVENT));
             eventBus().register(listener, GROUP_A);
 
             eventBus().dispatch(EVENT, NO_KEYS).block();
@@ -327,10 +336,10 @@ public interface GroupContract {
 
         @Test
         default void allGroupListenersShouldBeExecutedWhenAGroupListenerFails() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
-            MailboxListener failingListener = mock(MailboxListener.class);
-            when(failingListener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.SYNCHRONOUS);
+            EventListener failingListener = mock(EventListener.class);
+            when(failingListener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
             doThrow(new RuntimeException()).when(failingListener).event(any());
 
             eventBus().register(failingListener, GROUP_A);
@@ -343,8 +352,8 @@ public interface GroupContract {
 
         @Test
         default void allGroupListenersShouldBeExecutedWhenGenericGroups() throws Exception {
-            MailboxListener listener1 = newListener();
-            MailboxListener listener2 = newListener();
+            EventListener listener1 = newListener();
+            EventListener listener2 = newListener();
 
             eventBus().register(listener1, new GenericGroup("a"));
             eventBus().register(listener2, new GenericGroup("b"));
@@ -357,7 +366,7 @@ public interface GroupContract {
 
         @Test
         default void groupListenerShouldReceiveEventWhenRedeliver() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
             eventBus().register(listener, GROUP_A);
 
@@ -368,7 +377,7 @@ public interface GroupContract {
 
         @Test
         default void redeliverShouldNotThrowWhenAGroupListenerFails() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
             doThrow(new RuntimeException()).when(listener).event(any());
 
             eventBus().register(listener, GROUP_A);
@@ -385,7 +394,7 @@ public interface GroupContract {
 
         @Test
         default void redeliverShouldThrowAfterGroupIsUnregistered() {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
             eventBus().register(listener, GROUP_A).unregister();
 
@@ -395,8 +404,8 @@ public interface GroupContract {
 
         @Test
         default void redeliverShouldOnlySendEventToDefinedGroup() throws Exception {
-            MailboxListener listener = newListener();
-            MailboxListener listener2 = newListener();
+            EventListener listener = newListener();
+            EventListener listener2 = newListener();
             eventBus().register(listener, GROUP_A);
             eventBus().register(listener2, GROUP_B);
 
@@ -408,12 +417,12 @@ public interface GroupContract {
 
         @Test
         default void groupListenersShouldNotReceiveNoopRedeliveredEvents() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
             eventBus().register(listener, GROUP_A);
 
             Username bob = Username.of("bob");
-            MailboxListener.Added noopEvent = new MailboxListener.Added(MailboxSession.SessionId.of(18), bob, MailboxPath.forUser(bob, "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
+            Added noopEvent = new Added(MailboxSession.SessionId.of(18), bob, MailboxPath.forUser(bob, "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
             eventBus().reDeliver(GROUP_A, noopEvent).block();
 
             verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never()).event(any());
@@ -424,7 +433,7 @@ public interface GroupContract {
 
         @Test
         default void groupsDefinedOnlyOnSomeNodesShouldBeNotifiedWhenDispatch() throws Exception {
-            MailboxListener mailboxListener = newListener();
+            EventListener mailboxListener = newListener();
 
             eventBus().register(mailboxListener, GROUP_A);
 
@@ -435,7 +444,7 @@ public interface GroupContract {
 
         @Test
         default void groupsDefinedOnlyOnSomeNodesShouldNotBeNotifiedWhenRedeliver() {
-            MailboxListener mailboxListener = newListener();
+            EventListener mailboxListener = newListener();
 
             eventBus().register(mailboxListener, GROUP_A);
 
@@ -445,7 +454,7 @@ public interface GroupContract {
 
         @Test
         default void groupListenersShouldBeExecutedOnceWhenRedeliverInADistributedEnvironment() throws Exception {
-            MailboxListener mailboxListener = newListener();
+            EventListener mailboxListener = newListener();
 
             eventBus().register(mailboxListener, GROUP_A);
             eventBus2().register(mailboxListener, GROUP_A);
@@ -457,7 +466,7 @@ public interface GroupContract {
 
         @Test
         default void groupListenersShouldBeExecutedOnceInAControlledEnvironment() throws Exception {
-            MailboxListener mailboxListener = newListener();
+            EventListener mailboxListener = newListener();
 
             eventBus().register(mailboxListener, GROUP_A);
             eventBus2().register(mailboxListener, GROUP_A);
@@ -469,7 +478,7 @@ public interface GroupContract {
 
         @Test
         default void unregisterShouldStopNotificationForDistantGroups() throws Exception {
-            MailboxListener mailboxListener = newListener();
+            EventListener mailboxListener = newListener();
 
             eventBus().register(mailboxListener, GROUP_A).unregister();
 
@@ -482,7 +491,7 @@ public interface GroupContract {
 
         @Test
         default void registerShouldNotDispatchPastEventsForGroupsInADistributedContext() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
             eventBus().dispatch(EVENT, NO_KEYS).block();
 
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupTest.java
index 617e191..53176df 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupTest.java
@@ -22,6 +22,8 @@ package org.apache.james.mailbox.events;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
+import org.apache.james.events.GenericGroup;
+import org.apache.james.events.Group;
 import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
@@ -80,18 +82,18 @@ class GroupTest {
 
     @Test
     void asStringShouldReturnNameWhenGenericGroup() {
-        assertThat(new GenericGroup("abc").asString()).isEqualTo("org.apache.james.mailbox.events.GenericGroup-abc");
+        assertThat(new GenericGroup("abc").asString()).isEqualTo("org.apache.james.events.GenericGroup-abc");
     }
 
     @Test
     void deserializeShouldReturnGroupWhenGenericGroup() throws Exception {
-        assertThat(Group.deserialize("org.apache.james.mailbox.events.GenericGroup-abc"))
+        assertThat(Group.deserialize("org.apache.james.events.GenericGroup-abc"))
             .isEqualTo(new GenericGroup("abc"));
     }
 
     @Test
     void deserializeShouldReturnGroupWhenEmptyGenericGroup() throws Exception {
-        assertThat(Group.deserialize("org.apache.james.mailbox.events.GenericGroup-"))
+        assertThat(Group.deserialize("org.apache.james.events.GenericGroup-"))
             .isEqualTo(new GenericGroup(""));
     }
 
@@ -115,7 +117,7 @@ class GroupTest {
 
     @Test
     void deserializeShouldThrowWhenConstructorArgumentsRequired() {
-        assertThatThrownBy(() -> Group.deserialize("org.apache.james.mailbox.events.GenericGroup"))
+        assertThatThrownBy(() -> Group.deserialize("org.apache.james.events.GenericGroup"))
             .isInstanceOf(Group.GroupDeserializationException.class);
     }
 
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/InsertionIdTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/InsertionIdTest.java
index f8a1e0e..c951edd 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/InsertionIdTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/events/InsertionIdTest.java
@@ -24,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.util.UUID;
 
+import org.apache.james.events.EventDeadLetters;
 import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/KeyContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/KeyContract.java
index f652377..4c22d4b 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/KeyContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/events/KeyContract.java
@@ -49,7 +49,12 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.IntStream;
 
 import org.apache.james.core.Username;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventBus;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Registration;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.TestId;
 import org.junit.jupiter.api.Test;
@@ -120,12 +125,12 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void registeredListenersShouldNotReceiveNoopEvents() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
             Mono.from(eventBus().register(listener, KEY_1)).block();
 
             Username bob = Username.of("bob");
-            MailboxListener.Added noopEvent = new MailboxListener.Added(MailboxSession.SessionId.of(18), bob, MailboxPath.forUser(bob, "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
+            Added noopEvent = new Added(MailboxSession.SessionId.of(18), bob, MailboxPath.forUser(bob, "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
             eventBus().dispatch(noopEvent, KEY_1).block();
 
             verify(listener, after(FIVE_HUNDRED_MS.toMillis()).never())
@@ -134,7 +139,7 @@ public interface KeyContract extends EventBusContract {
 
        @Test
         default void registeredListenersShouldReceiveOnlyHandledEvents() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
             Mono.from(eventBus().register(listener, KEY_1)).block();
 
@@ -146,7 +151,7 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void dispatchShouldNotThrowWhenARegisteredListenerFails() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
             doThrow(new RuntimeException()).when(listener).event(any());
 
             Mono.from(eventBus().register(listener, KEY_1)).block();
@@ -157,7 +162,7 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void dispatchShouldNotNotifyRegisteredListenerWhenEmptyKeySet() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
             Mono.from(eventBus().register(listener, KEY_1)).block();
 
             eventBus().dispatch(EVENT, NO_KEYS).block();
@@ -168,7 +173,7 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void dispatchShouldNotNotifyListenerRegisteredOnOtherKeys() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
             Mono.from(eventBus().register(listener, KEY_1)).block();
 
             eventBus().dispatch(EVENT, ImmutableSet.of(KEY_2)).block();
@@ -179,7 +184,7 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void dispatchShouldNotifyRegisteredListeners() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
             Mono.from(eventBus().register(listener, KEY_1)).block();
 
             eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
@@ -189,7 +194,7 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void dispatchShouldNotifyLocalRegisteredListenerWithoutDelay() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
             Mono.from(eventBus().register(listener, KEY_1)).block();
 
             eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
@@ -199,8 +204,8 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void dispatchShouldNotifyOnlyRegisteredListener() throws Exception {
-            MailboxListener listener = newListener();
-            MailboxListener listener2 = newListener();
+            EventListener listener = newListener();
+            EventListener listener2 = newListener();
             Mono.from(eventBus().register(listener, KEY_1)).block();
             Mono.from(eventBus().register(listener2, KEY_2)).block();
 
@@ -213,8 +218,8 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void dispatchShouldNotifyAllListenersRegisteredOnAKey() throws Exception {
-            MailboxListener listener = newListener();
-            MailboxListener listener2 = newListener();
+            EventListener listener = newListener();
+            EventListener listener2 = newListener();
             Mono.from(eventBus().register(listener, KEY_1)).block();
             Mono.from(eventBus().register(listener2, KEY_1)).block();
 
@@ -226,7 +231,7 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void registerShouldAllowDuplicatedRegistration() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
             Mono.from(eventBus().register(listener, KEY_1)).block();
             Mono.from(eventBus().register(listener, KEY_1)).block();
 
@@ -237,7 +242,7 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void unregisterShouldRemoveDoubleRegisteredListener() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
             Mono.from(eventBus().register(listener, KEY_1)).block();
             Mono.from(eventBus().register(listener, KEY_1)).block().unregister();
 
@@ -249,7 +254,7 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void registerShouldNotDispatchPastEvents() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
             eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
 
@@ -261,7 +266,7 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void callingAllUnregisterMethodShouldUnregisterTheListener() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
             Registration registration = Mono.from(eventBus().register(listener, KEY_1)).block();
             Mono.from(eventBus().register(listener, KEY_1)).block().unregister();
             registration.unregister();
@@ -274,7 +279,7 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void unregisterShouldHaveNotNotifyWhenCalledOnDifferentKeys() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
             Mono.from(eventBus().register(listener, KEY_1)).block();
             Mono.from(eventBus().register(listener, KEY_2)).block().unregister();
 
@@ -285,7 +290,7 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void unregisterShouldBeIdempotentForKeyRegistrations() {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
             Registration registration = Mono.from(eventBus().register(listener, KEY_1)).block();
             registration.unregister();
@@ -296,7 +301,7 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void dispatchShouldAcceptSeveralKeys() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
             Mono.from(eventBus().register(listener, KEY_1)).block();
 
             eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1, KEY_2)).block();
@@ -306,7 +311,7 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void dispatchShouldCallListenerOnceWhenSeveralKeysMatching() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
             Mono.from(eventBus().register(listener, KEY_1)).block();
             Mono.from(eventBus().register(listener, KEY_2)).block();
 
@@ -317,7 +322,7 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void dispatchShouldNotNotifyUnregisteredListener() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
             Mono.from(eventBus().register(listener, KEY_1)).block().unregister();
 
             eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
@@ -329,8 +334,8 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void dispatchShouldNotifyAsynchronousListener() throws Exception {
-            MailboxListener listener = newListener();
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
+            EventListener listener = newListener();
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
             Mono.from(eventBus().register(listener, KEY_1)).block();
 
             eventBus().dispatch(EVENT, KEY_1).block();
@@ -340,8 +345,8 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void dispatchShouldNotBlockAsynchronousListener() throws Exception {
-            MailboxListener listener = newListener();
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
+            EventListener listener = newListener();
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
             CountDownLatch latch = new CountDownLatch(1);
             doAnswer(invocation -> {
                 latch.await();
@@ -357,7 +362,7 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void failingRegisteredListenersShouldNotAbortRegisteredDelivery() {
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution listener = new EventBusTestFixture.EventMatcherThrowingListener(ImmutableSet.of(EVENT));
+            EventBusTestFixture.EventListenerCountingSuccessfulExecution listener = new EventBusTestFixture.EventMatcherThrowingListener(ImmutableSet.of(EVENT));
             Mono.from(eventBus().register(listener, KEY_1)).block();
 
             eventBus().dispatch(EVENT, KEY_1).block();
@@ -369,10 +374,10 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void allRegisteredListenersShouldBeExecutedWhenARegisteredListenerFails() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
-            MailboxListener failingListener = mock(MailboxListener.class);
-            when(failingListener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.SYNCHRONOUS);
+            EventListener failingListener = mock(EventListener.class);
+            when(failingListener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
             doThrow(new RuntimeException()).when(failingListener).event(any());
 
             Mono.from(eventBus().register(failingListener, KEY_1)).block();
@@ -388,7 +393,7 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void crossEventBusRegistrationShouldBeAllowed() throws Exception {
-            MailboxListener mailboxListener = newListener();
+            EventListener mailboxListener = newListener();
 
             Mono.from(eventBus().register(mailboxListener, KEY_1)).block();
 
@@ -399,20 +404,20 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void unregisteredDistantListenersShouldNotBeNotified() throws Exception {
-            MailboxListener mailboxListener = newListener();
+            EventListener eventListener = newListener();
 
-            Mono.from(eventBus().register(mailboxListener, KEY_1)).block().unregister();
+            Mono.from(eventBus().register(eventListener, KEY_1)).block().unregister();
 
             eventBus2().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
 
-            verify(mailboxListener, after(FIVE_HUNDRED_MS.toMillis()).never())
+            verify(eventListener, after(FIVE_HUNDRED_MS.toMillis()).never())
                 .event(any());
         }
 
         @Test
         default void allRegisteredListenersShouldBeDispatched() throws Exception {
-            MailboxListener mailboxListener1 = newListener();
-            MailboxListener mailboxListener2 = newListener();
+            EventListener mailboxListener1 = newListener();
+            EventListener mailboxListener2 = newListener();
 
             Mono.from(eventBus().register(mailboxListener1, KEY_1)).block();
             Mono.from(eventBus2().register(mailboxListener2, KEY_1)).block();
@@ -425,7 +430,7 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void registerShouldNotDispatchPastEventsInDistributedContext() throws Exception {
-            MailboxListener listener = newListener();
+            EventListener listener = newListener();
 
             eventBus2().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
 
@@ -437,8 +442,8 @@ public interface KeyContract extends EventBusContract {
 
         @Test
         default void localDispatchedListenersShouldBeDispatchedWithoutDelay() throws Exception {
-            MailboxListener mailboxListener1 = newListener();
-            MailboxListener mailboxListener2 = newListener();
+            EventListener mailboxListener1 = newListener();
+            EventListener mailboxListener2 = newListener();
 
             Mono.from(eventBus().register(mailboxListener1, KEY_1)).block();
             Mono.from(eventBus2().register(mailboxListener2, KEY_1)).block();
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/util/EventCollector.java b/mailbox/api/src/test/java/org/apache/james/mailbox/util/EventCollector.java
index d149fc8..1b18ed3 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/util/EventCollector.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/util/EventCollector.java
@@ -22,11 +22,11 @@ package org.apache.james.mailbox.util;
 import java.util.Collection;
 import java.util.concurrent.ConcurrentLinkedDeque;
 
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.Group;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
 
-public class EventCollector implements MailboxListener.GroupMailboxListener {
+public class EventCollector implements EventListener.GroupEventListener {
     public static class EventCollectorGroup extends Group {
 
     }
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java
index f765922..35d9f40 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java
@@ -23,11 +23,11 @@ import java.util.EnumSet;
 
 import javax.inject.Inject;
 
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.SessionProvider;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.MailboxManagerConfiguration;
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
index 928e627..e40d175 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
@@ -21,9 +21,9 @@ package org.apache.james.mailbox.cassandra;
 
 import javax.mail.Flags;
 
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.quota.QuotaManager;
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java
index 3122449..728bd81 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java
@@ -28,6 +28,9 @@ import java.util.function.Predicate;
 import javax.inject.Inject;
 
 import org.apache.james.blob.api.BlobStore;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
 import org.apache.james.mailbox.acl.ACLDiff;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
@@ -47,9 +50,8 @@ import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraUserMailboxRightsDAO;
 import org.apache.james.mailbox.cassandra.mail.MessageAttachmentRepresentation;
 import org.apache.james.mailbox.cassandra.mail.MessageRepresentation;
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.Group;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
 import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MessageMetaData;
@@ -71,7 +73,7 @@ import reactor.core.publisher.Mono;
  * Mailbox listener failures lead to eventBus retrying their execution, it ensures the result of the deletion to be
  * idempotent.
  */
-public class DeleteMessageListener implements MailboxListener.GroupMailboxListener {
+public class DeleteMessageListener implements EventListener.GroupEventListener {
     private static final Optional<CassandraId> ALL_MAILBOXES = Optional.empty();
 
     public static class DeleteMessageListenerGroup extends Group {
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListener.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListener.java
index e5915aa..dcfd070 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListener.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListener.java
@@ -23,16 +23,19 @@ import static org.apache.james.mailbox.cassandra.GhostMailbox.MAILBOX_ID;
 import static org.apache.james.mailbox.cassandra.GhostMailbox.MAILBOX_NAME;
 import static org.apache.james.mailbox.cassandra.GhostMailbox.TYPE;
 
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.Group;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxRenamed;
 
 /**
  * See https://issues.apache.org/jira/browse/MAILBOX-322 for reading about the Ghost mailbox bug.
  *
  * This class logs mailboxes writes in order to give context to analyse ghost mailbox bug.
  */
-public class MailboxOperationLoggingListener implements MailboxListener.GroupMailboxListener {
+public class MailboxOperationLoggingListener implements EventListener.GroupEventListener {
     public static class MailboxOperationLoggingListenerGroup extends Group {
 
     }
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraCombinationManagerTestSystem.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraCombinationManagerTestSystem.java
index 1e0c20e..1317934 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraCombinationManagerTestSystem.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraCombinationManagerTestSystem.java
@@ -20,11 +20,11 @@
 package org.apache.james.mailbox.cassandra;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.MessageManager;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MailboxNotFoundException;
 import org.apache.james.mailbox.model.Mailbox;
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerStressTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerStressTest.java
index 6120bbd..b55f8d7 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerStressTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerStressTest.java
@@ -20,9 +20,9 @@
 package org.apache.james.mailbox.cassandra;
 
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxManagerStressContract;
 import org.apache.james.mailbox.cassandra.mail.MailboxAggregateModule;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.store.PreDeletionHooks;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.extension.RegisterExtension;
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
index cc974d9..7012984 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
@@ -40,6 +40,7 @@ import org.apache.james.blob.api.BlobStore;
 import org.apache.james.blob.api.HashBlobId;
 import org.apache.james.blob.cassandra.BlobTables;
 import org.apache.james.core.Username;
+import org.apache.james.events.EventBus;
 import org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStore;
 import org.apache.james.eventsourcing.eventstore.cassandra.EventStoreDao;
 import org.apache.james.eventsourcing.eventstore.cassandra.JsonEventSerializer;
@@ -67,7 +68,6 @@ import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraUserMailboxRightsDAO;
 import org.apache.james.mailbox.cassandra.mail.MailboxAggregateModule;
 import org.apache.james.mailbox.cassandra.mail.eventsourcing.acl.ACLModule;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.FetchGroup;
 import org.apache.james.mailbox.model.MailboxACL;
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerSideEffectTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerSideEffectTest.java
index 082ee2a..e4ee044 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerSideEffectTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerSideEffectTest.java
@@ -24,8 +24,8 @@ import java.util.Set;
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
 import org.apache.james.backends.cassandra.StatementRecorder;
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.cassandra.mail.MailboxAggregateModule;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.extension.PreDeletionHook;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.quota.QuotaManager;
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerTestSystem.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerTestSystem.java
index ee64a24..c845175 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerTestSystem.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMessageIdManagerTestSystem.java
@@ -22,8 +22,8 @@ package org.apache.james.mailbox.cassandra;
 import java.util.Set;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.extension.PreDeletionHook;
 import org.apache.james.mailbox.quota.CurrentQuotaManager;
 import org.apache.james.mailbox.quota.QuotaManager;
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraTestSystemFixture.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraTestSystemFixture.java
index dea017b..1b4f270 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraTestSystemFixture.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraTestSystemFixture.java
@@ -22,6 +22,7 @@ package org.apache.james.mailbox.cassandra;
 import static org.mockito.Mockito.mock;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.Authenticator;
 import org.apache.james.mailbox.Authorizator;
@@ -33,7 +34,6 @@ import org.apache.james.mailbox.cassandra.quota.CassandraGlobalMaxQuotaDao;
 import org.apache.james.mailbox.cassandra.quota.CassandraPerDomainMaxQuotaDao;
 import org.apache.james.mailbox.cassandra.quota.CassandraPerUserMaxQuotaDao;
 import org.apache.james.mailbox.cassandra.quota.CassandraPerUserMaxQuotaManager;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.EventBusTestFixture;
 import org.apache.james.mailbox.events.InVMEventBus;
 import org.apache.james.mailbox.events.MemoryEventDeadLetters;
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListenerTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListenerTest.java
index 45adb03..6bb9b8c 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListenerTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListenerTest.java
@@ -21,7 +21,7 @@ package org.apache.james.mailbox.cassandra;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import org.apache.james.mailbox.events.Group;
+import org.apache.james.events.Group;
 import org.junit.jupiter.api.Test;
 
 class MailboxOperationLoggingListenerTest {
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
index d2f060b..8fe8fac 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
@@ -69,7 +69,6 @@ import com.github.fge.lambdas.Throwing;
 import com.github.fge.lambdas.runnable.ThrowingRunnable;
 
 import reactor.core.publisher.Mono;
-import reactor.core.scheduler.Schedulers;
 
 class CassandraMailboxMapperTest {
     private static final UidValidity UID_VALIDITY = UidValidity.of(52);
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
index 6554bb6..244189c 100644
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
+++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
@@ -43,6 +43,7 @@ import org.apache.james.backends.es.DocumentId;
 import org.apache.james.backends.es.ElasticSearchIndexer;
 import org.apache.james.backends.es.RoutingKey;
 import org.apache.james.backends.es.UpdatedRepresentation;
+import org.apache.james.events.Group;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MailboxManager.MessageCapabilities;
 import org.apache.james.mailbox.MailboxManager.SearchCapabilities;
@@ -52,7 +53,6 @@ import org.apache.james.mailbox.SessionProvider;
 import org.apache.james.mailbox.elasticsearch.MailboxElasticSearchConstants;
 import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson;
 import org.apache.james.mailbox.elasticsearch.search.ElasticSearchSearcher;
-import org.apache.james.mailbox.events.Group;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageId;
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
index 9178820..a6f5476 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
@@ -20,7 +20,6 @@
 package org.apache.james.mailbox.elasticsearch;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assumptions.assumeTrue;
 
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
@@ -29,7 +28,6 @@ import java.time.ZoneId;
 import org.apache.james.backends.es.DockerElasticSearchExtension;
 import org.apache.james.backends.es.ElasticSearchIndexer;
 import org.apache.james.backends.es.ReactorElasticSearchClient;
-import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageManager;
@@ -38,7 +36,6 @@ import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson;
 import org.apache.james.mailbox.elasticsearch.query.CriterionConverter;
 import org.apache.james.mailbox.elasticsearch.query.QueryConverter;
 import org.apache.james.mailbox.elasticsearch.search.ElasticSearchSearcher;
-import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
 import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
@@ -59,7 +56,6 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
 import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
 
 import reactor.core.publisher.Flux;
 
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
index fcfa31e..cee6c69 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
@@ -35,6 +35,7 @@ import org.apache.james.backends.es.DockerElasticSearchExtension;
 import org.apache.james.backends.es.ElasticSearchIndexer;
 import org.apache.james.backends.es.ReactorElasticSearchClient;
 import org.apache.james.core.Username;
+import org.apache.james.events.Group;
 import org.apache.james.mailbox.Authorizator;
 import org.apache.james.mailbox.DefaultMailboxes;
 import org.apache.james.mailbox.MailboxSession;
@@ -48,7 +49,6 @@ import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson;
 import org.apache.james.mailbox.elasticsearch.query.CriterionConverter;
 import org.apache.james.mailbox.elasticsearch.query.QueryConverter;
 import org.apache.james.mailbox.elasticsearch.search.ElasticSearchSearcher;
-import org.apache.james.mailbox.events.Group;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.extractor.ParsedContent;
 import org.apache.james.mailbox.extractor.TextExtractor;
@@ -78,7 +78,6 @@ import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
 import org.apache.james.mailbox.store.search.ListeningMessageSearchIndex;
 import org.apache.james.mailbox.store.search.ListeningMessageSearchIndexContract;
 import org.awaitility.Duration;
-import org.elasticsearch.index.IndexNotFoundException;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLetters.java b/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLetters.java
similarity index 98%
copy from mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLetters.java
copy to mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLetters.java
index 97e4a8e..e170221 100644
--- a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLetters.java
+++ b/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLetters.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import javax.inject.Inject;
 
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersDAO.java b/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java
similarity index 62%
copy from mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersDAO.java
copy to mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java
index 7b62fc0..4bfbd32 100644
--- a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersDAO.java
+++ b/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java
@@ -17,25 +17,23 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.delete;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
-import static org.apache.james.mailbox.events.tables.CassandraEventDeadLettersTable.EVENT;
-import static org.apache.james.mailbox.events.tables.CassandraEventDeadLettersTable.GROUP;
-import static org.apache.james.mailbox.events.tables.CassandraEventDeadLettersTable.INSERTION_ID;
-import static org.apache.james.mailbox.events.tables.CassandraEventDeadLettersTable.TABLE_NAME;
 
 import javax.inject.Inject;
 
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
 import org.apache.james.event.json.EventSerializer;
+import org.apache.james.events.tables.CassandraEventDeadLettersTable;
 
 import com.datastax.driver.core.PreparedStatement;
 import com.datastax.driver.core.Session;
+import com.datastax.driver.core.querybuilder.QueryBuilder;
 
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
@@ -61,62 +59,62 @@ public class CassandraEventDeadLettersDAO {
     }
 
     private PreparedStatement prepareInsertStatement(Session session) {
-        return session.prepare(insertInto(TABLE_NAME)
-            .value(GROUP, bindMarker(GROUP))
-            .value(INSERTION_ID, bindMarker(INSERTION_ID))
-            .value(EVENT, bindMarker(EVENT)));
+        return session.prepare(QueryBuilder.insertInto(CassandraEventDeadLettersTable.TABLE_NAME)
+            .value(CassandraEventDeadLettersTable.GROUP, bindMarker(CassandraEventDeadLettersTable.GROUP))
+            .value(CassandraEventDeadLettersTable.INSERTION_ID, bindMarker(CassandraEventDeadLettersTable.INSERTION_ID))
+            .value(CassandraEventDeadLettersTable.EVENT, bindMarker(CassandraEventDeadLettersTable.EVENT)));
     }
 
     private PreparedStatement prepareDeleteStatement(Session session) {
         return session.prepare(delete()
-            .from(TABLE_NAME)
-            .where(eq(GROUP, bindMarker(GROUP)))
-            .and(eq(INSERTION_ID, bindMarker(INSERTION_ID))));
+            .from(CassandraEventDeadLettersTable.TABLE_NAME)
+            .where(QueryBuilder.eq(CassandraEventDeadLettersTable.GROUP, bindMarker(CassandraEventDeadLettersTable.GROUP)))
+            .and(QueryBuilder.eq(CassandraEventDeadLettersTable.INSERTION_ID, bindMarker(CassandraEventDeadLettersTable.INSERTION_ID))));
     }
 
     private PreparedStatement prepareSelectEventStatement(Session session) {
-        return session.prepare(select(EVENT)
-            .from(TABLE_NAME)
-            .where(eq(GROUP, bindMarker(GROUP)))
-            .and(eq(INSERTION_ID, bindMarker(INSERTION_ID))));
+        return session.prepare(QueryBuilder.select(CassandraEventDeadLettersTable.EVENT)
+            .from(CassandraEventDeadLettersTable.TABLE_NAME)
+            .where(QueryBuilder.eq(CassandraEventDeadLettersTable.GROUP, bindMarker(CassandraEventDeadLettersTable.GROUP)))
+            .and(QueryBuilder.eq(CassandraEventDeadLettersTable.INSERTION_ID, bindMarker(CassandraEventDeadLettersTable.INSERTION_ID))));
     }
 
     private PreparedStatement prepareSelectInsertionIdsWithGroupStatement(Session session) {
-        return session.prepare(select(INSERTION_ID)
-            .from(TABLE_NAME)
-            .where(eq(GROUP, bindMarker(GROUP))));
+        return session.prepare(QueryBuilder.select(CassandraEventDeadLettersTable.INSERTION_ID)
+            .from(CassandraEventDeadLettersTable.TABLE_NAME)
+            .where(QueryBuilder.eq(CassandraEventDeadLettersTable.GROUP, bindMarker(CassandraEventDeadLettersTable.GROUP))));
     }
 
     private PreparedStatement prepareContainEventStatement(Session session) {
-        return session.prepare(select(EVENT)
-            .from(TABLE_NAME)
+        return session.prepare(QueryBuilder.select(CassandraEventDeadLettersTable.EVENT)
+            .from(CassandraEventDeadLettersTable.TABLE_NAME)
             .limit(1));
     }
 
     Mono<Void> store(Group group, Event failedEvent, EventDeadLetters.InsertionId insertionId) {
         return executor.executeVoid(insertStatement.bind()
-                .setString(GROUP, group.asString())
-                .setUUID(INSERTION_ID, insertionId.getId())
-                .setString(EVENT, eventSerializer.toJson(failedEvent)));
+                .setString(CassandraEventDeadLettersTable.GROUP, group.asString())
+                .setUUID(CassandraEventDeadLettersTable.INSERTION_ID, insertionId.getId())
+                .setString(CassandraEventDeadLettersTable.EVENT, eventSerializer.toJson(failedEvent)));
     }
 
     Mono<Void> removeEvent(Group group, EventDeadLetters.InsertionId failedInsertionId) {
         return executor.executeVoid(deleteStatement.bind()
-                .setString(GROUP, group.asString())
-                .setUUID(INSERTION_ID, failedInsertionId.getId()));
+                .setString(CassandraEventDeadLettersTable.GROUP, group.asString())
+                .setUUID(CassandraEventDeadLettersTable.INSERTION_ID, failedInsertionId.getId()));
     }
 
     Mono<Event> retrieveFailedEvent(Group group, EventDeadLetters.InsertionId insertionId) {
         return executor.executeSingleRow(selectEventStatement.bind()
-                .setString(GROUP, group.asString())
-                .setUUID(INSERTION_ID, insertionId.getId()))
-            .map(row -> deserializeEvent(row.getString(EVENT)));
+                .setString(CassandraEventDeadLettersTable.GROUP, group.asString())
+                .setUUID(CassandraEventDeadLettersTable.INSERTION_ID, insertionId.getId()))
+            .map(row -> deserializeEvent(row.getString(CassandraEventDeadLettersTable.EVENT)));
     }
 
     Flux<EventDeadLetters.InsertionId> retrieveInsertionIdsWithGroup(Group group) {
         return executor.executeRows(selectEventIdsWithGroupStatement.bind()
-                .setString(GROUP, group.asString()))
-            .map(row -> EventDeadLetters.InsertionId.of(row.getUUID(INSERTION_ID)));
+                .setString(CassandraEventDeadLettersTable.GROUP, group.asString()))
+            .map(row -> EventDeadLetters.InsertionId.of(row.getUUID(CassandraEventDeadLettersTable.INSERTION_ID)));
     }
 
     Mono<Boolean> containEvents() {
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersGroupDAO.java b/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersGroupDAO.java
similarity index 79%
copy from mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersGroupDAO.java
copy to mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersGroupDAO.java
index bb37a3d..766d507 100644
--- a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersGroupDAO.java
+++ b/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersGroupDAO.java
@@ -17,20 +17,20 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
-import static org.apache.james.mailbox.events.tables.CassandraEventDeadLettersGroupTable.GROUP;
-import static org.apache.james.mailbox.events.tables.CassandraEventDeadLettersGroupTable.TABLE_NAME;
 
 import javax.inject.Inject;
 
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
+import org.apache.james.events.tables.CassandraEventDeadLettersGroupTable;
 
 import com.datastax.driver.core.PreparedStatement;
 import com.datastax.driver.core.Session;
+import com.datastax.driver.core.querybuilder.QueryBuilder;
 import com.github.fge.lambdas.Throwing;
 
 import reactor.core.publisher.Flux;
@@ -49,22 +49,22 @@ public class CassandraEventDeadLettersGroupDAO {
     }
 
     private PreparedStatement prepareInsertStatement(Session session) {
-        return session.prepare(insertInto(TABLE_NAME)
-            .value(GROUP, bindMarker(GROUP)));
+        return session.prepare(QueryBuilder.insertInto(CassandraEventDeadLettersGroupTable.TABLE_NAME)
+            .value(CassandraEventDeadLettersGroupTable.GROUP, bindMarker(CassandraEventDeadLettersGroupTable.GROUP)));
     }
 
     private PreparedStatement prepareSelectStatement(Session session) {
-        return session.prepare(select(GROUP)
-            .from(TABLE_NAME));
+        return session.prepare(QueryBuilder.select(CassandraEventDeadLettersGroupTable.GROUP)
+            .from(CassandraEventDeadLettersGroupTable.TABLE_NAME));
     }
 
     Mono<Void> storeGroup(Group group) {
         return executor.executeVoid(insertStatement.bind()
-                .setString(GROUP, group.asString()));
+                .setString(CassandraEventDeadLettersGroupTable.GROUP, group.asString()));
     }
 
     Flux<Group> retrieveAllGroups() {
         return executor.executeRows(selectAllStatement.bind())
-            .map(Throwing.function(row -> Group.deserialize(row.getString(GROUP))));
+            .map(Throwing.function(row -> Group.deserialize(row.getString(CassandraEventDeadLettersGroupTable.GROUP))));
     }
 }
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersModule.java b/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersModule.java
new file mode 100644
index 0000000..53053e8
--- /dev/null
+++ b/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersModule.java
@@ -0,0 +1,46 @@
+/****************************************************************
+ * 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.events;
+
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.backends.cassandra.utils.CassandraConstants;
+import org.apache.james.events.tables.CassandraEventDeadLettersGroupTable;
+import org.apache.james.events.tables.CassandraEventDeadLettersTable;
+
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.schemabuilder.SchemaBuilder;
+
+public interface CassandraEventDeadLettersModule {
+    CassandraModule MODULE = CassandraModule.builder()
+        .table(CassandraEventDeadLettersTable.TABLE_NAME)
+        .comment("Holds event dead letter")
+        .options(options -> options
+            .caching(SchemaBuilder.KeyCaching.ALL,
+                SchemaBuilder.rows(CassandraConstants.DEFAULT_CACHED_ROW_PER_PARTITION)))
+        .statement(statement -> statement
+            .addPartitionKey(CassandraEventDeadLettersTable.GROUP, DataType.text())
+            .addClusteringColumn(CassandraEventDeadLettersTable.INSERTION_ID, DataType.uuid())
+            .addColumn(CassandraEventDeadLettersTable.EVENT, DataType.text()))
+        .table(CassandraEventDeadLettersGroupTable.TABLE_NAME)
+        .comment("Projection table for retrieving groups for all failed events")
+        .statement(statement -> statement
+            .addPartitionKey(CassandraEventDeadLettersGroupTable.GROUP, DataType.text()))
+        .build();
+}
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/Registration.java b/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/tables/CassandraEventDeadLettersGroupTable.java
similarity index 87%
rename from mailbox/api/src/main/java/org/apache/james/mailbox/events/Registration.java
rename to mailbox/event/event-cassandra/src/main/java/org/apache/james/events/tables/CassandraEventDeadLettersGroupTable.java
index c5a3a53..fff28aa 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/Registration.java
+++ b/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/tables/CassandraEventDeadLettersGroupTable.java
@@ -17,8 +17,11 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events.tables;
 
-public interface Registration {
-    void unregister();
+public interface CassandraEventDeadLettersGroupTable {
+
+    String TABLE_NAME = "group_table";
+
+    String GROUP = "group";
 }
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/SpamEventListener.java b/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/tables/CassandraEventDeadLettersTable.java
similarity index 83%
copy from mailbox/store/src/main/java/org/apache/james/mailbox/store/event/SpamEventListener.java
copy to mailbox/event/event-cassandra/src/main/java/org/apache/james/events/tables/CassandraEventDeadLettersTable.java
index 4e8e9c9..51cbef8 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/SpamEventListener.java
+++ b/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/tables/CassandraEventDeadLettersTable.java
@@ -16,10 +16,14 @@
  * specific language governing permissions and limitations      *
  * under the License.                                           *
  ****************************************************************/
-package org.apache.james.mailbox.store.event;
 
-import org.apache.james.mailbox.events.MailboxListener;
+package org.apache.james.events.tables;
 
-public interface SpamEventListener extends MailboxListener.GroupMailboxListener {
+public interface CassandraEventDeadLettersTable {
 
+    String TABLE_NAME = "event_dead_letters";
+
+    String GROUP = "group";
+    String INSERTION_ID = "insertionId";
+    String EVENT = "event";
 }
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLetters.java b/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLetters.java
index 97e4a8e..77a1c5e 100644
--- a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLetters.java
+++ b/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLetters.java
@@ -21,6 +21,10 @@ package org.apache.james.mailbox.events;
 
 import javax.inject.Inject;
 
+import org.apache.james.events.Event;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.Group;
+
 import com.google.common.base.Preconditions;
 
 import reactor.core.publisher.Flux;
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersDAO.java b/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersDAO.java
index 7b62fc0..0d20d43 100644
--- a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersDAO.java
+++ b/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersDAO.java
@@ -33,6 +33,9 @@ import javax.inject.Inject;
 
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
 import org.apache.james.event.json.EventSerializer;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.Group;
 
 import com.datastax.driver.core.PreparedStatement;
 import com.datastax.driver.core.Session;
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersGroupDAO.java b/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersGroupDAO.java
index bb37a3d..20b283e 100644
--- a/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersGroupDAO.java
+++ b/mailbox/event/event-cassandra/src/main/java/org/apache/james/mailbox/events/CassandraEventDeadLettersGroupDAO.java
@@ -28,6 +28,7 @@ import static org.apache.james.mailbox.events.tables.CassandraEventDeadLettersGr
 import javax.inject.Inject;
 
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
+import org.apache.james.events.Group;
 
 import com.datastax.driver.core.PreparedStatement;
 import com.datastax.driver.core.Session;
diff --git a/mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java b/mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java
new file mode 100644
index 0000000..d6ba016
--- /dev/null
+++ b/mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java
@@ -0,0 +1,137 @@
+/****************************************************************
+ * 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.events;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import org.apache.james.event.json.EventSerializer;
+import org.apache.james.mailbox.model.TestId;
+import org.apache.james.mailbox.model.TestMessageId;
+import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+class CassandraEventDeadLettersDAOTest {
+
+    @RegisterExtension
+    static CassandraClusterExtension cassandraClusterExtension = new CassandraClusterExtension(CassandraEventDeadLettersModule.MODULE);
+
+    private CassandraEventDeadLettersDAO cassandraEventDeadLettersDAO;
+
+    @BeforeEach
+    void setUp(CassandraCluster cassandraCluster) {
+        EventSerializer eventSerializer = new EventSerializer(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
+        cassandraEventDeadLettersDAO = new CassandraEventDeadLettersDAO(cassandraCluster.getConf(), eventSerializer);
+    }
+
+    @Test
+    void removeEventShouldSucceededWhenRemoveStoredEvent() {
+        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_A, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_1).block();
+
+        cassandraEventDeadLettersDAO.removeEvent(EventDeadLettersContract.GROUP_A, EventDeadLettersContract.INSERTION_ID_1).block();
+
+        assertThat(cassandraEventDeadLettersDAO
+                .retrieveInsertionIdsWithGroup(EventDeadLettersContract.GROUP_A)
+                .collectList().block())
+            .isEmpty();
+    }
+
+    @Test
+    void retrieveFailedEventShouldReturnEmptyWhenDefault() {
+        assertThat(cassandraEventDeadLettersDAO
+                .retrieveFailedEvent(EventDeadLettersContract.GROUP_A, EventDeadLettersContract.INSERTION_ID_1)
+                .blockOptional().isPresent())
+            .isFalse();
+    }
+
+    @Test
+    void retrieveFailedEventShouldReturnStoredEvent() {
+        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_A, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_1).block();
+        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_2, EventDeadLettersContract.INSERTION_ID_2).block();
+
+        assertThat(cassandraEventDeadLettersDAO
+                .retrieveFailedEvent(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.INSERTION_ID_2)
+                .blockOptional().get())
+            .isEqualTo(EventDeadLettersContract.EVENT_2);
+    }
+
+    @Test
+    void retrieveInsertionIdsWithGroupShouldReturnEmptyWhenDefault() {
+        assertThat(cassandraEventDeadLettersDAO
+                .retrieveInsertionIdsWithGroup(EventDeadLettersContract.GROUP_A)
+                .collectList().block())
+            .isEmpty();
+    }
+
+    @Test
+    void retrieveInsertionIdsWithGroupShouldReturnStoredInsertionId() {
+        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_1).block();
+        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_2, EventDeadLettersContract.INSERTION_ID_2).block();
+        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_3, EventDeadLettersContract.INSERTION_ID_3).block();
+
+        assertThat(cassandraEventDeadLettersDAO
+                .retrieveInsertionIdsWithGroup(EventDeadLettersContract.GROUP_B)
+                .collectList().block())
+            .containsOnly(EventDeadLettersContract.INSERTION_ID_1, EventDeadLettersContract.INSERTION_ID_2, EventDeadLettersContract.INSERTION_ID_3);
+    }
+
+    @Test
+    void shouldReturnTrueWhenEventStored() {
+        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_1).block();
+        assertThat(cassandraEventDeadLettersDAO.containEvents().block()).isTrue();
+    }
+
+    @Test
+    void shouldReturnTrueWhenNoEventStored() {
+        assertThat(cassandraEventDeadLettersDAO.containEvents().block()).isFalse();
+    }
+
+    @Test
+    void shouldReturnTrueWhenEventsStoredAndRemovedSome() {
+        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_1).block();
+        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_2).block();
+        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_3).block();
+
+        assertThat(cassandraEventDeadLettersDAO.containEvents().block()).isTrue();
+
+        cassandraEventDeadLettersDAO.removeEvent(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.INSERTION_ID_3).block();
+
+        assertThat(cassandraEventDeadLettersDAO.containEvents().block()).isTrue();
+    }
+
+    @Test
+    void shouldReturnFalseWhenRemovedAllEventsStored() {
+        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_1).block();
+        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_2).block();
+        cassandraEventDeadLettersDAO.store(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.EVENT_1, EventDeadLettersContract.INSERTION_ID_3).block();
+
+        assertThat(cassandraEventDeadLettersDAO.containEvents().block()).isTrue();
+
+        cassandraEventDeadLettersDAO.removeEvent(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.INSERTION_ID_3).block();
+        cassandraEventDeadLettersDAO.removeEvent(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.INSERTION_ID_2).block();
+        cassandraEventDeadLettersDAO.removeEvent(EventDeadLettersContract.GROUP_B, EventDeadLettersContract.INSERTION_ID_1).block();
+
+        assertThat(cassandraEventDeadLettersDAO.containEvents().block()).isFalse();
+    }
+
+}
diff --git a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersTest.java b/mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersGroupDAOTest.java
similarity index 59%
copy from mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersTest.java
copy to mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersGroupDAOTest.java
index 9930e9f..f5eef74 100644
--- a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersTest.java
+++ b/mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersGroupDAOTest.java
@@ -17,33 +17,42 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
+
+import static org.assertj.core.api.Assertions.assertThat;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
-import org.apache.james.event.json.EventSerializer;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.mailbox.model.TestMessageId;
-import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
-import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-class CassandraEventDeadLettersTest implements EventDeadLettersContract.AllContracts {
+public class CassandraEventDeadLettersGroupDAOTest {
 
     @RegisterExtension
     static CassandraClusterExtension cassandraClusterExtension = new CassandraClusterExtension(CassandraEventDeadLettersModule.MODULE);
 
-    private CassandraEventDeadLetters eventDeadLetters;
+    private static CassandraEventDeadLettersGroupDAO GROUP_DAO;
+
+    @BeforeAll
+    static void setUp(CassandraCluster cassandraCluster) {
+        GROUP_DAO = new CassandraEventDeadLettersGroupDAO(cassandraCluster.getConf());
+    }
 
-    @BeforeEach
-    void setUp(CassandraCluster cassandraCluster) {
-        EventSerializer eventSerializer = new EventSerializer(new TestId.Factory(), new TestMessageId.Factory(), new DefaultUserQuotaRootResolver.DefaultQuotaRootDeserializer());
-        eventDeadLetters = new CassandraEventDeadLetters(new CassandraEventDeadLettersDAO(cassandraCluster.getConf(), eventSerializer),
-                                                         new CassandraEventDeadLettersGroupDAO(cassandraCluster.getConf()));
+    @Test
+    void retrieveAllGroupsShouldReturnEmptyWhenDefault() {
+        assertThat(GROUP_DAO.retrieveAllGroups()
+                .collectList().block())
+            .isEmpty();
     }
 
-    @Override
-    public EventDeadLetters eventDeadLetters() {
-        return eventDeadLetters;
+    @Test
+    void retrieveAllGroupsShouldReturnStoredGroups() {
+        GROUP_DAO.storeGroup(EventDeadLettersContract.GROUP_A).block();
+        GROUP_DAO.storeGroup(EventDeadLettersContract.GROUP_B).block();
+
+        assertThat(GROUP_DAO.retrieveAllGroups()
+                .collectList().block())
+            .containsOnly(EventDeadLettersContract.GROUP_A, EventDeadLettersContract.GROUP_B);
     }
 }
diff --git a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersHealthCheckTest.java b/mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java
similarity index 98%
copy from mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersHealthCheckTest.java
copy to mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java
index cd8e7db..dce43af 100644
--- a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersHealthCheckTest.java
+++ b/mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
diff --git a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersTest.java b/mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersTest.java
similarity index 98%
copy from mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersTest.java
copy to mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersTest.java
index 9930e9f..2e3b85c 100644
--- a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersTest.java
+++ b/mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersTest.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
diff --git a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersHealthCheckTest.java b/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersHealthCheckTest.java
index cd8e7db..027ad73 100644
--- a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersHealthCheckTest.java
+++ b/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersHealthCheckTest.java
@@ -23,6 +23,8 @@ import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
 import org.apache.james.backends.cassandra.DockerCassandra;
 import org.apache.james.event.json.EventSerializer;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.EventDeadLettersHealthCheck;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
diff --git a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersTest.java b/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersTest.java
index 9930e9f..7d81bcd 100644
--- a/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersTest.java
+++ b/mailbox/event/event-cassandra/src/test/java/org/apache/james/mailbox/events/CassandraEventDeadLettersTest.java
@@ -22,6 +22,7 @@ package org.apache.james.mailbox.events;
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
 import org.apache.james.event.json.EventSerializer;
+import org.apache.james.events.EventDeadLetters;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
diff --git a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/InVMEventBus.java b/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/InVMEventBus.java
index 6e73b0f..1e92333 100644
--- a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/InVMEventBus.java
+++ b/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/InVMEventBus.java
@@ -25,6 +25,15 @@ import java.util.concurrent.ConcurrentHashMap;
 
 import javax.inject.Inject;
 
+import org.apache.james.events.Event;
+import org.apache.james.events.EventBus;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
+import org.apache.james.events.GroupAlreadyRegistered;
+import org.apache.james.events.GroupRegistrationNotFound;
+import org.apache.james.events.Registration;
+import org.apache.james.events.RegistrationKey;
 import org.apache.james.mailbox.events.delivery.EventDelivery;
 import org.apache.james.mailbox.events.delivery.EventDelivery.PermanentFailureHandler.StoreToDeadLetters;
 import org.apache.james.mailbox.events.delivery.EventDelivery.Retryer.BackoffRetryer;
@@ -39,8 +48,8 @@ import reactor.core.publisher.Mono;
 
 public class InVMEventBus implements EventBus {
 
-    private final Multimap<RegistrationKey, MailboxListener.ReactiveMailboxListener> registrations;
-    private final ConcurrentHashMap<Group, MailboxListener.ReactiveMailboxListener> groups;
+    private final Multimap<RegistrationKey, EventListener.ReactiveEventListener> registrations;
+    private final ConcurrentHashMap<Group, EventListener.ReactiveEventListener> groups;
     private final EventDelivery eventDelivery;
     private final RetryBackoffConfiguration retryBackoff;
     private final EventDeadLetters eventDeadLetters;
@@ -55,14 +64,14 @@ public class InVMEventBus implements EventBus {
     }
 
     @Override
-    public Mono<Registration> register(MailboxListener.ReactiveMailboxListener listener, RegistrationKey key) {
+    public Mono<Registration> register(EventListener.ReactiveEventListener listener, RegistrationKey key) {
         registrations.put(key, listener);
         return Mono.just(() -> registrations.remove(key, listener));
     }
 
     @Override
-    public Registration register(MailboxListener.ReactiveMailboxListener listener, Group group) {
-        MailboxListener previous = groups.putIfAbsent(group, listener);
+    public Registration register(EventListener.ReactiveEventListener listener, Group group) {
+        EventListener previous = groups.putIfAbsent(group, listener);
         if (previous == null) {
             return () -> groups.remove(group, listener);
         }
@@ -87,7 +96,7 @@ public class InVMEventBus implements EventBus {
         return Mono.empty();
     }
 
-    private MailboxListener.ReactiveMailboxListener retrieveListenerFromGroup(Group group) {
+    private EventListener.ReactiveEventListener retrieveListenerFromGroup(Group group) {
         return Optional.ofNullable(groups.get(group))
             .orElseThrow(() -> new GroupRegistrationNotFound(group));
     }
@@ -104,7 +113,7 @@ public class InVMEventBus implements EventBus {
             .then();
     }
 
-    private Mono<Void> groupDelivery(Event event, MailboxListener.ReactiveMailboxListener mailboxListener, Group group) {
+    private Mono<Void> groupDelivery(Event event, EventListener.ReactiveEventListener mailboxListener, Group group) {
         return eventDelivery.deliver(
             mailboxListener,
             event,
@@ -117,7 +126,7 @@ public class InVMEventBus implements EventBus {
         return groups.keySet();
     }
 
-    private Set<MailboxListener.ReactiveMailboxListener> registeredListenersByKeys(Set<RegistrationKey> keys) {
+    private Set<EventListener.ReactiveEventListener> registeredListenersByKeys(Set<RegistrationKey> keys) {
         return keys.stream()
             .flatMap(registrationKey -> registrations.get(registrationKey).stream())
             .collect(Guavate.toImmutableSet());
diff --git a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/MemoryEventDeadLetters.java b/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/MemoryEventDeadLetters.java
index 5f8af25..b11e26f 100644
--- a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/MemoryEventDeadLetters.java
+++ b/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/MemoryEventDeadLetters.java
@@ -19,6 +19,10 @@
 
 package org.apache.james.mailbox.events;
 
+import org.apache.james.events.Event;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.Group;
+
 import com.google.common.base.Preconditions;
 import com.google.common.collect.HashBasedTable;
 import com.google.common.collect.ImmutableList;
diff --git a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/EventDelivery.java b/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/EventDelivery.java
index d0f06dd..c0038ca 100644
--- a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/EventDelivery.java
+++ b/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/EventDelivery.java
@@ -22,10 +22,10 @@ package org.apache.james.mailbox.events.delivery;
 import static org.apache.james.mailbox.events.delivery.EventDelivery.PermanentFailureHandler.NO_HANDLER;
 import static org.apache.james.mailbox.events.delivery.EventDelivery.Retryer.NO_RETRYER;
 
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.EventDeadLetters;
-import org.apache.james.mailbox.events.Group;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
 import org.apache.james.mailbox.events.RetryBackoffConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -69,16 +69,16 @@ public interface EventDelivery {
 
         class BackoffRetryer implements EventDelivery.Retryer {
 
-            public static BackoffRetryer of(RetryBackoffConfiguration retryBackoff, MailboxListener mailboxListener) {
+            public static BackoffRetryer of(RetryBackoffConfiguration retryBackoff, EventListener mailboxListener) {
                 return new BackoffRetryer(retryBackoff, mailboxListener);
             }
 
             private static final Logger LOGGER = LoggerFactory.getLogger(BackoffRetryer.class);
 
             private final RetryBackoffConfiguration retryBackoff;
-            private final MailboxListener mailboxListener;
+            private final EventListener mailboxListener;
 
-            public BackoffRetryer(RetryBackoffConfiguration retryBackoff, MailboxListener mailboxListener) {
+            public BackoffRetryer(RetryBackoffConfiguration retryBackoff, EventListener mailboxListener) {
                 this.retryBackoff = retryBackoff;
                 this.mailboxListener = mailboxListener;
             }
@@ -126,9 +126,9 @@ public interface EventDelivery {
         Mono<Void> handle(Event event);
     }
 
-    Mono<Void> deliver(MailboxListener.ReactiveMailboxListener listener, Event event, DeliveryOption option);
+    Mono<Void> deliver(EventListener.ReactiveEventListener listener, Event event, DeliveryOption option);
 
-    default Mono<Void> deliver(MailboxListener listener, Event event, DeliveryOption option) {
-        return deliver(MailboxListener.wrapReactive(listener), event, option);
+    default Mono<Void> deliver(EventListener listener, Event event, DeliveryOption option) {
+        return deliver(EventListener.wrapReactive(listener), event, option);
     }
 }
diff --git a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/InVmEventDelivery.java b/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/InVmEventDelivery.java
index f4f7036..e8ed94c 100644
--- a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/InVmEventDelivery.java
+++ b/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/InVmEventDelivery.java
@@ -19,14 +19,14 @@
 
 package org.apache.james.mailbox.events.delivery;
 
-import static org.apache.james.mailbox.events.EventBus.Metrics.timerName;
+import static org.apache.james.events.EventBus.Metrics.timerName;
 import static org.apache.james.util.ReactorUtils.context;
 
 import javax.inject.Inject;
 
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.EventBus;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventBus;
+import org.apache.james.events.EventListener;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.util.MDCBuilder;
 import org.apache.james.util.MDCStructuredLogger;
@@ -51,14 +51,14 @@ public class InVmEventDelivery implements EventDelivery {
     }
 
     @Override
-    public Mono<Void> deliver(MailboxListener.ReactiveMailboxListener listener, Event event, DeliveryOption option) {
+    public Mono<Void> deliver(EventListener.ReactiveEventListener listener, Event event, DeliveryOption option) {
         Mono<Void> executionResult = deliverByOption(listener, event, option);
 
         return waitForResultIfNeeded(listener.getExecutionMode(), executionResult);
     }
 
-    private Mono<Void> waitForResultIfNeeded(MailboxListener.ExecutionMode executionMode, Mono<Void> executionResult) {
-        if (executionMode.equals(MailboxListener.ExecutionMode.SYNCHRONOUS)) {
+    private Mono<Void> waitForResultIfNeeded(EventListener.ExecutionMode executionMode, Mono<Void> executionResult) {
+        if (executionMode.equals(EventListener.ExecutionMode.SYNCHRONOUS)) {
             return executionResult;
         }
         return Flux.merge(executionResult, Mono.empty())
@@ -66,7 +66,7 @@ public class InVmEventDelivery implements EventDelivery {
             .onErrorResume(throwable -> Mono.empty());
     }
 
-    private Mono<Void> deliverByOption(MailboxListener.ReactiveMailboxListener listener, Event event, DeliveryOption deliveryOption) {
+    private Mono<Void> deliverByOption(EventListener.ReactiveEventListener listener, Event event, DeliveryOption deliveryOption) {
         Mono<Void> deliveryToListener = doDeliverToListener(listener, event)
             .doOnError(throwable -> structuredLogger(event, listener)
                 .log(logger -> logger.error("Error while processing listener", throwable)))
@@ -77,7 +77,7 @@ public class InVmEventDelivery implements EventDelivery {
             .then();
     }
 
-    private Mono<Void> doDeliverToListener(MailboxListener.ReactiveMailboxListener mailboxListener, Event event) {
+    private Mono<Void> doDeliverToListener(EventListener.ReactiveEventListener mailboxListener, Event event) {
         if (mailboxListener.isHandling(event)) {
             return Mono.defer(() -> Mono.from(metricFactory.decoratePublisherWithTimerMetric(timerName(mailboxListener),
                     mailboxListener.reactiveEvent(event))))
@@ -86,7 +86,7 @@ public class InVmEventDelivery implements EventDelivery {
         return Mono.empty();
     }
 
-    private MDCBuilder buildMDC(MailboxListener mailboxListener, Event event) {
+    private MDCBuilder buildMDC(EventListener mailboxListener, Event event) {
         return MDCBuilder.create()
             .addContext(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
             .addContext(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
@@ -94,7 +94,7 @@ public class InVmEventDelivery implements EventDelivery {
             .addContext(EventBus.StructuredLoggingFields.LISTENER_CLASS, mailboxListener.getClass());
     }
 
-    private StructuredLogger structuredLogger(Event event, MailboxListener mailboxListener) {
+    private StructuredLogger structuredLogger(Event event, EventListener mailboxListener) {
         return MDCStructuredLogger.forLogger(LOGGER)
             .addField(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
             .addField(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
diff --git a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/InVMEventBusTest.java b/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/InVMEventBusTest.java
index 5a6a6ea..c12963f 100644
--- a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/InVMEventBusTest.java
+++ b/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/InVMEventBusTest.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.mailbox.events;
 
+import org.apache.james.events.EventBus;
+import org.apache.james.events.EventDeadLetters;
 import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
 import org.junit.jupiter.api.BeforeEach;
diff --git a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersHealthCheckTest.java b/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersHealthCheckTest.java
index c05deb0..58c4e7e 100644
--- a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersHealthCheckTest.java
+++ b/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersHealthCheckTest.java
@@ -20,6 +20,8 @@
 package org.apache.james.mailbox.events;
 
 import org.apache.commons.lang3.NotImplementedException;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.EventDeadLettersHealthCheck;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 
diff --git a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersTest.java b/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersTest.java
index 2ef0996..43ae3df 100644
--- a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersTest.java
+++ b/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/MemoryEventDeadLettersTest.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.mailbox.events;
 
+import org.apache.james.events.EventDeadLetters;
 import org.junit.jupiter.api.BeforeEach;
 
 class MemoryEventDeadLettersTest implements EventDeadLettersContract.AllContracts {
diff --git a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/delivery/InVmEventDeliveryTest.java b/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/delivery/InVmEventDeliveryTest.java
index dd210a9..72f779a 100644
--- a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/delivery/InVmEventDeliveryTest.java
+++ b/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/delivery/InVmEventDeliveryTest.java
@@ -20,8 +20,8 @@
 package org.apache.james.mailbox.events.delivery;
 
 import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT;
+import static org.apache.james.mailbox.events.EventBusTestFixture.EventListenerCountingSuccessfulExecution;
 import static org.apache.james.mailbox.events.EventBusTestFixture.GROUP_A;
-import static org.apache.james.mailbox.events.EventBusTestFixture.MailboxListenerCountingSuccessfulExecution;
 import static org.apache.james.mailbox.events.delivery.EventDelivery.Retryer;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
@@ -32,7 +32,7 @@ import static org.mockito.Mockito.when;
 
 import java.time.Duration;
 
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.events.EventListener;
 import org.apache.james.mailbox.events.MemoryEventDeadLetters;
 import org.apache.james.mailbox.events.RetryBackoffConfiguration;
 import org.apache.james.mailbox.events.delivery.EventDelivery.DeliveryOption;
@@ -46,7 +46,7 @@ import org.junit.jupiter.api.Test;
 
 class InVmEventDeliveryTest {
     private InVmEventDelivery inVmEventDelivery;
-    private MailboxListenerCountingSuccessfulExecution listener;
+    private EventListenerCountingSuccessfulExecution listener;
 
     @BeforeEach
     void setUp() {
@@ -54,8 +54,8 @@ class InVmEventDeliveryTest {
         inVmEventDelivery = new InVmEventDelivery(new RecordingMetricFactory());
     }
 
-    MailboxListenerCountingSuccessfulExecution newListener() {
-        return spy(new MailboxListenerCountingSuccessfulExecution());
+    EventListenerCountingSuccessfulExecution newListener() {
+        return spy(new EventListenerCountingSuccessfulExecution());
     }
 
     @Nested
@@ -63,7 +63,7 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldDeliverEvent() {
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.SYNCHRONOUS);
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
             inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
                 .block();
 
@@ -73,7 +73,7 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldReturnSuccessSynchronousMono() {
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.SYNCHRONOUS);
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
             assertThatCode(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
                     .block())
                 .doesNotThrowAnyException();
@@ -81,7 +81,7 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldNotDeliverWhenListenerGetException() {
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.SYNCHRONOUS);
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
             doThrow(new RuntimeException())
                 .when(listener).event(EVENT);
 
@@ -95,7 +95,7 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldReturnAnErrorMonoWhenListenerGetException() {
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.SYNCHRONOUS);
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.SYNCHRONOUS);
             doThrow(new RuntimeException())
                 .when(listener).event(EVENT);
 
@@ -110,7 +110,7 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldDeliverEvent() {
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
             inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
                 .block();
 
@@ -120,7 +120,7 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldReturnSuccessSynchronousMono() {
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
             assertThatCode(() -> inVmEventDelivery.deliver(listener, EVENT, DeliveryOption.none())
                     .block())
                 .doesNotThrowAnyException();
@@ -128,7 +128,7 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldNotFailWhenListenerGetException() {
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
             doThrow(new RuntimeException())
                 .when(listener).event(EVENT);
 
@@ -139,7 +139,7 @@ class InVmEventDeliveryTest {
 
         @Test
         void deliverShouldReturnAnSuccessSyncMonoWhenListenerGetException() {
-            when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
+            when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
             doThrow(new RuntimeException())
                 .when(listener).event(EVENT);
 
@@ -154,7 +154,7 @@ class InVmEventDeliveryTest {
 
         @Test
         void retryShouldWorkWhenDeliverWithRetry() {
-            MailboxListenerCountingSuccessfulExecution listener = newListener();
+            EventListenerCountingSuccessfulExecution listener = newListener();
             doThrow(new RuntimeException())
                 .doThrow(new RuntimeException())
                 .doThrow(new RuntimeException())
@@ -173,7 +173,7 @@ class InVmEventDeliveryTest {
 
         @Test
         void failureHandlerShouldWorkWhenDeliverWithFailureHandler() {
-            MailboxListenerCountingSuccessfulExecution listener = newListener();
+            EventListenerCountingSuccessfulExecution listener = newListener();
             doThrow(new RuntimeException())
                 .when(listener).event(EVENT);
 
@@ -191,7 +191,7 @@ class InVmEventDeliveryTest {
 
         @Test
         void failureHandlerShouldNotWorkWhenRetrySuccess() {
-            MailboxListenerCountingSuccessfulExecution listener = newListener();
+            EventListenerCountingSuccessfulExecution listener = newListener();
             doThrow(new RuntimeException())
                 .doThrow(new RuntimeException())
                 .doCallRealMethod()
@@ -216,7 +216,7 @@ class InVmEventDeliveryTest {
 
         @Test
         void failureHandlerShouldWorkWhenRetryFails() {
-            MailboxListenerCountingSuccessfulExecution listener = newListener();
+            EventListenerCountingSuccessfulExecution listener = newListener();
             //do throw  RetryBackoffConfiguration.DEFAULT.DEFAULT_MAX_RETRIES + 1 times
             doThrow(new RuntimeException())
                 .doThrow(new RuntimeException())
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/GenericGroup.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/EventBusId.java
similarity index 58%
rename from mailbox/api/src/main/java/org/apache/james/mailbox/events/GenericGroup.java
rename to mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/EventBusId.java
index a679682..53f9d2c 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/GenericGroup.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/EventBusId.java
@@ -17,35 +17,56 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import java.util.Objects;
+import java.util.UUID;
 
-public class GenericGroup extends Group {
-    static final String DELIMITER = "-";
-    private final String groupName;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
 
-    public GenericGroup(String groupName) {
-        this.groupName = groupName;
+public class EventBusId {
+    public static EventBusId of(UUID uuid) {
+        return new EventBusId(uuid);
     }
 
-    @Override
-    public String asString() {
-        return super.asString() + DELIMITER + groupName;
+    public static EventBusId random() {
+        return new EventBusId(UUID.randomUUID());
+    }
+
+    public static EventBusId of(String serialized) {
+        return new EventBusId(UUID.fromString(serialized));
+    }
+
+    private final UUID id;
+
+    private EventBusId(UUID id) {
+        Preconditions.checkNotNull(id);
+        this.id = id;
     }
 
     @Override
     public final boolean equals(Object o) {
-        if (o instanceof GenericGroup) {
-            GenericGroup that = (GenericGroup) o;
-
-            return Objects.equals(this.groupName, that.groupName);
+        if (o instanceof EventBusId) {
+            EventBusId eventBusId = (EventBusId) o;
+            return Objects.equals(this.id, eventBusId.id);
         }
         return false;
     }
 
+    public String asString() {
+        return id.toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id);
+    }
+
     @Override
-    public final int hashCode() {
-        return Objects.hash(groupName);
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+            .add("id", id)
+            .toString();
     }
 }
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/EventDispatcher.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/EventDispatcher.java
similarity index 92%
copy from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/EventDispatcher.java
copy to mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/EventDispatcher.java
index af13994..99d0a7d 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/EventDispatcher.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/EventDispatcher.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import static com.rabbitmq.client.MessageProperties.PERSISTENT_TEXT_PLAIN;
 import static org.apache.james.backends.rabbitmq.Constants.AUTO_DELETE;
@@ -26,10 +26,10 @@ import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
 import static org.apache.james.backends.rabbitmq.Constants.EMPTY_ROUTING_KEY;
 import static org.apache.james.backends.rabbitmq.Constants.EXCLUSIVE;
 import static org.apache.james.backends.rabbitmq.Constants.NO_ARGUMENTS;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.EVENT_BUS_ID;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT_DEAD_LETTER_EXCHANGE_NAME;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT_DEAD_LETTER_QUEUE;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME;
+import static org.apache.james.events.RabbitMQEventBus.EVENT_BUS_ID;
+import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT_DEAD_LETTER_EXCHANGE_NAME;
+import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT_DEAD_LETTER_QUEUE;
+import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME;
 
 import java.nio.charset.StandardCharsets;
 import java.util.Collection;
@@ -37,7 +37,7 @@ import java.util.Collections;
 import java.util.Set;
 
 import org.apache.james.event.json.EventSerializer;
-import org.apache.james.mailbox.events.RoutingKeyConverter.RoutingKey;
+import org.apache.james.events.RoutingKeyConverter.RoutingKey;
 import org.apache.james.util.MDCBuilder;
 import org.apache.james.util.MDCStructuredLogger;
 import org.apache.james.util.StructuredLogger;
@@ -125,12 +125,12 @@ public class EventDispatcher {
         return Flux.fromIterable(keys)
             .flatMap(key -> localListenerRegistry.getLocalMailboxListeners(key)
                 .map(listener -> Tuples.of(key, listener)), EventBus.EXECUTION_RATE)
-            .filter(pair -> pair.getT2().getExecutionMode() == MailboxListener.ExecutionMode.SYNCHRONOUS)
+            .filter(pair -> pair.getT2().getExecutionMode() == EventListener.ExecutionMode.SYNCHRONOUS)
             .flatMap(pair -> executeListener(event, pair.getT2(), pair.getT1()), EventBus.EXECUTION_RATE)
             .then();
     }
 
-    private Mono<Void> executeListener(Event event, MailboxListener.ReactiveMailboxListener mailboxListener, RegistrationKey registrationKey) {
+    private Mono<Void> executeListener(Event event, EventListener.ReactiveEventListener mailboxListener, RegistrationKey registrationKey) {
         return mailboxListenerExecutor.execute(mailboxListener,
                     MDCBuilder.create()
                         .addContext(EventBus.StructuredLoggingFields.REGISTRATION_KEY, registrationKey),
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupConsumerRetry.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/GroupConsumerRetry.java
similarity index 96%
copy from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupConsumerRetry.java
copy to mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/GroupConsumerRetry.java
index 8286d30..b8526f8 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupConsumerRetry.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/GroupConsumerRetry.java
@@ -17,14 +17,13 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import static com.rabbitmq.client.MessageProperties.PERSISTENT_TEXT_PLAIN;
 import static org.apache.james.backends.rabbitmq.Constants.DIRECT_EXCHANGE;
 import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
 import static org.apache.james.backends.rabbitmq.Constants.EMPTY_ROUTING_KEY;
-import static org.apache.james.mailbox.events.GroupRegistration.RETRY_COUNT;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT;
+import static org.apache.james.events.GroupRegistration.RETRY_COUNT;
 
 import java.nio.charset.StandardCharsets;
 
@@ -53,7 +52,7 @@ class GroupConsumerRetry {
             return new RetryExchangeName(group.asString());
         }
 
-        static final String MAILBOX_EVENT_RETRY_EXCHANGE_PREFIX = MAILBOX_EVENT + "-retryExchange-";
+        static final String MAILBOX_EVENT_RETRY_EXCHANGE_PREFIX = RabbitMQEventBus.MAILBOX_EVENT + "-retryExchange-";
 
         private final String name;
 
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistration.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/GroupRegistration.java
similarity index 91%
copy from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistration.java
copy to mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/GroupRegistration.java
index 7d80a82..5c6285c 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistration.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/GroupRegistration.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import static org.apache.james.backends.rabbitmq.Constants.AUTO_DELETE;
 import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
@@ -25,9 +25,6 @@ import static org.apache.james.backends.rabbitmq.Constants.EMPTY_ROUTING_KEY;
 import static org.apache.james.backends.rabbitmq.Constants.EXCLUSIVE;
 import static org.apache.james.backends.rabbitmq.Constants.REQUEUE;
 import static org.apache.james.backends.rabbitmq.Constants.deadLetterQueue;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT_DEAD_LETTER_EXCHANGE_NAME;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME;
 
 import java.nio.charset.StandardCharsets;
 import java.util.Objects;
@@ -60,7 +57,7 @@ class GroupRegistration implements Registration {
             return new WorkQueueName(group);
         }
 
-        static final String MAILBOX_EVENT_WORK_QUEUE_PREFIX = MAILBOX_EVENT + "-workQueue-";
+        static final String MAILBOX_EVENT_WORK_QUEUE_PREFIX = RabbitMQEventBus.MAILBOX_EVENT + "-workQueue-";
 
         private final Group group;
 
@@ -79,7 +76,7 @@ class GroupRegistration implements Registration {
     static final int DEFAULT_RETRY_COUNT = 0;
 
     private final ReactorRabbitMQChannelPool channelPool;
-    private final MailboxListener.ReactiveMailboxListener mailboxListener;
+    private final EventListener.ReactiveEventListener mailboxListener;
     private final WorkQueueName queueName;
     private final Receiver receiver;
     private final Runnable unregisterGroup;
@@ -93,7 +90,7 @@ class GroupRegistration implements Registration {
     private Optional<Disposable> receiverSubscriber;
 
     GroupRegistration(ReactorRabbitMQChannelPool channelPool, Sender sender, ReceiverProvider receiverProvider, EventSerializer eventSerializer,
-                      MailboxListener.ReactiveMailboxListener mailboxListener, Group group, RetryBackoffConfiguration retryBackoff,
+                      EventListener.ReactiveEventListener mailboxListener, Group group, RetryBackoffConfiguration retryBackoff,
                       EventDeadLetters eventDeadLetters,
                       Runnable unregisterGroup, MailboxListenerExecutor mailboxListenerExecutor) {
         this.channelPool = channelPool;
@@ -127,9 +124,9 @@ class GroupRegistration implements Registration {
                 .durable(DURABLE)
                 .exclusive(!EXCLUSIVE)
                 .autoDelete(!AUTO_DELETE)
-                .arguments(deadLetterQueue(MAILBOX_EVENT_DEAD_LETTER_EXCHANGE_NAME)),
+                .arguments(deadLetterQueue(RabbitMQEventBus.MAILBOX_EVENT_DEAD_LETTER_EXCHANGE_NAME)),
             BindingSpecification.binding()
-                .exchange(MAILBOX_EVENT_EXCHANGE_NAME)
+                .exchange(RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME)
                 .queue(queueName.asString())
                 .routingKey(EMPTY_ROUTING_KEY));
     }
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistrationHandler.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
similarity index 93%
copy from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistrationHandler.java
copy to mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
index 251b375..c4f7814 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistrationHandler.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import java.util.Map;
 import java.util.Optional;
@@ -61,7 +61,7 @@ class GroupRegistrationHandler {
         groupRegistrations.values().forEach(GroupRegistration::unregister);
     }
 
-    Registration register(MailboxListener.ReactiveMailboxListener listener, Group group) {
+    Registration register(EventListener.ReactiveEventListener listener, Group group) {
         return groupRegistrations
             .compute(group, (groupToRegister, oldGroupRegistration) -> {
                 if (oldGroupRegistration != null) {
@@ -72,7 +72,7 @@ class GroupRegistrationHandler {
             .start();
     }
 
-    private GroupRegistration newGroupRegistration(MailboxListener.ReactiveMailboxListener listener, Group group) {
+    private GroupRegistration newGroupRegistration(EventListener.ReactiveEventListener listener, Group group) {
         return new GroupRegistration(
             channelPool, sender,
             receiverProvider,
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/EventDeadLettersHealthCheck.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/KeyReconnectionHandler.java
similarity index 50%
rename from mailbox/api/src/main/java/org/apache/james/mailbox/events/EventDeadLettersHealthCheck.java
rename to mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/KeyReconnectionHandler.java
index 27d33d6..24b5dd1 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/EventDeadLettersHealthCheck.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/KeyReconnectionHandler.java
@@ -17,41 +17,42 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
+
+import static org.apache.james.backends.rabbitmq.Constants.AUTO_DELETE;
+import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
+import static org.apache.james.backends.rabbitmq.Constants.EXCLUSIVE;
 
 import javax.inject.Inject;
 
-import org.apache.james.core.healthcheck.ComponentName;
-import org.apache.james.core.healthcheck.HealthCheck;
-import org.apache.james.core.healthcheck.Result;
+import org.apache.james.backends.rabbitmq.SimpleConnectionPool;
+import org.reactivestreams.Publisher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.Connection;
 
 import reactor.core.publisher.Mono;
 
-public class EventDeadLettersHealthCheck implements HealthCheck {
-    private static final ComponentName COMPONENT_NAME = new ComponentName("EventDeadLettersHealthCheck");
+public class KeyReconnectionHandler implements SimpleConnectionPool.ReconnectionHandler {
+    private static final Logger LOGGER = LoggerFactory.getLogger(KeyReconnectionHandler.class);
 
-    private final EventDeadLetters eventDeadLetters;
+    private final EventBusId eventBusId;
 
     @Inject
-    EventDeadLettersHealthCheck(EventDeadLetters eventDeadLetters) {
-        this.eventDeadLetters = eventDeadLetters;
-    }
-
-    @Override
-    public ComponentName componentName() {
-        return COMPONENT_NAME;
+    public KeyReconnectionHandler(EventBusId eventBusId) {
+        this.eventBusId = eventBusId;
     }
 
     @Override
-    public Mono<Result> check() {
-        return eventDeadLetters.containEvents()
-            .map(containEvents -> {
-                if (containEvents) {
-                    return Result.degraded(COMPONENT_NAME, "EventDeadLetters contain events. This might indicate transient failure on mailbox event processing.");
-                }
-
-                return Result.healthy(COMPONENT_NAME);
-            })
-            .onErrorResume(e -> Mono.just(Result.unhealthy(COMPONENT_NAME, "Error checking EventDeadLettersHealthCheck", e)));
+    public Publisher<Void> handleReconnection(Connection connection) {
+        return Mono.fromRunnable(() -> {
+            try (Channel channel = connection.createChannel()) {
+                channel.queueDeclare(KeyRegistrationHandler.EVENTBUS_QUEUE_NAME_PREFIX + eventBusId.asString(), DURABLE, !EXCLUSIVE, AUTO_DELETE, KeyRegistrationHandler.QUEUE_ARGUMENTS);
+            } catch (Exception e) {
+                LOGGER.error("Error recovering connection", e);
+            }
+        });
     }
 }
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistration.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/KeyRegistration.java
similarity index 94%
copy from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistration.java
copy to mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/KeyRegistration.java
index 8dd002d..b7d6c28 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistration.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/KeyRegistration.java
@@ -17,7 +17,9 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
+
+import org.apache.james.events.Registration;
 
 class KeyRegistration implements Registration {
     private final Runnable unregister;
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistrationHandler.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
similarity index 95%
copy from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistrationHandler.java
copy to mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
index f4d1de5..be06184 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistrationHandler.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
@@ -17,12 +17,12 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import static org.apache.james.backends.rabbitmq.Constants.AUTO_DELETE;
 import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
 import static org.apache.james.backends.rabbitmq.Constants.EXCLUSIVE;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.EVENT_BUS_ID;
+import static org.apache.james.events.RabbitMQEventBus.EVENT_BUS_ID;
 
 import java.nio.charset.StandardCharsets;
 import java.time.Duration;
@@ -127,7 +127,7 @@ class KeyRegistrationHandler {
         receiver.close();
     }
 
-    Mono<Registration> register(MailboxListener.ReactiveMailboxListener listener, RegistrationKey key) {
+    Mono<Registration> register(EventListener.ReactiveEventListener listener, RegistrationKey key) {
         LocalListenerRegistry.LocalRegistration registration = localListenerRegistry.addListener(key, listener);
 
         return registerIfNeeded(key, registration)
@@ -169,7 +169,7 @@ class KeyRegistrationHandler {
             .then();
     }
 
-    private Mono<Void> executeListener(MailboxListener.ReactiveMailboxListener listener, Event event, RegistrationKey key) {
+    private Mono<Void> executeListener(EventListener.ReactiveEventListener listener, Event event, RegistrationKey key) {
         MDCBuilder mdcBuilder = MDCBuilder.create()
             .addContext(EventBus.StructuredLoggingFields.REGISTRATION_KEY, key);
 
@@ -180,9 +180,9 @@ class KeyRegistrationHandler {
             .then();
     }
 
-    private boolean isLocalSynchronousListeners(EventBusId eventBusId, MailboxListener listener) {
+    private boolean isLocalSynchronousListeners(EventBusId eventBusId, EventListener listener) {
         return eventBusId.equals(this.eventBusId) &&
-            listener.getExecutionMode().equals(MailboxListener.ExecutionMode.SYNCHRONOUS);
+            listener.getExecutionMode().equals(EventListener.ExecutionMode.SYNCHRONOUS);
     }
 
     private Event toEvent(Delivery delivery) {
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/LocalListenerRegistry.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/LocalListenerRegistry.java
similarity index 77%
copy from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/LocalListenerRegistry.java
copy to mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/LocalListenerRegistry.java
index a76302d..05306ae 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/LocalListenerRegistry.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/LocalListenerRegistry.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import static com.google.common.base.Predicates.not;
 
@@ -26,6 +26,9 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Supplier;
 
+import org.apache.james.events.EventListener;
+import org.apache.james.events.RegistrationKey;
+
 import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableSet;
 
@@ -55,17 +58,17 @@ class LocalListenerRegistry {
         }
     }
 
-    private final ConcurrentHashMap<RegistrationKey, ImmutableSet<MailboxListener.ReactiveMailboxListener>> listenersByKey;
+    private final ConcurrentHashMap<RegistrationKey, ImmutableSet<EventListener.ReactiveEventListener>> listenersByKey;
 
     LocalListenerRegistry() {
         this.listenersByKey = new ConcurrentHashMap<>();
     }
 
-    LocalRegistration addListener(RegistrationKey registrationKey, MailboxListener.ReactiveMailboxListener listener) {
+    LocalRegistration addListener(RegistrationKey registrationKey, EventListener.ReactiveEventListener listener) {
         AtomicBoolean firstListener = new AtomicBoolean(false);
         listenersByKey.compute(registrationKey, (key, listeners) ->
             Optional.ofNullable(listeners)
-                .map(set -> ImmutableSet.<MailboxListener.ReactiveMailboxListener>builder().addAll(set).add(listener).build())
+                .map(set -> ImmutableSet.<EventListener.ReactiveEventListener>builder().addAll(set).add(listener).build())
                 .orElseGet(() -> {
                     firstListener.set(true);
                     return ImmutableSet.of(listener);
@@ -74,16 +77,16 @@ class LocalListenerRegistry {
         return new LocalRegistration(firstListener.get(), () -> removeListener(registrationKey, listener));
     }
 
-    LocalRegistration addListener(RegistrationKey registrationKey, MailboxListener listener) {
-        return addListener(registrationKey, MailboxListener.wrapReactive(listener));
+    LocalRegistration addListener(RegistrationKey registrationKey, EventListener listener) {
+        return addListener(registrationKey, EventListener.wrapReactive(listener));
     }
 
-    private RemovalStatus removeListener(RegistrationKey registrationKey, MailboxListener.ReactiveMailboxListener listener) {
+    private RemovalStatus removeListener(RegistrationKey registrationKey, EventListener.ReactiveEventListener listener) {
         AtomicBoolean lastListenerRemoved = new AtomicBoolean(false);
         listenersByKey.compute(registrationKey, (key, listeners) -> {
             boolean listenersContainRequested = Optional.ofNullable(listeners).orElse(ImmutableSet.of()).contains(listener);
             if (listenersContainRequested) {
-                ImmutableSet<MailboxListener.ReactiveMailboxListener> remainingListeners = removeListenerFromSet(listener, listeners);
+                ImmutableSet<EventListener.ReactiveEventListener> remainingListeners = removeListenerFromSet(listener, listeners);
                 if (remainingListeners.isEmpty()) {
                     lastListenerRemoved.set(true);
                     return null;
@@ -95,15 +98,15 @@ class LocalListenerRegistry {
         return lastListenerRemoved::get;
     }
 
-    private ImmutableSet<MailboxListener.ReactiveMailboxListener> removeListenerFromSet(MailboxListener listener, ImmutableSet<MailboxListener.ReactiveMailboxListener> listeners) {
-        ImmutableSet<MailboxListener.ReactiveMailboxListener> remainingListeners = listeners.stream().filter(not(listener::equals)).collect(Guavate.toImmutableSet());
+    private ImmutableSet<EventListener.ReactiveEventListener> removeListenerFromSet(EventListener listener, ImmutableSet<EventListener.ReactiveEventListener> listeners) {
+        ImmutableSet<EventListener.ReactiveEventListener> remainingListeners = listeners.stream().filter(not(listener::equals)).collect(Guavate.toImmutableSet());
         if (remainingListeners.isEmpty()) {
             return ImmutableSet.of();
         }
         return remainingListeners;
     }
 
-    Flux<MailboxListener.ReactiveMailboxListener> getLocalMailboxListeners(RegistrationKey registrationKey) {
+    Flux<EventListener.ReactiveEventListener> getLocalMailboxListeners(RegistrationKey registrationKey) {
         return Flux.fromIterable(listenersByKey.getOrDefault(registrationKey, ImmutableSet.of()));
     }
 }
\ No newline at end of file
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/MailboxListenerExecutor.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/MailboxListenerExecutor.java
similarity index 84%
copy from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/MailboxListenerExecutor.java
copy to mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/MailboxListenerExecutor.java
index deb0098..7b6afef 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/MailboxListenerExecutor.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/MailboxListenerExecutor.java
@@ -17,10 +17,13 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
-import static org.apache.james.mailbox.events.EventBus.Metrics.timerName;
+import static org.apache.james.events.EventBus.Metrics.timerName;
 
+import org.apache.james.events.Event;
+import org.apache.james.events.EventBus;
+import org.apache.james.events.EventListener;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.util.MDCBuilder;
 import org.apache.james.util.ReactorUtils;
@@ -34,7 +37,7 @@ class MailboxListenerExecutor {
         this.metricFactory = metricFactory;
     }
 
-    Mono<Void> execute(MailboxListener.ReactiveMailboxListener listener, MDCBuilder mdcBuilder, Event event) {
+    Mono<Void> execute(EventListener.ReactiveEventListener listener, MDCBuilder mdcBuilder, Event event) {
         if (listener.isHandling(event)) {
             return Mono.from(metricFactory.decoratePublisherWithTimerMetric(timerName(listener),
                 Mono.from(listener.reactiveEvent(event))
@@ -43,7 +46,7 @@ class MailboxListenerExecutor {
         return Mono.empty();
     }
 
-    private MDCBuilder mdc(MailboxListener listener, MDCBuilder mdcBuilder, Event event) {
+    private MDCBuilder mdc(EventListener listener, MDCBuilder mdcBuilder, Event event) {
         return mdcBuilder
             .addContext(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
             .addContext(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RabbitMQEventBus.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RabbitMQEventBus.java
similarity index 96%
copy from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RabbitMQEventBus.java
copy to mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RabbitMQEventBus.java
index eff6278..73a2209 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RabbitMQEventBus.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RabbitMQEventBus.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import java.util.Set;
 
@@ -127,13 +127,13 @@ public class RabbitMQEventBus implements EventBus, Startable {
     }
 
     @Override
-    public Mono<Registration> register(MailboxListener.ReactiveMailboxListener listener, RegistrationKey key) {
+    public Mono<Registration> register(EventListener.ReactiveEventListener listener, RegistrationKey key) {
         Preconditions.checkState(isRunning, NOT_RUNNING_ERROR_MESSAGE);
         return keyRegistrationHandler.register(listener, key);
     }
 
     @Override
-    public Registration register(MailboxListener.ReactiveMailboxListener listener, Group group) {
+    public Registration register(EventListener.ReactiveEventListener listener, Group group) {
         Preconditions.checkState(isRunning, NOT_RUNNING_ERROR_MESSAGE);
         return groupRegistrationHandler.register(listener, group);
     }
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RegistrationBinder.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RegistrationBinder.java
similarity index 94%
copy from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RegistrationBinder.java
copy to mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RegistrationBinder.java
index f4405a6..45fbd49 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RegistrationBinder.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RegistrationBinder.java
@@ -17,9 +17,9 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME;
+import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME;
 
 import reactor.core.publisher.Mono;
 import reactor.rabbitmq.BindingSpecification;
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/RegistrationKey.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RegistrationQueueName.java
similarity index 83%
rename from mailbox/api/src/main/java/org/apache/james/mailbox/events/RegistrationKey.java
rename to mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RegistrationQueueName.java
index 1d0e320..9da51a4 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/RegistrationKey.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RegistrationQueueName.java
@@ -17,15 +17,16 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
-public interface RegistrationKey {
+class RegistrationQueueName {
+    private final String queueName;
 
-    interface Factory {
-        Class<? extends RegistrationKey> forClass();
-
-        RegistrationKey fromString(String asString);
+    RegistrationQueueName(String queueName) {
+        this.queueName = queueName;
     }
 
-    String asString();
+    String asString() {
+        return queueName;
+    }
 }
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RoutingKeyConverter.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RoutingKeyConverter.java
similarity index 98%
copy from mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RoutingKeyConverter.java
copy to mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RoutingKeyConverter.java
index bf84ec1..79c6500 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RoutingKeyConverter.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/RoutingKeyConverter.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import static org.apache.james.backends.rabbitmq.Constants.EMPTY_ROUTING_KEY;
 
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/WaitDelayGenerator.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/WaitDelayGenerator.java
new file mode 100644
index 0000000..01e604d
--- /dev/null
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/events/WaitDelayGenerator.java
@@ -0,0 +1,83 @@
+/****************************************************************
+ * 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.events;
+
+import java.security.SecureRandom;
+import java.time.Duration;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.primitives.Ints;
+
+import reactor.core.publisher.Mono;
+import reactor.core.scheduler.Schedulers;
+
+class WaitDelayGenerator {
+
+    static WaitDelayGenerator of(RetryBackoffConfiguration retryBackoff) {
+        return new WaitDelayGenerator(retryBackoff);
+    }
+
+    private static Duration randomBetween(Duration base, Duration jitter) {
+        Preconditions.checkArgument(!jitter.isNegative(), "jitter value should always be positive");
+        if (jitter.isZero()) {
+            return base;
+        }
+        long maxJitterAsMillis = jitter.toMillis();
+        long jitterAsMillis = SECURE_RANDOM.nextInt(Ints.checkedCast(maxJitterAsMillis * 2)) / 2;
+        return base.plusMillis(jitterAsMillis);
+    }
+
+    private static final SecureRandom SECURE_RANDOM = new SecureRandom();
+
+    private final RetryBackoffConfiguration retryBackoff;
+
+    private WaitDelayGenerator(RetryBackoffConfiguration retryBackoff) {
+        this.retryBackoff = retryBackoff;
+    }
+
+    Mono<Integer> delayIfHaveTo(int retryCount) {
+        Mono<Integer> countRetryMono = Mono.just(retryCount);
+        if (!shouldDelay(retryCount)) {
+            return countRetryMono;
+        }
+
+        return countRetryMono
+            .delayElement(generateDelay(retryCount), Schedulers.elastic());
+    }
+
+    @VisibleForTesting
+    Duration generateDelay(int retryCount) {
+        if (!shouldDelay(retryCount)) {
+            return Duration.ZERO;
+        }
+        long exponentialFactor = Double.valueOf(Math.pow(2, retryCount - 1)).longValue();
+        Duration minDelay = retryBackoff.getFirstBackoff().multipliedBy(exponentialFactor);
+        Duration jitterDelay = retryBackoff.getFirstBackoff()
+            .multipliedBy(Double.valueOf(retryBackoff.getJitterFactor() * 100).intValue())
+            .dividedBy(100);
+
+        return randomBetween(minDelay, jitterDelay);
+    }
+
+    private boolean shouldDelay(int retryCount) {
+        return retryCount >= 1 && retryCount <= retryBackoff.getMaxRetries();
+    }
+}
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/EventDispatcher.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/EventDispatcher.java
index af13994..e7d1e62 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/EventDispatcher.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/EventDispatcher.java
@@ -37,6 +37,12 @@ import java.util.Collections;
 import java.util.Set;
 
 import org.apache.james.event.json.EventSerializer;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventBus;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
+import org.apache.james.events.RegistrationKey;
 import org.apache.james.mailbox.events.RoutingKeyConverter.RoutingKey;
 import org.apache.james.util.MDCBuilder;
 import org.apache.james.util.MDCStructuredLogger;
@@ -125,12 +131,12 @@ public class EventDispatcher {
         return Flux.fromIterable(keys)
             .flatMap(key -> localListenerRegistry.getLocalMailboxListeners(key)
                 .map(listener -> Tuples.of(key, listener)), EventBus.EXECUTION_RATE)
-            .filter(pair -> pair.getT2().getExecutionMode() == MailboxListener.ExecutionMode.SYNCHRONOUS)
+            .filter(pair -> pair.getT2().getExecutionMode() == EventListener.ExecutionMode.SYNCHRONOUS)
             .flatMap(pair -> executeListener(event, pair.getT2(), pair.getT1()), EventBus.EXECUTION_RATE)
             .then();
     }
 
-    private Mono<Void> executeListener(Event event, MailboxListener.ReactiveMailboxListener mailboxListener, RegistrationKey registrationKey) {
+    private Mono<Void> executeListener(Event event, EventListener.ReactiveEventListener mailboxListener, RegistrationKey registrationKey) {
         return mailboxListenerExecutor.execute(mailboxListener,
                     MDCBuilder.create()
                         .addContext(EventBus.StructuredLoggingFields.REGISTRATION_KEY, registrationKey),
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupConsumerRetry.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupConsumerRetry.java
index 8286d30..d74cc64 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupConsumerRetry.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupConsumerRetry.java
@@ -29,6 +29,10 @@ import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT;
 import java.nio.charset.StandardCharsets;
 
 import org.apache.james.event.json.EventSerializer;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventBus;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.Group;
 import org.apache.james.util.MDCStructuredLogger;
 import org.apache.james.util.StructuredLogger;
 import org.slf4j.Logger;
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistration.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistration.java
index 7d80a82..e07d6a7 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistration.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistration.java
@@ -37,6 +37,12 @@ import java.util.function.Predicate;
 import org.apache.james.backends.rabbitmq.ReactorRabbitMQChannelPool;
 import org.apache.james.backends.rabbitmq.ReceiverProvider;
 import org.apache.james.event.json.EventSerializer;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventBus;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
+import org.apache.james.events.Registration;
 import org.apache.james.util.MDCBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -79,7 +85,7 @@ class GroupRegistration implements Registration {
     static final int DEFAULT_RETRY_COUNT = 0;
 
     private final ReactorRabbitMQChannelPool channelPool;
-    private final MailboxListener.ReactiveMailboxListener mailboxListener;
+    private final EventListener.ReactiveEventListener mailboxListener;
     private final WorkQueueName queueName;
     private final Receiver receiver;
     private final Runnable unregisterGroup;
@@ -93,7 +99,7 @@ class GroupRegistration implements Registration {
     private Optional<Disposable> receiverSubscriber;
 
     GroupRegistration(ReactorRabbitMQChannelPool channelPool, Sender sender, ReceiverProvider receiverProvider, EventSerializer eventSerializer,
-                      MailboxListener.ReactiveMailboxListener mailboxListener, Group group, RetryBackoffConfiguration retryBackoff,
+                      EventListener.ReactiveEventListener mailboxListener, Group group, RetryBackoffConfiguration retryBackoff,
                       EventDeadLetters eventDeadLetters,
                       Runnable unregisterGroup, MailboxListenerExecutor mailboxListenerExecutor) {
         this.channelPool = channelPool;
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistrationHandler.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistrationHandler.java
index 251b375..950ac44 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistrationHandler.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/GroupRegistrationHandler.java
@@ -26,6 +26,12 @@ import java.util.concurrent.ConcurrentHashMap;
 import org.apache.james.backends.rabbitmq.ReactorRabbitMQChannelPool;
 import org.apache.james.backends.rabbitmq.ReceiverProvider;
 import org.apache.james.event.json.EventSerializer;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
+import org.apache.james.events.GroupAlreadyRegistered;
+import org.apache.james.events.GroupRegistrationNotFound;
+import org.apache.james.events.Registration;
 
 import reactor.rabbitmq.Sender;
 
@@ -61,7 +67,7 @@ class GroupRegistrationHandler {
         groupRegistrations.values().forEach(GroupRegistration::unregister);
     }
 
-    Registration register(MailboxListener.ReactiveMailboxListener listener, Group group) {
+    Registration register(EventListener.ReactiveEventListener listener, Group group) {
         return groupRegistrations
             .compute(group, (groupToRegister, oldGroupRegistration) -> {
                 if (oldGroupRegistration != null) {
@@ -72,7 +78,7 @@ class GroupRegistrationHandler {
             .start();
     }
 
-    private GroupRegistration newGroupRegistration(MailboxListener.ReactiveMailboxListener listener, Group group) {
+    private GroupRegistration newGroupRegistration(EventListener.ReactiveEventListener listener, Group group) {
         return new GroupRegistration(
             channelPool, sender,
             receiverProvider,
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistration.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistration.java
index 8dd002d..be1f399 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistration.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistration.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.mailbox.events;
 
+import org.apache.james.events.Registration;
+
 class KeyRegistration implements Registration {
     private final Runnable unregister;
 
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistrationHandler.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistrationHandler.java
index f4d1de5..0731ca8 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistrationHandler.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/KeyRegistrationHandler.java
@@ -32,6 +32,11 @@ import java.util.function.Predicate;
 
 import org.apache.james.backends.rabbitmq.ReceiverProvider;
 import org.apache.james.event.json.EventSerializer;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventBus;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Registration;
+import org.apache.james.events.RegistrationKey;
 import org.apache.james.util.MDCBuilder;
 import org.apache.james.util.MDCStructuredLogger;
 import org.apache.james.util.StructuredLogger;
@@ -127,7 +132,7 @@ class KeyRegistrationHandler {
         receiver.close();
     }
 
-    Mono<Registration> register(MailboxListener.ReactiveMailboxListener listener, RegistrationKey key) {
+    Mono<Registration> register(EventListener.ReactiveEventListener listener, RegistrationKey key) {
         LocalListenerRegistry.LocalRegistration registration = localListenerRegistry.addListener(key, listener);
 
         return registerIfNeeded(key, registration)
@@ -169,7 +174,7 @@ class KeyRegistrationHandler {
             .then();
     }
 
-    private Mono<Void> executeListener(MailboxListener.ReactiveMailboxListener listener, Event event, RegistrationKey key) {
+    private Mono<Void> executeListener(EventListener.ReactiveEventListener listener, Event event, RegistrationKey key) {
         MDCBuilder mdcBuilder = MDCBuilder.create()
             .addContext(EventBus.StructuredLoggingFields.REGISTRATION_KEY, key);
 
@@ -180,9 +185,9 @@ class KeyRegistrationHandler {
             .then();
     }
 
-    private boolean isLocalSynchronousListeners(EventBusId eventBusId, MailboxListener listener) {
+    private boolean isLocalSynchronousListeners(EventBusId eventBusId, EventListener listener) {
         return eventBusId.equals(this.eventBusId) &&
-            listener.getExecutionMode().equals(MailboxListener.ExecutionMode.SYNCHRONOUS);
+            listener.getExecutionMode().equals(EventListener.ExecutionMode.SYNCHRONOUS);
     }
 
     private Event toEvent(Delivery delivery) {
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/LocalListenerRegistry.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/LocalListenerRegistry.java
index a76302d..468bde6 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/LocalListenerRegistry.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/LocalListenerRegistry.java
@@ -26,6 +26,9 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Supplier;
 
+import org.apache.james.events.EventListener;
+import org.apache.james.events.RegistrationKey;
+
 import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableSet;
 
@@ -55,17 +58,17 @@ class LocalListenerRegistry {
         }
     }
 
-    private final ConcurrentHashMap<RegistrationKey, ImmutableSet<MailboxListener.ReactiveMailboxListener>> listenersByKey;
+    private final ConcurrentHashMap<RegistrationKey, ImmutableSet<EventListener.ReactiveEventListener>> listenersByKey;
 
     LocalListenerRegistry() {
         this.listenersByKey = new ConcurrentHashMap<>();
     }
 
-    LocalRegistration addListener(RegistrationKey registrationKey, MailboxListener.ReactiveMailboxListener listener) {
+    LocalRegistration addListener(RegistrationKey registrationKey, EventListener.ReactiveEventListener listener) {
         AtomicBoolean firstListener = new AtomicBoolean(false);
         listenersByKey.compute(registrationKey, (key, listeners) ->
             Optional.ofNullable(listeners)
-                .map(set -> ImmutableSet.<MailboxListener.ReactiveMailboxListener>builder().addAll(set).add(listener).build())
+                .map(set -> ImmutableSet.<EventListener.ReactiveEventListener>builder().addAll(set).add(listener).build())
                 .orElseGet(() -> {
                     firstListener.set(true);
                     return ImmutableSet.of(listener);
@@ -74,16 +77,16 @@ class LocalListenerRegistry {
         return new LocalRegistration(firstListener.get(), () -> removeListener(registrationKey, listener));
     }
 
-    LocalRegistration addListener(RegistrationKey registrationKey, MailboxListener listener) {
-        return addListener(registrationKey, MailboxListener.wrapReactive(listener));
+    LocalRegistration addListener(RegistrationKey registrationKey, EventListener listener) {
+        return addListener(registrationKey, EventListener.wrapReactive(listener));
     }
 
-    private RemovalStatus removeListener(RegistrationKey registrationKey, MailboxListener.ReactiveMailboxListener listener) {
+    private RemovalStatus removeListener(RegistrationKey registrationKey, EventListener.ReactiveEventListener listener) {
         AtomicBoolean lastListenerRemoved = new AtomicBoolean(false);
         listenersByKey.compute(registrationKey, (key, listeners) -> {
             boolean listenersContainRequested = Optional.ofNullable(listeners).orElse(ImmutableSet.of()).contains(listener);
             if (listenersContainRequested) {
-                ImmutableSet<MailboxListener.ReactiveMailboxListener> remainingListeners = removeListenerFromSet(listener, listeners);
+                ImmutableSet<EventListener.ReactiveEventListener> remainingListeners = removeListenerFromSet(listener, listeners);
                 if (remainingListeners.isEmpty()) {
                     lastListenerRemoved.set(true);
                     return null;
@@ -95,15 +98,15 @@ class LocalListenerRegistry {
         return lastListenerRemoved::get;
     }
 
-    private ImmutableSet<MailboxListener.ReactiveMailboxListener> removeListenerFromSet(MailboxListener listener, ImmutableSet<MailboxListener.ReactiveMailboxListener> listeners) {
-        ImmutableSet<MailboxListener.ReactiveMailboxListener> remainingListeners = listeners.stream().filter(not(listener::equals)).collect(Guavate.toImmutableSet());
+    private ImmutableSet<EventListener.ReactiveEventListener> removeListenerFromSet(EventListener listener, ImmutableSet<EventListener.ReactiveEventListener> listeners) {
+        ImmutableSet<EventListener.ReactiveEventListener> remainingListeners = listeners.stream().filter(not(listener::equals)).collect(Guavate.toImmutableSet());
         if (remainingListeners.isEmpty()) {
             return ImmutableSet.of();
         }
         return remainingListeners;
     }
 
-    Flux<MailboxListener.ReactiveMailboxListener> getLocalMailboxListeners(RegistrationKey registrationKey) {
+    Flux<EventListener.ReactiveEventListener> getLocalMailboxListeners(RegistrationKey registrationKey) {
         return Flux.fromIterable(listenersByKey.getOrDefault(registrationKey, ImmutableSet.of()));
     }
 }
\ No newline at end of file
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/MailboxListenerExecutor.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/MailboxListenerExecutor.java
index deb0098..f35dc77 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/MailboxListenerExecutor.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/MailboxListenerExecutor.java
@@ -19,8 +19,11 @@
 
 package org.apache.james.mailbox.events;
 
-import static org.apache.james.mailbox.events.EventBus.Metrics.timerName;
+import static org.apache.james.events.EventBus.Metrics.timerName;
 
+import org.apache.james.events.Event;
+import org.apache.james.events.EventBus;
+import org.apache.james.events.EventListener;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.util.MDCBuilder;
 import org.apache.james.util.ReactorUtils;
@@ -34,7 +37,7 @@ class MailboxListenerExecutor {
         this.metricFactory = metricFactory;
     }
 
-    Mono<Void> execute(MailboxListener.ReactiveMailboxListener listener, MDCBuilder mdcBuilder, Event event) {
+    Mono<Void> execute(EventListener.ReactiveEventListener listener, MDCBuilder mdcBuilder, Event event) {
         if (listener.isHandling(event)) {
             return Mono.from(metricFactory.decoratePublisherWithTimerMetric(timerName(listener),
                 Mono.from(listener.reactiveEvent(event))
@@ -43,7 +46,7 @@ class MailboxListenerExecutor {
         return Mono.empty();
     }
 
-    private MDCBuilder mdc(MailboxListener listener, MDCBuilder mdcBuilder, Event event) {
+    private MDCBuilder mdc(EventListener listener, MDCBuilder mdcBuilder, Event event) {
         return mdcBuilder
             .addContext(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
             .addContext(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RabbitMQEventBus.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RabbitMQEventBus.java
index eff6278..14c4804 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RabbitMQEventBus.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RabbitMQEventBus.java
@@ -27,6 +27,13 @@ import javax.inject.Inject;
 import org.apache.james.backends.rabbitmq.ReactorRabbitMQChannelPool;
 import org.apache.james.backends.rabbitmq.ReceiverProvider;
 import org.apache.james.event.json.EventSerializer;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventBus;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
+import org.apache.james.events.Registration;
+import org.apache.james.events.RegistrationKey;
 import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.metrics.api.MetricFactory;
 
@@ -127,13 +134,13 @@ public class RabbitMQEventBus implements EventBus, Startable {
     }
 
     @Override
-    public Mono<Registration> register(MailboxListener.ReactiveMailboxListener listener, RegistrationKey key) {
+    public Mono<Registration> register(EventListener.ReactiveEventListener listener, RegistrationKey key) {
         Preconditions.checkState(isRunning, NOT_RUNNING_ERROR_MESSAGE);
         return keyRegistrationHandler.register(listener, key);
     }
 
     @Override
-    public Registration register(MailboxListener.ReactiveMailboxListener listener, Group group) {
+    public Registration register(EventListener.ReactiveEventListener listener, Group group) {
         Preconditions.checkState(isRunning, NOT_RUNNING_ERROR_MESSAGE);
         return groupRegistrationHandler.register(listener, group);
     }
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RegistrationBinder.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RegistrationBinder.java
index f4405a6..88fa692 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RegistrationBinder.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RegistrationBinder.java
@@ -21,6 +21,8 @@ package org.apache.james.mailbox.events;
 
 import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME;
 
+import org.apache.james.events.RegistrationKey;
+
 import reactor.core.publisher.Mono;
 import reactor.rabbitmq.BindingSpecification;
 import reactor.rabbitmq.Sender;
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RoutingKeyConverter.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RoutingKeyConverter.java
index bf84ec1..755ef27 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RoutingKeyConverter.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RoutingKeyConverter.java
@@ -27,6 +27,8 @@ import java.util.Set;
 
 import javax.inject.Inject;
 
+import org.apache.james.events.RegistrationKey;
+
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Joiner;
 import com.google.common.base.Preconditions;
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/InsertionIdTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/EventBusIdTest.java
similarity index 66%
copy from mailbox/api/src/test/java/org/apache/james/mailbox/events/InsertionIdTest.java
copy to mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/EventBusIdTest.java
index f8a1e0e..67220dc 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/InsertionIdTest.java
+++ b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/EventBusIdTest.java
@@ -17,10 +17,9 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.util.UUID;
 
@@ -28,29 +27,24 @@ import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
 
-class InsertionIdTest {
+class EventBusIdTest {
+
     private static final UUID UUID_1 = UUID.fromString("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
 
     @Test
-    void eventIdShouldMatchBeanContract() {
-        EqualsVerifier.forClass(EventDeadLetters.InsertionId.class).verify();
+    void eventBusIdShouldMatchBeanContract() {
+        EqualsVerifier.forClass(EventBusId.class);
     }
 
     @Test
     void ofShouldDeserializeUUIDs() {
-        assertThat(EventDeadLetters.InsertionId.of(UUID_1.toString()))
-            .isEqualTo(EventDeadLetters.InsertionId.of(UUID_1));
-    }
-
-    @Test
-    void ofStringShouldThrowOnNullValue() {
-        assertThatThrownBy(() -> EventDeadLetters.InsertionId.of((String) null))
-            .isInstanceOf(NullPointerException.class);
+        assertThat(EventBusId.of(UUID_1.toString()))
+            .isEqualTo(EventBusId.of(UUID_1));
     }
 
     @Test
-    void ofUuidShouldThrowOnNullValue() {
-        assertThatThrownBy(() -> EventDeadLetters.InsertionId.of((UUID) null))
-            .isInstanceOf(NullPointerException.class);
+    void asStringShouldReturnWrappedValue() {
+        assertThat(EventBusId.of(UUID_1).asString())
+            .isEqualTo("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
     }
 }
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/LocalListenerRegistryTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/LocalListenerRegistryTest.java
similarity index 85%
copy from mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/LocalListenerRegistryTest.java
copy to mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/LocalListenerRegistryTest.java
index 10ee4d8..a3de3f6 100644
--- a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/LocalListenerRegistryTest.java
+++ b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/LocalListenerRegistryTest.java
@@ -17,9 +17,9 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
-import static org.apache.james.mailbox.events.MailboxListener.wrapReactive;
+import static org.apache.james.events.EventListener.wrapReactive;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.time.Duration;
@@ -53,7 +53,7 @@ class LocalListenerRegistryTest {
 
     @Test
     void getLocalMailboxListenersShouldReturnPreviouslyAddedListener() {
-        MailboxListener listener = event -> { };
+        EventListener listener = event -> { };
         testee.addListener(KEY_1, listener);
 
         assertThat(testee.getLocalMailboxListeners(KEY_1).collectList().block())
@@ -62,8 +62,8 @@ class LocalListenerRegistryTest {
 
     @Test
     void getLocalMailboxListenersShouldReturnPreviouslyAddedListeners() {
-        MailboxListener listener1 = event -> { };
-        MailboxListener listener2 = event -> { };
+        EventListener listener1 = event -> { };
+        EventListener listener2 = event -> { };
         testee.addListener(KEY_1, listener1);
         testee.addListener(KEY_1, listener2);
 
@@ -73,8 +73,8 @@ class LocalListenerRegistryTest {
 
     @Test
     void getLocalMailboxListenersShouldNotReturnRemovedListeners() {
-        MailboxListener listener1 = event -> { };
-        MailboxListener listener2 = event -> { };
+        EventListener listener1 = event -> { };
+        EventListener listener2 = event -> { };
         testee.addListener(KEY_1, listener1);
         LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener2);
 
@@ -86,15 +86,15 @@ class LocalListenerRegistryTest {
 
     @Test
     void addListenerShouldReturnFirstListenerWhenNoPreviouslyRegisteredListeners() {
-        MailboxListener listener = event -> { };
+        EventListener listener = event -> { };
 
         assertThat(testee.addListener(KEY_1, listener).isFirstListener()).isTrue();
     }
 
     @Test
     void addListenerShouldNotReturnFirstListenerWhenPreviouslyRegisteredListeners() {
-        MailboxListener listener = event -> { };
-        MailboxListener listener2 = event -> { };
+        EventListener listener = event -> { };
+        EventListener listener2 = event -> { };
 
         testee.addListener(KEY_1, listener);
 
@@ -103,8 +103,8 @@ class LocalListenerRegistryTest {
 
     @Test
     void removeListenerShouldNotReturnLastListenerRemovedWhenSeveralListener() {
-        MailboxListener listener = event -> { };
-        MailboxListener listener2 = event -> { };
+        EventListener listener = event -> { };
+        EventListener listener2 = event -> { };
 
         LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener);
         testee.addListener(KEY_1, listener2);
@@ -114,7 +114,7 @@ class LocalListenerRegistryTest {
 
     @Test
     void removeListenerShouldReturnLastListenerRemovedWhenOneListener() {
-        MailboxListener listener = event -> { };
+        EventListener listener = event -> { };
 
 
         LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener);
@@ -128,7 +128,7 @@ class LocalListenerRegistryTest {
 
         @Test
         void getLocalMailboxListenersShouldReturnPreviousAddedListener() throws Exception {
-            MailboxListener listener = event -> { };
+            EventListener listener = event -> { };
 
             ConcurrentTestRunner.builder()
                 .operation((threadNumber, operationNumber) -> testee.addListener(KEY_1, listener))
@@ -142,9 +142,9 @@ class LocalListenerRegistryTest {
 
         @Test
         void getLocalMailboxListenersShouldReturnAllPreviousAddedListeners() throws Exception {
-            MailboxListener listener1 = event -> { };
-            MailboxListener listener2 = event -> { };
-            MailboxListener listener3 = event -> { };
+            EventListener listener1 = event -> { };
+            EventListener listener2 = event -> { };
+            EventListener listener3 = event -> { };
 
             ConcurrentTestRunner.builder()
                 .randomlyDistributedOperations(
@@ -161,7 +161,7 @@ class LocalListenerRegistryTest {
 
         @Test
         void getLocalMailboxListenersShouldReturnEmptyWhenRemoveAddedListener() throws Exception {
-            MailboxListener listener1 = event -> { };
+            EventListener listener1 = event -> { };
 
             LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener1);
 
@@ -177,9 +177,9 @@ class LocalListenerRegistryTest {
 
         @Test
         void addListenerOnlyReturnIsFirstListenerForEmptyRegistry() throws Exception {
-            MailboxListener listener1 = event -> { };
-            MailboxListener listener2 = event -> { };
-            MailboxListener listener3 = event -> { };
+            EventListener listener1 = event -> { };
+            EventListener listener2 = event -> { };
+            EventListener listener3 = event -> { };
 
             AtomicInteger firstListenerCount = new AtomicInteger(0);
 
@@ -211,7 +211,7 @@ class LocalListenerRegistryTest {
 
         @Test
         void removeListenerOnlyReturnLastListenerRemovedForEmptyRegistry() throws Exception {
-            MailboxListener listener1 = event -> { };
+            EventListener listener1 = event -> { };
             AtomicInteger lastListenerRemoved = new AtomicInteger(0);
 
             LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener1);
@@ -230,11 +230,11 @@ class LocalListenerRegistryTest {
 
         @Test
         void iterationShouldPerformOnASnapshotOfListenersSet() {
-            MailboxListener listener1 = event -> { };
-            MailboxListener listener2 = event -> { };
-            MailboxListener listener3 = event -> { };
-            MailboxListener listener4 = event -> { };
-            MailboxListener listener5 = event -> { };
+            EventListener listener1 = event -> { };
+            EventListener listener2 = event -> { };
+            EventListener listener3 = event -> { };
+            EventListener listener4 = event -> { };
+            EventListener listener5 = event -> { };
 
             testee.addListener(KEY_1, listener1);
             testee.addListener(KEY_1, listener2);
@@ -242,7 +242,7 @@ class LocalListenerRegistryTest {
             testee.addListener(KEY_1, listener4);
             LocalListenerRegistry.LocalRegistration registration5 = testee.addListener(KEY_1, listener5);
 
-            Mono<List<MailboxListener.ReactiveMailboxListener>> listeners = testee.getLocalMailboxListeners(KEY_1)
+            Mono<List<EventListener.ReactiveEventListener>> listeners = testee.getLocalMailboxListeners(KEY_1)
                 .publishOn(Schedulers.elastic())
                 .delayElements(Duration.ofMillis(100))
                 .collectList();
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/NetworkErrorTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/NetworkErrorTest.java
similarity index 88%
copy from mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/NetworkErrorTest.java
copy to mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/NetworkErrorTest.java
index ab7fa36..2e9ec01 100644
--- a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/NetworkErrorTest.java
+++ b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/NetworkErrorTest.java
@@ -17,13 +17,13 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT;
-import static org.apache.james.mailbox.events.EventBusTestFixture.GROUP_A;
-import static org.apache.james.mailbox.events.EventBusTestFixture.NO_KEYS;
-import static org.apache.james.mailbox.events.EventBusTestFixture.RETRY_BACKOFF_CONFIGURATION;
-import static org.apache.james.mailbox.events.EventBusTestFixture.newListener;
+import static org.apache.james.events.EventBusTestFixture.EVENT;
+import static org.apache.james.events.EventBusTestFixture.GROUP_A;
+import static org.apache.james.events.EventBusTestFixture.NO_KEYS;
+import static org.apache.james.events.EventBusTestFixture.RETRY_BACKOFF_CONFIGURATION;
+import static org.apache.james.events.EventBusTestFixture.newListener;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.Mockito.verify;
 
@@ -69,7 +69,7 @@ class NetworkErrorTest {
 
     @Test
     void dispatchShouldWorkAfterNetworkIssuesForOldRegistration() {
-        MailboxListener listener = newListener();
+        EventListener listener = newListener();
         eventBus.register(listener, GROUP_A);
 
         rabbitMQExtension.getRabbitMQ().pause();
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/NetworkErrorTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
similarity index 69%
copy from mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/NetworkErrorTest.java
copy to mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
index ab7fa36..a7371d9 100644
--- a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/NetworkErrorTest.java
+++ b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/RabbitMQEventBusDeadLetterQueueUpgradeTest.java
@@ -17,29 +17,31 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT;
-import static org.apache.james.mailbox.events.EventBusTestFixture.GROUP_A;
-import static org.apache.james.mailbox.events.EventBusTestFixture.NO_KEYS;
-import static org.apache.james.mailbox.events.EventBusTestFixture.RETRY_BACKOFF_CONFIGURATION;
-import static org.apache.james.mailbox.events.EventBusTestFixture.newListener;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.Mockito.verify;
+import static org.apache.james.backends.rabbitmq.Constants.AUTO_DELETE;
+import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
+import static org.apache.james.backends.rabbitmq.Constants.EXCLUSIVE;
+import static org.apache.james.events.EventBusTestFixture.RETRY_BACKOFF_CONFIGURATION;
+import static org.assertj.core.api.Assertions.assertThatCode;
 
 import org.apache.james.backends.rabbitmq.RabbitMQExtension;
-import org.apache.james.backends.rabbitmq.RabbitMQFixture;
 import org.apache.james.event.json.EventSerializer;
+import org.apache.james.events.EventBusTestFixture.GroupA;
+import org.apache.james.events.GroupRegistration.WorkQueueName;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
+import org.apache.james.mailbox.util.EventCollector;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-class NetworkErrorTest {
+import reactor.rabbitmq.QueueSpecification;
+
+class RabbitMQEventBusDeadLetterQueueUpgradeTest {
     @RegisterExtension
     static RabbitMQExtension rabbitMQExtension = RabbitMQExtension.singletonRabbitMQ()
         .isolationPolicy(RabbitMQExtension.IsolationPolicy.WEAK);
@@ -68,21 +70,19 @@ class NetworkErrorTest {
     }
 
     @Test
-    void dispatchShouldWorkAfterNetworkIssuesForOldRegistration() {
-        MailboxListener listener = newListener();
-        eventBus.register(listener, GROUP_A);
-
-        rabbitMQExtension.getRabbitMQ().pause();
-
-        assertThatThrownBy(() -> eventBus.dispatch(EVENT, NO_KEYS).block())
-            .isInstanceOf(IllegalStateException.class)
-            .hasMessageContaining("Retries exhausted");
-
-        rabbitMQExtension.getRabbitMQ().unpause();
-
-        eventBus.dispatch(EVENT, NO_KEYS).block();
-        RabbitMQFixture.awaitAtMostThirtySeconds
-            .untilAsserted(() -> verify(listener).event(EVENT));
+    void eventBusShouldStartWhenDeadLetterUpgradeWasNotPerformed() {
+        GroupA registeredGroup = new GroupA();
+        WorkQueueName workQueueName = WorkQueueName.of(registeredGroup);
+        
+        rabbitMQExtension.getSender()
+            .declareQueue(QueueSpecification.queue(workQueueName.asString())
+                .durable(DURABLE)
+                .exclusive(!EXCLUSIVE)
+                .autoDelete(!AUTO_DELETE))
+            .block();
+
+        assertThatCode(eventBus::start).doesNotThrowAnyException();
+        assertThatCode(() -> eventBus.register(new EventCollector(), registeredGroup)).doesNotThrowAnyException();
     }
 
 }
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RabbitMQEventBusTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
similarity index 91%
copy from mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RabbitMQEventBusTest.java
copy to mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
index ff88499..47e84be 100644
--- a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RabbitMQEventBusTest.java
+++ b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/RabbitMQEventBusTest.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import static org.apache.james.backends.rabbitmq.Constants.AUTO_DELETE;
 import static org.apache.james.backends.rabbitmq.Constants.DIRECT_EXCHANGE;
@@ -25,20 +25,20 @@ import static org.apache.james.backends.rabbitmq.Constants.DURABLE;
 import static org.apache.james.backends.rabbitmq.Constants.EMPTY_ROUTING_KEY;
 import static org.apache.james.backends.rabbitmq.Constants.EXCLUSIVE;
 import static org.apache.james.backends.rabbitmq.Constants.NO_ARGUMENTS;
-import static org.apache.james.mailbox.events.EventBusConcurrentTestContract.newCountingListener;
-import static org.apache.james.mailbox.events.EventBusTestFixture.ALL_GROUPS;
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT;
-import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT_2;
-import static org.apache.james.mailbox.events.EventBusTestFixture.GROUP_A;
-import static org.apache.james.mailbox.events.EventBusTestFixture.GROUP_B;
-import static org.apache.james.mailbox.events.EventBusTestFixture.KEY_1;
-import static org.apache.james.mailbox.events.EventBusTestFixture.NO_KEYS;
-import static org.apache.james.mailbox.events.EventBusTestFixture.newAsyncListener;
-import static org.apache.james.mailbox.events.EventBusTestFixture.newListener;
-import static org.apache.james.mailbox.events.GroupRegistration.WorkQueueName.MAILBOX_EVENT_WORK_QUEUE_PREFIX;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT_DEAD_LETTER_QUEUE;
-import static org.apache.james.mailbox.events.RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME;
+import static org.apache.james.events.EventBusConcurrentTestContract.newCountingListener;
+import static org.apache.james.events.EventBusTestFixture.ALL_GROUPS;
+import static org.apache.james.events.EventBusTestFixture.EVENT;
+import static org.apache.james.events.EventBusTestFixture.EVENT_2;
+import static org.apache.james.events.EventBusTestFixture.GROUP_A;
+import static org.apache.james.events.EventBusTestFixture.GROUP_B;
+import static org.apache.james.events.EventBusTestFixture.KEY_1;
+import static org.apache.james.events.EventBusTestFixture.NO_KEYS;
+import static org.apache.james.events.EventBusTestFixture.newAsyncListener;
+import static org.apache.james.events.EventBusTestFixture.newListener;
+import static org.apache.james.events.GroupRegistration.WorkQueueName.MAILBOX_EVENT_WORK_QUEUE_PREFIX;
+import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT;
+import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT_DEAD_LETTER_QUEUE;
+import static org.apache.james.events.RabbitMQEventBus.MAILBOX_EVENT_EXCHANGE_NAME;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -64,10 +64,10 @@ import org.apache.james.backends.rabbitmq.RabbitMQFixture;
 import org.apache.james.backends.rabbitmq.RabbitMQManagementAPI;
 import org.apache.james.backends.rabbitmq.ReceiverProvider;
 import org.apache.james.event.json.EventSerializer;
-import org.apache.james.mailbox.events.EventBusTestFixture.GroupA;
-import org.apache.james.mailbox.events.EventBusTestFixture.MailboxListenerCountingSuccessfulExecution;
-import org.apache.james.mailbox.events.EventDispatcher.DispatchingFailureGroup;
-import org.apache.james.mailbox.events.RoutingKeyConverter.RoutingKey;
+import org.apache.james.events.EventBusTestFixture.EventListenerCountingSuccessfulExecution;
+import org.apache.james.events.EventBusTestFixture.GroupA;
+import org.apache.james.events.EventDispatcher.DispatchingFailureGroup;
+import org.apache.james.events.RoutingKeyConverter.RoutingKey;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
@@ -286,7 +286,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
 
     @Test
     void registerGroupShouldCreateRetryExchange() throws Exception {
-        MailboxListener listener = newListener();
+        EventListener listener = newListener();
         EventBusTestFixture.GroupA registeredGroup = new EventBusTestFixture.GroupA();
         eventBus.register(listener, registeredGroup);
 
@@ -306,7 +306,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
 
         @Test
         void rabbitMQEventBusShouldHandleBulksGracefully() throws Exception {
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
             eventBus().register(countingListener1, new EventBusTestFixture.GroupA());
             int totalGlobalRegistrations = 1; // GroupA
 
@@ -347,9 +347,9 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
 
         @Test
         void inProcessingEventShouldBeReDispatchedToAnotherEventBusWhenOneIsDown() {
-            MailboxListenerCountingSuccessfulExecution eventBusListener = spy(new EventBusTestFixture.MailboxListenerCountingSuccessfulExecution());
-            MailboxListenerCountingSuccessfulExecution eventBus2Listener = spy(new EventBusTestFixture.MailboxListenerCountingSuccessfulExecution());
-            MailboxListenerCountingSuccessfulExecution eventBus3Listener = spy(new EventBusTestFixture.MailboxListenerCountingSuccessfulExecution());
+            EventListenerCountingSuccessfulExecution eventBusListener = spy(new EventListenerCountingSuccessfulExecution());
+            EventListenerCountingSuccessfulExecution eventBus2Listener = spy(new EventListenerCountingSuccessfulExecution());
+            EventListenerCountingSuccessfulExecution eventBus3Listener = spy(new EventListenerCountingSuccessfulExecution());
             Answer<?> callEventAndSleepForever = invocation -> {
                 invocation.callRealMethod();
                 TimeUnit.SECONDS.sleep(Long.MAX_VALUE);
@@ -462,7 +462,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
                 @Test
                 void dispatchShouldWorkAfterNetworkIssuesForOldRegistrationAndKey() {
                     rabbitMQEventBusWithNetWorkIssue.start();
-                    MailboxListener listener = newListener();
+                    EventListener listener = newListener();
                     Mono.from(rabbitMQEventBusWithNetWorkIssue.register(listener, KEY_1)).block();
 
                     rabbitMQNetWorkIssueExtension.getRabbitMQ().pause();
@@ -492,7 +492,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void dispatchShouldWorkAfterRestartForOldRegistration() throws Exception {
                 eventBus.start();
-                MailboxListener listener = newListener();
+                EventListener listener = newListener();
                 eventBus.register(listener, GROUP_A);
 
                 rabbitMQExtension.getRabbitMQ().restart();
@@ -504,7 +504,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void dispatchShouldWorkAfterRestartForNewRegistration() throws Exception {
                 eventBus.start();
-                MailboxListener listener = newListener();
+                EventListener listener = newListener();
 
                 rabbitMQExtension.getRabbitMQ().restart();
 
@@ -519,7 +519,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void redeliverShouldWorkAfterRestartForOldRegistration() throws Exception {
                 eventBus.start();
-                MailboxListener listener = newListener();
+                EventListener listener = newListener();
                 eventBus.register(listener, GROUP_A);
 
                 rabbitMQExtension.getRabbitMQ().restart();
@@ -531,7 +531,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void redeliverShouldWorkAfterRestartForNewRegistration() throws Exception {
                 eventBus.start();
-                MailboxListener listener = newListener();
+                EventListener listener = newListener();
 
                 rabbitMQExtension.getRabbitMQ().restart();
 
@@ -544,7 +544,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void dispatchShouldWorkAfterRestartForOldKeyRegistration() throws Exception {
                 eventBus.start();
-                MailboxListener listener = newListener();
+                EventListener listener = newListener();
                 Mono.from(eventBus.register(listener, KEY_1)).block();
 
                 rabbitMQExtension.getRabbitMQ().restart();
@@ -556,7 +556,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void dispatchedMessagesShouldSurviveARabbitMQRestart() throws Exception {
                 eventBusWithKeyHandlerNotStarted.startWithoutStartingKeyRegistrationHandler();
-                MailboxListener listener = newAsyncListener();
+                EventListener listener = newAsyncListener();
                 Mono.from(eventBusWithKeyHandlerNotStarted.register(listener, KEY_1)).block();
                 Mono<Void> dispatch = eventBusWithKeyHandlerNotStarted.dispatch(EVENT, KEY_1);
                 dispatch.block();
@@ -572,7 +572,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void dispatchShouldWorkAfterRestartForNewKeyRegistration() throws Exception {
                 eventBus.start();
-                MailboxListener listener = newListener();
+                EventListener listener = newListener();
 
                 rabbitMQExtension.getRabbitMQ().restart();
 
@@ -585,7 +585,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void dispatchShouldWorkAfterNetworkIssuesForNewRegistration() {
                 eventBus.start();
-                MailboxListener listener = newListener();
+                EventListener listener = newListener();
 
                 rabbitMQExtension.getRabbitMQ().pause();
 
@@ -603,7 +603,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void redeliverShouldWorkAfterNetworkIssuesForNewRegistration() {
                 eventBus.start();
-                MailboxListener listener = newListener();
+                EventListener listener = newListener();
 
                 rabbitMQExtension.getRabbitMQ().pause();
 
@@ -620,8 +620,8 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void dispatchShouldWorkAfterNetworkIssuesForOldKeyRegistration() {
                 eventBus.start();
-                MailboxListener listener = newListener();
-                when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
+                EventListener listener = newListener();
+                when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
                 Mono.from(eventBus.register(listener, KEY_1)).block();
 
                 rabbitMQExtension.getRabbitMQ().pause();
@@ -639,8 +639,8 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void dispatchShouldWorkAfterNetworkIssuesForNewKeyRegistration() {
                 eventBus.start();
-                MailboxListener listener = newListener();
-                when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
+                EventListener listener = newListener();
+                when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
 
                 rabbitMQExtension.getRabbitMQ().pause();
 
@@ -667,7 +667,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void stopShouldNotDeleteGroupRegistrationWorkQueue() {
                 eventBus.start();
-                eventBus.register(mock(MailboxListener.class), GROUP_A);
+                eventBus.register(mock(EventListener.class), GROUP_A);
                 eventBus.stop();
 
                 assertThat(rabbitManagementAPI.listQueues())
@@ -692,7 +692,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             void dispatchShouldStopDeliveringEventsShortlyAfterStopIsCalled() throws Exception {
                 eventBus.start();
 
-                MailboxListenerCountingSuccessfulExecution listener = new MailboxListenerCountingSuccessfulExecution();
+                EventListenerCountingSuccessfulExecution listener = new EventListenerCountingSuccessfulExecution();
                 eventBus.register(listener, GROUP_A);
 
                 try (Closeable closeable = ConcurrentTestRunner.builder()
@@ -759,7 +759,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
 
             @Test
             void multipleEventBusStopShouldNotDeleteGroupRegistrationWorkQueue() {
-                eventBus.register(mock(MailboxListener.class), GROUP_A);
+                eventBus.register(mock(EventListener.class), GROUP_A);
 
                 eventBus.stop();
                 eventBus2.stop();
@@ -788,7 +788,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
                 eventBus.start();
                 eventBus2.start();
 
-                MailboxListenerCountingSuccessfulExecution listener = new MailboxListenerCountingSuccessfulExecution();
+                EventListenerCountingSuccessfulExecution listener = new EventListenerCountingSuccessfulExecution();
                 eventBus.register(listener, GROUP_A);
                 eventBus2.register(listener, GROUP_A);
 
@@ -967,7 +967,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
         }
     }
 
-    private void assertThatListenerReceiveOneEvent(MailboxListener listener) {
+    private void assertThatListenerReceiveOneEvent(EventListener listener) {
         RabbitMQFixture.awaitAtMostThirtySeconds
             .untilAsserted(() -> verify(listener).event(EVENT));
     }
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RoutingKeyConverterTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/RoutingKeyConverterTest.java
similarity index 99%
copy from mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RoutingKeyConverterTest.java
copy to mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/RoutingKeyConverterTest.java
index 4b158dc..d07d95a 100644
--- a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RoutingKeyConverterTest.java
+++ b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/RoutingKeyConverterTest.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.events;
+package org.apache.james.events;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/WaitDelayGeneratorTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/WaitDelayGeneratorTest.java
new file mode 100644
index 0000000..045e114
--- /dev/null
+++ b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/events/WaitDelayGeneratorTest.java
@@ -0,0 +1,103 @@
+/****************************************************************
+ * 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.events;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.time.Duration;
+
+import org.assertj.core.api.SoftAssertions;
+import org.junit.jupiter.api.Test;
+
+class WaitDelayGeneratorTest {
+
+    @Test
+    void generateDelayShouldReturnZeroWhenZeroRetryCount() {
+        WaitDelayGenerator generator = WaitDelayGenerator.of(RetryBackoffConfiguration.DEFAULT);
+
+        assertThat(generator.generateDelay(0))
+            .isEqualTo(Duration.ofMillis(0));
+    }
+
+    @Test
+    void generateDelayShouldReturnByRandomInRangeOfExponentialGrowthOfRetryCount() {
+        WaitDelayGenerator generator = WaitDelayGenerator.of(RetryBackoffConfiguration.builder()
+            .maxRetries(4)
+            .firstBackoff(Duration.ofMillis(100))
+            .jitterFactor(0.5)
+            .build());
+
+        SoftAssertions.assertSoftly(softly -> {
+            softly.assertThat(generator.generateDelay(1).toMillis())
+                .isBetween(50L, 150L);
+            softly.assertThat(generator.generateDelay(2).toMillis())
+                .isBetween(100L, 300L);
+            softly.assertThat(generator.generateDelay(3).toMillis())
+                .isBetween(200L, 600L);
+            softly.assertThat(generator.generateDelay(4).toMillis())
+                .isBetween(300L, 1200L);
+        });
+    }
+
+    @Test
+    void generateDelayShouldReturnZeroWhenZeroMaxRetries() {
+        WaitDelayGenerator generator = WaitDelayGenerator.of(RetryBackoffConfiguration.builder()
+            .maxRetries(0)
+            .firstBackoff(Duration.ofMillis(1000))
+            .jitterFactor(0.5)
+            .build());
+
+        SoftAssertions.assertSoftly(softly -> {
+            softly.assertThat(generator.generateDelay(1)).isEqualTo(Duration.ZERO);
+            softly.assertThat(generator.generateDelay(2)).isEqualTo(Duration.ZERO);
+            softly.assertThat(generator.generateDelay(3)).isEqualTo(Duration.ZERO);
+        });
+    }
+
+    @Test
+    void generateDelayShouldReturnZeroWhenZeroFirstBackOff() {
+        WaitDelayGenerator generator = WaitDelayGenerator.of(RetryBackoffConfiguration.builder()
+            .maxRetries(3)
+            .firstBackoff(Duration.ZERO)
+            .jitterFactor(0.5)
+            .build());
+
+        SoftAssertions.assertSoftly(softly -> {
+            softly.assertThat(generator.generateDelay(1)).isEqualTo(Duration.ZERO);
+            softly.assertThat(generator.generateDelay(2)).isEqualTo(Duration.ZERO);
+            softly.assertThat(generator.generateDelay(3)).isEqualTo(Duration.ZERO);
+        });
+    }
+
+    @Test
+    void generateDelayShouldReturnFloorOfExponentialGrowthStepsWhenZeroJitterFactor() {
+        WaitDelayGenerator generator = WaitDelayGenerator.of(RetryBackoffConfiguration.builder()
+            .maxRetries(3)
+            .firstBackoff(Duration.ofMillis(100))
+            .jitterFactor(0.0)
+            .build());
+
+        SoftAssertions.assertSoftly(softly -> {
+            softly.assertThat(generator.generateDelay(1)).isEqualTo(Duration.ofMillis(100));
+            softly.assertThat(generator.generateDelay(2)).isEqualTo(Duration.ofMillis(200));
+            softly.assertThat(generator.generateDelay(3)).isEqualTo(Duration.ofMillis(400));
+        });
+    }
+}
\ No newline at end of file
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/LocalListenerRegistryTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/LocalListenerRegistryTest.java
index 10ee4d8..aa54521 100644
--- a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/LocalListenerRegistryTest.java
+++ b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/LocalListenerRegistryTest.java
@@ -19,13 +19,14 @@
 
 package org.apache.james.mailbox.events;
 
-import static org.apache.james.mailbox.events.MailboxListener.wrapReactive;
+import static org.apache.james.events.EventListener.wrapReactive;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.time.Duration;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import org.apache.james.events.EventListener;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.util.concurrency.ConcurrentTestRunner;
 import org.junit.jupiter.api.BeforeEach;
@@ -53,7 +54,7 @@ class LocalListenerRegistryTest {
 
     @Test
     void getLocalMailboxListenersShouldReturnPreviouslyAddedListener() {
-        MailboxListener listener = event -> { };
+        EventListener listener = event -> { };
         testee.addListener(KEY_1, listener);
 
         assertThat(testee.getLocalMailboxListeners(KEY_1).collectList().block())
@@ -62,8 +63,8 @@ class LocalListenerRegistryTest {
 
     @Test
     void getLocalMailboxListenersShouldReturnPreviouslyAddedListeners() {
-        MailboxListener listener1 = event -> { };
-        MailboxListener listener2 = event -> { };
+        EventListener listener1 = event -> { };
+        EventListener listener2 = event -> { };
         testee.addListener(KEY_1, listener1);
         testee.addListener(KEY_1, listener2);
 
@@ -73,8 +74,8 @@ class LocalListenerRegistryTest {
 
     @Test
     void getLocalMailboxListenersShouldNotReturnRemovedListeners() {
-        MailboxListener listener1 = event -> { };
-        MailboxListener listener2 = event -> { };
+        EventListener listener1 = event -> { };
+        EventListener listener2 = event -> { };
         testee.addListener(KEY_1, listener1);
         LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener2);
 
@@ -86,15 +87,15 @@ class LocalListenerRegistryTest {
 
     @Test
     void addListenerShouldReturnFirstListenerWhenNoPreviouslyRegisteredListeners() {
-        MailboxListener listener = event -> { };
+        EventListener listener = event -> { };
 
         assertThat(testee.addListener(KEY_1, listener).isFirstListener()).isTrue();
     }
 
     @Test
     void addListenerShouldNotReturnFirstListenerWhenPreviouslyRegisteredListeners() {
-        MailboxListener listener = event -> { };
-        MailboxListener listener2 = event -> { };
+        EventListener listener = event -> { };
+        EventListener listener2 = event -> { };
 
         testee.addListener(KEY_1, listener);
 
@@ -103,8 +104,8 @@ class LocalListenerRegistryTest {
 
     @Test
     void removeListenerShouldNotReturnLastListenerRemovedWhenSeveralListener() {
-        MailboxListener listener = event -> { };
-        MailboxListener listener2 = event -> { };
+        EventListener listener = event -> { };
+        EventListener listener2 = event -> { };
 
         LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener);
         testee.addListener(KEY_1, listener2);
@@ -114,7 +115,7 @@ class LocalListenerRegistryTest {
 
     @Test
     void removeListenerShouldReturnLastListenerRemovedWhenOneListener() {
-        MailboxListener listener = event -> { };
+        EventListener listener = event -> { };
 
 
         LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener);
@@ -128,7 +129,7 @@ class LocalListenerRegistryTest {
 
         @Test
         void getLocalMailboxListenersShouldReturnPreviousAddedListener() throws Exception {
-            MailboxListener listener = event -> { };
+            EventListener listener = event -> { };
 
             ConcurrentTestRunner.builder()
                 .operation((threadNumber, operationNumber) -> testee.addListener(KEY_1, listener))
@@ -142,9 +143,9 @@ class LocalListenerRegistryTest {
 
         @Test
         void getLocalMailboxListenersShouldReturnAllPreviousAddedListeners() throws Exception {
-            MailboxListener listener1 = event -> { };
-            MailboxListener listener2 = event -> { };
-            MailboxListener listener3 = event -> { };
+            EventListener listener1 = event -> { };
+            EventListener listener2 = event -> { };
+            EventListener listener3 = event -> { };
 
             ConcurrentTestRunner.builder()
                 .randomlyDistributedOperations(
@@ -161,7 +162,7 @@ class LocalListenerRegistryTest {
 
         @Test
         void getLocalMailboxListenersShouldReturnEmptyWhenRemoveAddedListener() throws Exception {
-            MailboxListener listener1 = event -> { };
+            EventListener listener1 = event -> { };
 
             LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener1);
 
@@ -177,9 +178,9 @@ class LocalListenerRegistryTest {
 
         @Test
         void addListenerOnlyReturnIsFirstListenerForEmptyRegistry() throws Exception {
-            MailboxListener listener1 = event -> { };
-            MailboxListener listener2 = event -> { };
-            MailboxListener listener3 = event -> { };
+            EventListener listener1 = event -> { };
+            EventListener listener2 = event -> { };
+            EventListener listener3 = event -> { };
 
             AtomicInteger firstListenerCount = new AtomicInteger(0);
 
@@ -211,7 +212,7 @@ class LocalListenerRegistryTest {
 
         @Test
         void removeListenerOnlyReturnLastListenerRemovedForEmptyRegistry() throws Exception {
-            MailboxListener listener1 = event -> { };
+            EventListener listener1 = event -> { };
             AtomicInteger lastListenerRemoved = new AtomicInteger(0);
 
             LocalListenerRegistry.LocalRegistration registration = testee.addListener(KEY_1, listener1);
@@ -230,11 +231,11 @@ class LocalListenerRegistryTest {
 
         @Test
         void iterationShouldPerformOnASnapshotOfListenersSet() {
-            MailboxListener listener1 = event -> { };
-            MailboxListener listener2 = event -> { };
-            MailboxListener listener3 = event -> { };
-            MailboxListener listener4 = event -> { };
-            MailboxListener listener5 = event -> { };
+            EventListener listener1 = event -> { };
+            EventListener listener2 = event -> { };
+            EventListener listener3 = event -> { };
+            EventListener listener4 = event -> { };
+            EventListener listener5 = event -> { };
 
             testee.addListener(KEY_1, listener1);
             testee.addListener(KEY_1, listener2);
@@ -242,7 +243,7 @@ class LocalListenerRegistryTest {
             testee.addListener(KEY_1, listener4);
             LocalListenerRegistry.LocalRegistration registration5 = testee.addListener(KEY_1, listener5);
 
-            Mono<List<MailboxListener.ReactiveMailboxListener>> listeners = testee.getLocalMailboxListeners(KEY_1)
+            Mono<List<EventListener.ReactiveEventListener>> listeners = testee.getLocalMailboxListeners(KEY_1)
                 .publishOn(Schedulers.elastic())
                 .delayElements(Duration.ofMillis(100))
                 .collectList();
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/NetworkErrorTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/NetworkErrorTest.java
index ab7fa36..fd551ec 100644
--- a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/NetworkErrorTest.java
+++ b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/NetworkErrorTest.java
@@ -30,6 +30,7 @@ import static org.mockito.Mockito.verify;
 import org.apache.james.backends.rabbitmq.RabbitMQExtension;
 import org.apache.james.backends.rabbitmq.RabbitMQFixture;
 import org.apache.james.event.json.EventSerializer;
+import org.apache.james.events.EventListener;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
@@ -69,7 +70,7 @@ class NetworkErrorTest {
 
     @Test
     void dispatchShouldWorkAfterNetworkIssuesForOldRegistration() {
-        MailboxListener listener = newListener();
+        EventListener listener = newListener();
         eventBus.register(listener, GROUP_A);
 
         rabbitMQExtension.getRabbitMQ().pause();
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RabbitMQEventBusTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RabbitMQEventBusTest.java
index ff88499..a167ca9 100644
--- a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RabbitMQEventBusTest.java
+++ b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RabbitMQEventBusTest.java
@@ -64,8 +64,14 @@ import org.apache.james.backends.rabbitmq.RabbitMQFixture;
 import org.apache.james.backends.rabbitmq.RabbitMQManagementAPI;
 import org.apache.james.backends.rabbitmq.ReceiverProvider;
 import org.apache.james.event.json.EventSerializer;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventBus;
+import org.apache.james.events.EventDeadLetters;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
+import org.apache.james.events.GroupRegistrationNotFound;
+import org.apache.james.mailbox.events.EventBusTestFixture.EventListenerCountingSuccessfulExecution;
 import org.apache.james.mailbox.events.EventBusTestFixture.GroupA;
-import org.apache.james.mailbox.events.EventBusTestFixture.MailboxListenerCountingSuccessfulExecution;
 import org.apache.james.mailbox.events.EventDispatcher.DispatchingFailureGroup;
 import org.apache.james.mailbox.events.RoutingKeyConverter.RoutingKey;
 import org.apache.james.mailbox.model.TestId;
@@ -286,7 +292,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
 
     @Test
     void registerGroupShouldCreateRetryExchange() throws Exception {
-        MailboxListener listener = newListener();
+        EventListener listener = newListener();
         EventBusTestFixture.GroupA registeredGroup = new EventBusTestFixture.GroupA();
         eventBus.register(listener, registeredGroup);
 
@@ -306,7 +312,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
 
         @Test
         void rabbitMQEventBusShouldHandleBulksGracefully() throws Exception {
-            EventBusTestFixture.MailboxListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
+            EventListenerCountingSuccessfulExecution countingListener1 = newCountingListener();
             eventBus().register(countingListener1, new EventBusTestFixture.GroupA());
             int totalGlobalRegistrations = 1; // GroupA
 
@@ -347,9 +353,9 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
 
         @Test
         void inProcessingEventShouldBeReDispatchedToAnotherEventBusWhenOneIsDown() {
-            MailboxListenerCountingSuccessfulExecution eventBusListener = spy(new EventBusTestFixture.MailboxListenerCountingSuccessfulExecution());
-            MailboxListenerCountingSuccessfulExecution eventBus2Listener = spy(new EventBusTestFixture.MailboxListenerCountingSuccessfulExecution());
-            MailboxListenerCountingSuccessfulExecution eventBus3Listener = spy(new EventBusTestFixture.MailboxListenerCountingSuccessfulExecution());
+            EventListenerCountingSuccessfulExecution eventBusListener = spy(new EventListenerCountingSuccessfulExecution());
+            EventListenerCountingSuccessfulExecution eventBus2Listener = spy(new EventListenerCountingSuccessfulExecution());
+            EventListenerCountingSuccessfulExecution eventBus3Listener = spy(new EventListenerCountingSuccessfulExecution());
             Answer<?> callEventAndSleepForever = invocation -> {
                 invocation.callRealMethod();
                 TimeUnit.SECONDS.sleep(Long.MAX_VALUE);
@@ -462,7 +468,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
                 @Test
                 void dispatchShouldWorkAfterNetworkIssuesForOldRegistrationAndKey() {
                     rabbitMQEventBusWithNetWorkIssue.start();
-                    MailboxListener listener = newListener();
+                    EventListener listener = newListener();
                     Mono.from(rabbitMQEventBusWithNetWorkIssue.register(listener, KEY_1)).block();
 
                     rabbitMQNetWorkIssueExtension.getRabbitMQ().pause();
@@ -492,7 +498,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void dispatchShouldWorkAfterRestartForOldRegistration() throws Exception {
                 eventBus.start();
-                MailboxListener listener = newListener();
+                EventListener listener = newListener();
                 eventBus.register(listener, GROUP_A);
 
                 rabbitMQExtension.getRabbitMQ().restart();
@@ -504,7 +510,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void dispatchShouldWorkAfterRestartForNewRegistration() throws Exception {
                 eventBus.start();
-                MailboxListener listener = newListener();
+                EventListener listener = newListener();
 
                 rabbitMQExtension.getRabbitMQ().restart();
 
@@ -519,7 +525,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void redeliverShouldWorkAfterRestartForOldRegistration() throws Exception {
                 eventBus.start();
-                MailboxListener listener = newListener();
+                EventListener listener = newListener();
                 eventBus.register(listener, GROUP_A);
 
                 rabbitMQExtension.getRabbitMQ().restart();
@@ -531,7 +537,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void redeliverShouldWorkAfterRestartForNewRegistration() throws Exception {
                 eventBus.start();
-                MailboxListener listener = newListener();
+                EventListener listener = newListener();
 
                 rabbitMQExtension.getRabbitMQ().restart();
 
@@ -544,7 +550,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void dispatchShouldWorkAfterRestartForOldKeyRegistration() throws Exception {
                 eventBus.start();
-                MailboxListener listener = newListener();
+                EventListener listener = newListener();
                 Mono.from(eventBus.register(listener, KEY_1)).block();
 
                 rabbitMQExtension.getRabbitMQ().restart();
@@ -556,7 +562,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void dispatchedMessagesShouldSurviveARabbitMQRestart() throws Exception {
                 eventBusWithKeyHandlerNotStarted.startWithoutStartingKeyRegistrationHandler();
-                MailboxListener listener = newAsyncListener();
+                EventListener listener = newAsyncListener();
                 Mono.from(eventBusWithKeyHandlerNotStarted.register(listener, KEY_1)).block();
                 Mono<Void> dispatch = eventBusWithKeyHandlerNotStarted.dispatch(EVENT, KEY_1);
                 dispatch.block();
@@ -572,7 +578,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void dispatchShouldWorkAfterRestartForNewKeyRegistration() throws Exception {
                 eventBus.start();
-                MailboxListener listener = newListener();
+                EventListener listener = newListener();
 
                 rabbitMQExtension.getRabbitMQ().restart();
 
@@ -585,7 +591,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void dispatchShouldWorkAfterNetworkIssuesForNewRegistration() {
                 eventBus.start();
-                MailboxListener listener = newListener();
+                EventListener listener = newListener();
 
                 rabbitMQExtension.getRabbitMQ().pause();
 
@@ -603,7 +609,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void redeliverShouldWorkAfterNetworkIssuesForNewRegistration() {
                 eventBus.start();
-                MailboxListener listener = newListener();
+                EventListener listener = newListener();
 
                 rabbitMQExtension.getRabbitMQ().pause();
 
@@ -620,8 +626,8 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void dispatchShouldWorkAfterNetworkIssuesForOldKeyRegistration() {
                 eventBus.start();
-                MailboxListener listener = newListener();
-                when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
+                EventListener listener = newListener();
+                when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
                 Mono.from(eventBus.register(listener, KEY_1)).block();
 
                 rabbitMQExtension.getRabbitMQ().pause();
@@ -639,8 +645,8 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void dispatchShouldWorkAfterNetworkIssuesForNewKeyRegistration() {
                 eventBus.start();
-                MailboxListener listener = newListener();
-                when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
+                EventListener listener = newListener();
+                when(listener.getExecutionMode()).thenReturn(EventListener.ExecutionMode.ASYNCHRONOUS);
 
                 rabbitMQExtension.getRabbitMQ().pause();
 
@@ -667,7 +673,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             @Test
             void stopShouldNotDeleteGroupRegistrationWorkQueue() {
                 eventBus.start();
-                eventBus.register(mock(MailboxListener.class), GROUP_A);
+                eventBus.register(mock(EventListener.class), GROUP_A);
                 eventBus.stop();
 
                 assertThat(rabbitManagementAPI.listQueues())
@@ -692,7 +698,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
             void dispatchShouldStopDeliveringEventsShortlyAfterStopIsCalled() throws Exception {
                 eventBus.start();
 
-                MailboxListenerCountingSuccessfulExecution listener = new MailboxListenerCountingSuccessfulExecution();
+                EventListenerCountingSuccessfulExecution listener = new EventListenerCountingSuccessfulExecution();
                 eventBus.register(listener, GROUP_A);
 
                 try (Closeable closeable = ConcurrentTestRunner.builder()
@@ -759,7 +765,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
 
             @Test
             void multipleEventBusStopShouldNotDeleteGroupRegistrationWorkQueue() {
-                eventBus.register(mock(MailboxListener.class), GROUP_A);
+                eventBus.register(mock(EventListener.class), GROUP_A);
 
                 eventBus.stop();
                 eventBus2.stop();
@@ -788,7 +794,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
                 eventBus.start();
                 eventBus2.start();
 
-                MailboxListenerCountingSuccessfulExecution listener = new MailboxListenerCountingSuccessfulExecution();
+                EventListenerCountingSuccessfulExecution listener = new EventListenerCountingSuccessfulExecution();
                 eventBus.register(listener, GROUP_A);
                 eventBus2.register(listener, GROUP_A);
 
@@ -967,7 +973,7 @@ class RabbitMQEventBusTest implements GroupContract.SingleEventBusGroupContract,
         }
     }
 
-    private void assertThatListenerReceiveOneEvent(MailboxListener listener) {
+    private void assertThatListenerReceiveOneEvent(EventListener listener) {
         RabbitMQFixture.awaitAtMostThirtySeconds
             .untilAsserted(() -> verify(listener).event(EVENT));
     }
diff --git a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RoutingKeyConverterTest.java b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RoutingKeyConverterTest.java
index 4b158dc..9fb93dc 100644
--- a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RoutingKeyConverterTest.java
+++ b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/RoutingKeyConverterTest.java
@@ -24,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.util.Objects;
 
+import org.apache.james.events.RegistrationKey;
 import org.apache.james.mailbox.model.TestId;
 import org.junit.jupiter.api.Test;
 
diff --git a/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala b/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala
index 92f0160..fa7c110 100644
--- a/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala
+++ b/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala
@@ -28,10 +28,11 @@ import org.apache.james.core.Username
 import org.apache.james.core.quota.{QuotaCountLimit, QuotaCountUsage, QuotaSizeLimit, QuotaSizeUsage}
 import org.apache.james.event.json.DTOs.SystemFlag.SystemFlag
 import org.apache.james.event.json.DTOs._
+import org.apache.james.events
+import org.apache.james.events.Event.EventId
 import org.apache.james.mailbox.MailboxSession.SessionId
-import org.apache.james.mailbox.events.Event.EventId
-import org.apache.james.mailbox.events.MailboxListener.{Added => JavaAdded, Expunged => JavaExpunged, FlagsUpdated => JavaFlagsUpdated, MailboxACLUpdated => JavaMailboxACLUpdated, MailboxAdded => JavaMailboxAdded, MailboxDeletion => JavaMailboxDeletion, MailboxRenamed => JavaMailboxRenamed, QuotaUsageUpdatedEvent => JavaQuotaUsageUpdatedEvent}
-import org.apache.james.mailbox.events.{Event => JavaEvent, MessageMoveEvent => JavaMessageMoveEvent}
+import org.apache.james.mailbox.events.MailboxEvents.{Added => JavaAdded, Expunged => JavaExpunged, FlagsUpdated => JavaFlagsUpdated, MailboxACLUpdated => JavaMailboxACLUpdated, MailboxAdded => JavaMailboxAdded, MailboxDeletion => JavaMailboxDeletion, MailboxRenamed => JavaMailboxRenamed, QuotaUsageUpdatedEvent => JavaQuotaUsageUpdatedEvent}
+import org.apache.james.mailbox.events.{MessageMoveEvent => JavaMessageMoveEvent}
 import org.apache.james.mailbox.model.{MailboxId, MessageId, MessageMoves, QuotaRoot, MailboxACL => JavaMailboxACL, MessageMetaData => JavaMessageMetaData, Quota => JavaQuota}
 import org.apache.james.mailbox.quota.QuotaRootDeserializer
 import org.apache.james.mailbox.{MessageUid, ModSeq}
@@ -40,36 +41,36 @@ import play.api.libs.json._
 import scala.jdk.CollectionConverters._
 
 private sealed trait Event {
-  def toJava: JavaEvent
+  def toJava: events.Event
 }
 
 private object DTO {
   case class MailboxACLUpdated(eventId: EventId, sessionId: SessionId, user: Username, mailboxPath: MailboxPath, aclDiff: ACLDiff, mailboxId: MailboxId) extends Event {
-    override def toJava: JavaEvent = new JavaMailboxACLUpdated(sessionId, user, mailboxPath.toJava, aclDiff.toJava, mailboxId, eventId)
+    override def toJava: events.Event = new JavaMailboxACLUpdated(sessionId, user, mailboxPath.toJava, aclDiff.toJava, mailboxId, eventId)
   }
 
   case class MailboxAdded(eventId: EventId, mailboxPath: MailboxPath, mailboxId: MailboxId, user: Username, sessionId: SessionId) extends Event {
-    override def toJava: JavaEvent = new JavaMailboxAdded(sessionId, user, mailboxPath.toJava, mailboxId, eventId)
+    override def toJava: events.Event = new JavaMailboxAdded(sessionId, user, mailboxPath.toJava, mailboxId, eventId)
   }
 
   case class MailboxDeletion(eventId: EventId, sessionId: SessionId, user: Username, path: MailboxPath, mailboxACL: Option[MailboxACL], quotaRoot: QuotaRoot,
                              deletedMessageCount: QuotaCountUsage, totalDeletedSize: QuotaSizeUsage, mailboxId: MailboxId) extends Event {
-    override def toJava: JavaEvent = new JavaMailboxDeletion(sessionId, user, path.toJava, mailboxACL.map(mailboxACL => mailboxACL.toJava).getOrElse(new JavaMailboxACL()), quotaRoot, deletedMessageCount,
+    override def toJava: events.Event = new JavaMailboxDeletion(sessionId, user, path.toJava, mailboxACL.map(mailboxACL => mailboxACL.toJava).getOrElse(new JavaMailboxACL()), quotaRoot, deletedMessageCount,
       totalDeletedSize, mailboxId, eventId)
   }
 
   case class MailboxRenamed(eventId: EventId, sessionId: SessionId, user: Username, path: MailboxPath, mailboxId: MailboxId, newPath: MailboxPath) extends Event {
-    override def toJava: JavaEvent = new JavaMailboxRenamed(sessionId, user, path.toJava, mailboxId, newPath.toJava, eventId)
+    override def toJava: events.Event = new JavaMailboxRenamed(sessionId, user, path.toJava, mailboxId, newPath.toJava, eventId)
   }
 
   case class QuotaUsageUpdatedEvent(eventId: EventId, user: Username, quotaRoot: QuotaRoot, countQuota: Quota[QuotaCountLimit, QuotaCountUsage],
                                     sizeQuota: Quota[QuotaSizeLimit, QuotaSizeUsage], time: Instant) extends Event {
-    override def toJava: JavaEvent = new JavaQuotaUsageUpdatedEvent(eventId, user, quotaRoot, countQuota.toJava, sizeQuota.toJava, time)
+    override def toJava: events.Event = new JavaQuotaUsageUpdatedEvent(eventId, user, quotaRoot, countQuota.toJava, sizeQuota.toJava, time)
   }
 
   case class Added(eventId: EventId, sessionId: SessionId, user: Username, path: MailboxPath, mailboxId: MailboxId,
                    added: Map[MessageUid, DTOs.MessageMetaData]) extends Event {
-    override def toJava: JavaEvent = new JavaAdded(
+    override def toJava: events.Event = new JavaAdded(
       sessionId,
       user,
       path.toJava,
@@ -80,7 +81,7 @@ private object DTO {
 
   case class Expunged(eventId: EventId, sessionId: SessionId, user: Username, path: MailboxPath, mailboxId: MailboxId,
                       expunged: Map[MessageUid, DTOs.MessageMetaData]) extends Event {
-    override def toJava: JavaEvent = new JavaExpunged(
+    override def toJava: events.Event = new JavaExpunged(
       sessionId,
       user,
       path.toJava,
@@ -91,7 +92,7 @@ private object DTO {
 
   case class MessageMoveEvent(eventId: EventId, user: Username, previousMailboxIds: Iterable[MailboxId], targetMailboxIds: Iterable[MailboxId],
                               messageIds: Iterable[MessageId]) extends Event {
-    override def toJava: JavaEvent = JavaMessageMoveEvent.builder()
+    override def toJava: events.Event = JavaMessageMoveEvent.builder()
       .eventId(eventId)
       .user(user)
       .messageId(messageIds.asJava)
@@ -104,7 +105,7 @@ private object DTO {
 
   case class FlagsUpdated(eventId: EventId, sessionId: SessionId, user: Username, path: MailboxPath, mailboxId: MailboxId,
                           updatedFlags: List[DTOs.UpdatedFlags]) extends Event {
-    override def toJava: JavaEvent = new JavaFlagsUpdated(
+    override def toJava: events.Event = new JavaFlagsUpdated(
       sessionId,
       user,
       path.toJava,
@@ -188,7 +189,7 @@ private object ScalaConverter {
     mailboxId = event.getMailboxId,
     updatedFlags = event.getUpdatedFlags.asScala.toList.map(DTOs.UpdatedFlags.toUpdatedFlags))
 
-  def toScala(javaEvent: JavaEvent): Event = javaEvent match {
+  def toScala(javaEvent: events.Event): Event = javaEvent match {
     case e: JavaAdded => toScala(e)
     case e: JavaExpunged => toScala(e)
     case e: JavaFlagsUpdated => toScala(e)
@@ -347,15 +348,15 @@ class JsonSerialize(mailboxIdFactory: MailboxId.Factory, messageIdFactory: Messa
   }
 
   private val eventSerializerPrivateWrapper = new EventSerializerPrivateWrapper()
-  def toJson(event: JavaEvent): String = eventSerializerPrivateWrapper.toJson(ScalaConverter.toScala(event))
-  def fromJson(json: String): JsResult[JavaEvent] = eventSerializerPrivateWrapper.fromJson(json)
+  def toJson(event: events.Event): String = eventSerializerPrivateWrapper.toJson(ScalaConverter.toScala(event))
+  def fromJson(json: String): JsResult[events.Event] = eventSerializerPrivateWrapper.fromJson(json)
     .map(event => event.toJava)
 }
 
 class EventSerializer @Inject() (mailboxIdFactory: MailboxId.Factory, messageIdFactory: MessageId.Factory, quotaRootDeserializer: QuotaRootDeserializer) {
   private val jsonSerialize = new JsonSerialize(mailboxIdFactory, messageIdFactory, quotaRootDeserializer)
 
-  def toJson(event: JavaEvent): String = jsonSerialize.toJson(event)
-  def fromJson(json: String): JsResult[JavaEvent] = jsonSerialize.fromJson(json)
+  def toJson(event: events.Event): String = jsonSerialize.toJson(event)
+  def fromJson(json: String): JsResult[events.Event] = jsonSerialize.fromJson(json)
 }
 
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
index 483123f..7477cad 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
@@ -37,7 +37,7 @@ import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
@@ -68,8 +68,7 @@ class AddedSerializationTest {
     private static final SortedMap<MessageUid, MessageMetaData> ADDED = ImmutableSortedMap.of(
         MESSAGE_UID, new MessageMetaData(MESSAGE_UID, MOD_SEQ, FLAGS, SIZE, Date.from(INSTANT), MESSAGE_ID));
 
-    private static final MailboxListener.Added DEFAULT_ADDED_EVENT = new MailboxListener.Added(SESSION_ID, USERNAME,
-        MAILBOX_PATH, MAILBOX_ID, ADDED, EVENT_ID);
+    private static final Added DEFAULT_ADDED_EVENT = new Added(SESSION_ID, USERNAME, MAILBOX_PATH, MAILBOX_ID, ADDED, EVENT_ID);
     private static final String DEFAULT_ADDED_EVENT_JSON = 
         "{" +
         "  \"Added\": {" +
@@ -112,7 +111,7 @@ class AddedSerializationTest {
     @Nested
     class WithEmptyAddedMap {
 
-        private final MailboxListener.Added emptyAddedEvent = new MailboxListener.Added(SESSION_ID, USERNAME, MAILBOX_PATH,
+        private final Added emptyAddedEvent = new Added(SESSION_ID, USERNAME, MAILBOX_PATH,
             MAILBOX_ID, ImmutableSortedMap.of(), EVENT_ID);
         private final String emptyAddedEventJson =
             "{" +
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java
index 06066c3..866f241 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java
@@ -37,7 +37,7 @@ import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
@@ -68,7 +68,7 @@ class ExpungedSerializationTest {
     private static final Map<MessageUid, MessageMetaData> EXPUNGED = ImmutableMap.of(
         MESSAGE_UID, new MessageMetaData(MESSAGE_UID, MOD_SEQ, FLAGS, SIZE, Date.from(INSTANT), MESSAGE_ID));
 
-    private static final MailboxListener.Expunged DEFAULT_EXPUNGED_EVENT = new MailboxListener.Expunged(SESSION_ID, USERNAME,
+    private static final Expunged DEFAULT_EXPUNGED_EVENT = new Expunged(SESSION_ID, USERNAME,
         MAILBOX_PATH, MAILBOX_ID, EXPUNGED, EVENT_ID);
     private static final String DEFAULT_EXPUNGED_EVENT_JSON =
         "{" +
@@ -112,7 +112,7 @@ class ExpungedSerializationTest {
     @Nested
     class WithEmptyExpungedMap {
 
-        private final MailboxListener.Expunged emptyExpungedEvent = new MailboxListener.Expunged(SESSION_ID, USERNAME,
+        private final Expunged emptyExpungedEvent = new Expunged(SESSION_ID, USERNAME,
             MAILBOX_PATH, MAILBOX_ID, ImmutableMap.of(), EVENT_ID);
         private final String emptyExpungedEventJson =
             "{" +
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java
index 6cb82f3..d90e7df 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java
@@ -35,7 +35,7 @@ import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
@@ -94,7 +94,7 @@ class FlagsUpdatedSerializationTest {
 
     private static List<UpdatedFlags> UPDATED_FLAGS_LIST = ImmutableList.of(UPDATED_FLAG_1, UPDATED_FLAG_2);
 
-    private static final MailboxListener.FlagsUpdated DEFAULT_EVENT = new MailboxListener.FlagsUpdated(SESSION_ID, USERNAME,
+    private static final FlagsUpdated DEFAULT_EVENT = new FlagsUpdated(SESSION_ID, USERNAME,
         MAILBOX_PATH, MAILBOX_ID, UPDATED_FLAGS_LIST, EVENT_ID);
     private static final String DEFAULT_EVENT_JSON =
         "{" +
@@ -141,7 +141,7 @@ class FlagsUpdatedSerializationTest {
     @Nested
     class WithEmptyUpdatedFlags {
         private final List<UpdatedFlags> emptyUpdatedFlags = ImmutableList.of();
-        private final MailboxListener.FlagsUpdated emptyUpdatedFlagsEvent = new MailboxListener.FlagsUpdated(SESSION_ID, USERNAME, MAILBOX_PATH,
+        private final FlagsUpdated emptyUpdatedFlagsEvent = new FlagsUpdated(SESSION_ID, USERNAME, MAILBOX_PATH,
             MAILBOX_ID, emptyUpdatedFlags, EVENT_ID);
 
         private static final String EVENT_JSON_WITH_EMPTY_UPDATED_FLAGS =
@@ -196,7 +196,7 @@ class FlagsUpdatedSerializationTest {
 
         private final List<UpdatedFlags> updatedFlagsListWithMessageIds = ImmutableList.of(updatedFlagsWithMessageId1, updatedFlagsWithMessageId2);
 
-        private final MailboxListener.FlagsUpdated eventWithMessageIds = new MailboxListener.FlagsUpdated(SESSION_ID, USERNAME,
+        private final FlagsUpdated eventWithMessageIds = new FlagsUpdated(SESSION_ID, USERNAME,
             MAILBOX_PATH, MAILBOX_ID, updatedFlagsListWithMessageIds, EVENT_ID);
 
         private static final String EVENT_WITH_MESSAGE_IDS_JSON =
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java
index d80c0ec..e957e53 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java
@@ -30,7 +30,7 @@ import java.util.NoSuchElementException;
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.acl.ACLDiff;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxACLUpdated;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
@@ -48,7 +48,7 @@ class MailboxACLUpdatedEventSerializationTest {
         new MailboxACL.Entry(MailboxACL.EntryKey.createUserEntryKey(Username.of("alice"), true),
             new MailboxACL.Rfc4314Rights(MailboxACL.Right.Insert)));
 
-    private static final MailboxListener.MailboxACLUpdated MAILBOX_ACL_UPDATED = new MailboxListener.MailboxACLUpdated(
+    private static final MailboxACLUpdated MAILBOX_ACL_UPDATED = new MailboxACLUpdated(
                 MailboxSession.SessionId.of(6),
         USERNAME,
                 new MailboxPath(MailboxConstants.USER_NAMESPACE, Username.of("bob"), "mailboxName"),
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxAddedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxAddedSerializationTest.java
index 082237d..1063d2f 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxAddedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxAddedSerializationTest.java
@@ -29,7 +29,7 @@ import java.util.NoSuchElementException;
 
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.TestId;
@@ -38,7 +38,7 @@ import org.junit.jupiter.api.Test;
 
 class MailboxAddedSerializationTest {
     private static final Username USERNAME = Username.of("user");
-    private static final MailboxListener.MailboxAdded EVENT_1 = new MailboxListener.MailboxAdded(
+    private static final MailboxAdded EVENT_1 = new MailboxAdded(
         MailboxSession.SessionId.of(42),
         USERNAME,
         new MailboxPath(MailboxConstants.USER_NAMESPACE, Username.of("bob"), "mailboxName"),
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxDeletionSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxDeletionSerializationTest.java
index d4ca296..99f7072 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxDeletionSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxDeletionSerializationTest.java
@@ -35,7 +35,7 @@ import org.apache.james.core.Username;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeUsage;
 import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
@@ -53,7 +53,7 @@ class MailboxDeletionSerializationTest {
     private static final QuotaRoot QUOTA_ROOT = QuotaRoot.quotaRoot("#private&user@domain", Optional.of(Domain.of("domain")));
     private static final QuotaCountUsage DELETED_MESSAGE_COUNT = QuotaCountUsage.count(60);
     private static final QuotaSizeUsage TOTAL_DELETED_SIZE = QuotaSizeUsage.size(100);
-    private static final MailboxListener.MailboxDeletion DEFAULT_MAILBOX_DELETION_EVENT = new MailboxListener.MailboxDeletion(
+    private static final MailboxDeletion DEFAULT_MAILBOX_DELETION_EVENT = new MailboxDeletion(
         SESSION_ID,
         USERNAME,
         MAILBOX_PATH,
@@ -64,7 +64,7 @@ class MailboxDeletionSerializationTest {
         MAILBOX_ID,
         EVENT_ID);
 
-    private static final MailboxListener.MailboxDeletion EMPTY_ACL_MAILBOX_DELETION_EVENT = new MailboxListener.MailboxDeletion(
+    private static final MailboxDeletion EMPTY_ACL_MAILBOX_DELETION_EVENT = new MailboxDeletion(
         SESSION_ID,
         USERNAME,
         MAILBOX_PATH,
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxRenamedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxRenamedSerializationTest.java
index 4de9225..18e55d4 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxRenamedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxRenamedSerializationTest.java
@@ -30,7 +30,7 @@ import java.util.NoSuchElementException;
 
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxRenamed;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.TestId;
@@ -46,7 +46,7 @@ class MailboxRenamedSerializationTest {
     private static final MailboxPath DEFAULT_NEW_MAILBOX_PATH = new MailboxPath(USER_NAMESPACE, DEFAULT_USERNAME, NEW_MAILBOX_NAME);
     private static final MailboxSession.SessionId DEFAULT_SESSION_ID = MailboxSession.SessionId.of(123456789);
     private static final MailboxId DEFAULT_MAILBOX_ID = TestId.of(123456);
-    private static final MailboxListener.MailboxRenamed DEFAULT_MAILBOX_RENAMED_EVENT = new MailboxListener.MailboxRenamed(
+    private static final MailboxRenamed DEFAULT_MAILBOX_RENAMED_EVENT = new MailboxRenamed(
         DEFAULT_SESSION_ID,
         DEFAULT_USERNAME,
         DEFAULT_OLD_MAILBOX_PATH,
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageMoveEventSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageMoveEventSerializationTest.java
index 68a32a2..b24bc93 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageMoveEventSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageMoveEventSerializationTest.java
@@ -28,7 +28,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import java.util.NoSuchElementException;
 
 import org.apache.james.core.Username;
-import org.apache.james.mailbox.events.Event;
+import org.apache.james.events.Event;
 import org.apache.james.mailbox.events.MessageMoveEvent;
 import org.apache.james.mailbox.model.MessageMoves;
 import org.apache.james.mailbox.model.TestId;
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/QuotaUsageUpdatedEventSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/QuotaUsageUpdatedEventSerializationTest.java
index 66e07e3..7991349 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/QuotaUsageUpdatedEventSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/QuotaUsageUpdatedEventSerializationTest.java
@@ -34,7 +34,7 @@ import org.apache.james.core.quota.QuotaCountLimit;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.mailbox.model.QuotaRoot;
 import org.junit.jupiter.api.Test;
@@ -50,7 +50,7 @@ class QuotaUsageUpdatedEventSerializationTest {
         .computedLimit(QuotaSizeLimit.size(10000))
         .build();
     private static final Instant INSTANT = Instant.parse("2018-11-13T12:00:55Z");
-    private final MailboxListener.QuotaUsageUpdatedEvent eventWithUserContainsUsername = new MailboxListener.QuotaUsageUpdatedEvent(
+    private final QuotaUsageUpdatedEvent eventWithUserContainsUsername = new QuotaUsageUpdatedEvent(
         EVENT_ID,
         Username.of("onlyusername"),
         QUOTA_ROOT,
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/SerializerFixture.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/SerializerFixture.java
index bd8ad0d..a9e6deb 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/SerializerFixture.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/SerializerFixture.java
@@ -19,7 +19,7 @@
 
 package org.apache.james.event.json;
 
-import org.apache.james.mailbox.events.Event;
+import org.apache.james.events.Event;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver;
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java
index 764868d..5259366 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java
@@ -23,9 +23,9 @@ import java.util.EnumSet;
 
 import javax.inject.Inject;
 
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.SessionProvider;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.jpa.JPAMailboxSessionMapperFactory;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MessageId;
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
index b11c70b..a43ae7c 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
@@ -21,9 +21,9 @@ package org.apache.james.mailbox.jpa.openjpa;
 
 import javax.mail.Flags;
 
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.quota.QuotaManager;
diff --git a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JPAMailboxManagerTest.java b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JPAMailboxManagerTest.java
index 530a596..bd632cc 100644
--- a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JPAMailboxManagerTest.java
+++ b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JPAMailboxManagerTest.java
@@ -21,9 +21,9 @@ package org.apache.james.mailbox.jpa;
 import java.util.Optional;
 
 import org.apache.james.backends.jpa.JpaTestCluster;
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxManagerTest;
 import org.apache.james.mailbox.SubscriptionManager;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.jpa.openjpa.OpenJPAMailboxManager;
 import org.apache.james.mailbox.store.StoreSubscriptionManager;
 import org.junit.jupiter.api.AfterEach;
diff --git a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JpaMailboxManagerStressTest.java b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JpaMailboxManagerStressTest.java
index 520c195..6917668 100644
--- a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JpaMailboxManagerStressTest.java
+++ b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JpaMailboxManagerStressTest.java
@@ -22,8 +22,8 @@ package org.apache.james.mailbox.jpa;
 import java.util.Optional;
 
 import org.apache.james.backends.jpa.JpaTestCluster;
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxManagerStressContract;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.jpa.openjpa.OpenJPAMailboxManager;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
diff --git a/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java b/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
index 6d76bea..a382198 100644
--- a/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
+++ b/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
@@ -131,14 +131,14 @@ import reactor.core.publisher.Mono;
  * Lucene based {@link ListeningMessageSearchIndex} which offers message searching via a Lucene index
  */
 public class LuceneMessageSearchIndex extends ListeningMessageSearchIndex {
-    public static class LuceneMessageSearchIndexGroup extends org.apache.james.mailbox.events.Group {
+    public static class LuceneMessageSearchIndexGroup extends org.apache.james.events.Group {
 
     }
 
     private static final Logger LOGGER = LoggerFactory.getLogger(LuceneMessageSearchIndex.class);
     private static final Date MAX_DATE;
     private static final Date MIN_DATE;
-    public static final org.apache.james.mailbox.events.Group GROUP = new LuceneMessageSearchIndexGroup();
+    public static final org.apache.james.events.Group GROUP = new LuceneMessageSearchIndexGroup();
     
     static {
         Calendar cal = Calendar.getInstance();
@@ -404,7 +404,7 @@ public class LuceneMessageSearchIndex extends ListeningMessageSearchIndex {
     }
 
     @Override
-    public org.apache.james.mailbox.events.Group getDefaultGroup() {
+    public org.apache.james.events.Group getDefaultGroup() {
         return GROUP;
     }
 
diff --git a/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndexTest.java b/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndexTest.java
index d274a37..dab83c0 100644
--- a/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndexTest.java
+++ b/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndexTest.java
@@ -19,29 +19,16 @@
 
 package org.apache.james.mailbox.lucene.search;
 
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.nio.charset.StandardCharsets;
-
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.MailboxSessionUtil;
-import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
 import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
-import org.apache.james.mailbox.model.ComposedMessageId;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.store.search.AbstractMessageSearchIndexTest;
-import org.apache.james.mime4j.dom.Message;
 import org.apache.lucene.store.RAMDirectory;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 
 import com.github.fge.lambdas.Throwing;
 
-import reactor.core.publisher.Flux;
-
 class LuceneMessageSearchIndexTest extends AbstractMessageSearchIndexTest {
 
     @Override
diff --git a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/DomainUserMaildirMailboxManagerStressTest.java b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/DomainUserMaildirMailboxManagerStressTest.java
index ff61e53..09adfb7 100644
--- a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/DomainUserMaildirMailboxManagerStressTest.java
+++ b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/DomainUserMaildirMailboxManagerStressTest.java
@@ -21,8 +21,8 @@ package org.apache.james.mailbox.maildir;
 
 import java.io.File;
 
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxManagerStressContract;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.store.StoreMailboxManager;
 import org.junit.jupiter.api.BeforeEach;
diff --git a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/DomainUserMaildirMailboxManagerTest.java b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/DomainUserMaildirMailboxManagerTest.java
index 601b019..55ae598 100644
--- a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/DomainUserMaildirMailboxManagerTest.java
+++ b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/DomainUserMaildirMailboxManagerTest.java
@@ -20,10 +20,10 @@ package org.apache.james.mailbox.maildir;
 
 import java.util.Optional;
 
+import org.apache.james.events.EventBus;
 import org.apache.james.junit.TemporaryFolderExtension;
 import org.apache.james.mailbox.MailboxManagerTest;
 import org.apache.james.mailbox.SubscriptionManager;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.store.StoreMailboxManager;
 import org.apache.james.mailbox.store.StoreSubscriptionManager;
 import org.junit.jupiter.api.Disabled;
diff --git a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/FullUserMaildirMailboxManagerStressTest.java b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/FullUserMaildirMailboxManagerStressTest.java
index 6bb20fc..33cd409 100644
--- a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/FullUserMaildirMailboxManagerStressTest.java
+++ b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/FullUserMaildirMailboxManagerStressTest.java
@@ -21,8 +21,8 @@ package org.apache.james.mailbox.maildir;
 
 import java.io.File;
 
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxManagerStressContract;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.store.StoreMailboxManager;
 import org.junit.jupiter.api.BeforeEach;
diff --git a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/FullUserMaildirMailboxManagerTest.java b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/FullUserMaildirMailboxManagerTest.java
index d9ff4c4..633cc6e 100644
--- a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/FullUserMaildirMailboxManagerTest.java
+++ b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/FullUserMaildirMailboxManagerTest.java
@@ -20,10 +20,10 @@ package org.apache.james.mailbox.maildir;
 
 import java.util.Optional;
 
+import org.apache.james.events.EventBus;
 import org.apache.james.junit.TemporaryFolderExtension;
 import org.apache.james.mailbox.MailboxManagerTest;
 import org.apache.james.mailbox.SubscriptionManager;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.store.StoreMailboxManager;
 import org.apache.james.mailbox.store.StoreSubscriptionManager;
 import org.junit.jupiter.api.Disabled;
diff --git a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/UserMaildirMailboxManagerStressTest.java b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/UserMaildirMailboxManagerStressTest.java
index 03acce9..3c2b2ce 100644
--- a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/UserMaildirMailboxManagerStressTest.java
+++ b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/UserMaildirMailboxManagerStressTest.java
@@ -21,8 +21,8 @@ package org.apache.james.mailbox.maildir;
 
 import java.io.File;
 
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxManagerStressContract;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.store.StoreMailboxManager;
 import org.junit.jupiter.api.BeforeEach;
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMailboxManager.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMailboxManager.java
index 6ec12db..a71a2b8 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMailboxManager.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMailboxManager.java
@@ -23,10 +23,10 @@ import java.util.EnumSet;
 
 import javax.inject.Inject;
 
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.SessionProvider;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.MailboxManagerConfiguration;
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
index 59567b9..7b56397 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
@@ -2,9 +2,9 @@ package org.apache.james.mailbox.inmemory;
 
 import javax.mail.Flags;
 
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.quota.QuotaManager;
diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/MemoryMailboxManagerStressTest.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/MemoryMailboxManagerStressTest.java
index ea5e1ea..c060065 100644
--- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/MemoryMailboxManagerStressTest.java
+++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/MemoryMailboxManagerStressTest.java
@@ -19,8 +19,8 @@
 
 package org.apache.james.mailbox.inmemory;
 
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxManagerStressContract;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.extension.PreDeletionHook;
 import org.junit.jupiter.api.BeforeEach;
 
diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/MemoryMailboxManagerTest.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/MemoryMailboxManagerTest.java
index c02c55f..4bde607 100644
--- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/MemoryMailboxManagerTest.java
+++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/MemoryMailboxManagerTest.java
@@ -19,9 +19,9 @@
 
 package org.apache.james.mailbox.inmemory;
 
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxManagerTest;
 import org.apache.james.mailbox.SubscriptionManager;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.store.StoreSubscriptionManager;
 
 class MemoryMailboxManagerTest extends MailboxManagerTest<InMemoryMailboxManager> {
diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryIntegrationResources.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryIntegrationResources.java
index a80ff7a..bc172a8 100644
--- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryIntegrationResources.java
+++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryIntegrationResources.java
@@ -23,6 +23,8 @@ import java.util.Collection;
 import java.util.Optional;
 import java.util.function.Function;
 
+import org.apache.james.events.EventBus;
+import org.apache.james.events.EventListener;
 import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.Authenticator;
 import org.apache.james.mailbox.Authorizator;
@@ -31,10 +33,8 @@ import org.apache.james.mailbox.SessionProvider;
 import org.apache.james.mailbox.acl.GroupMembershipResolver;
 import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
 import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.EventBusTestFixture;
 import org.apache.james.mailbox.events.InVMEventBus;
-import org.apache.james.mailbox.events.MailboxListener;
 import org.apache.james.mailbox.events.MemoryEventDeadLetters;
 import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.extension.PreDeletionHook;
@@ -208,7 +208,7 @@ public class InMemoryIntegrationResources implements IntegrationResources<StoreM
         private Optional<MessageParser> messageParser;
         private Optional<Function<MailboxManagerSearchIndexStage, MessageSearchIndex>> searchIndexFactory;
         private ImmutableSet.Builder<Function<MailboxManagerPreInstanciationStage, PreDeletionHook>> preDeletionHooksFactories;
-        private ImmutableList.Builder<MailboxListener.GroupMailboxListener> listenersToBeRegistered;
+        private ImmutableList.Builder<EventListener.GroupEventListener> listenersToBeRegistered;
 
         private Builder() {
             this.authenticator = Optional.empty();
diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryMessageIdManagerSideEffectTest.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryMessageIdManagerSideEffectTest.java
index fc8f774..5949260 100644
--- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryMessageIdManagerSideEffectTest.java
+++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryMessageIdManagerSideEffectTest.java
@@ -21,7 +21,7 @@ package org.apache.james.mailbox.inmemory.manager;
 
 import java.util.Set;
 
-import org.apache.james.mailbox.events.EventBus;
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.extension.PreDeletionHook;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
 import org.apache.james.mailbox.quota.QuotaManager;
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdCrossingListener.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdCrossingListener.java
index 7c9760c..da86cd6 100644
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdCrossingListener.java
+++ b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdCrossingListener.java
@@ -24,15 +24,16 @@ import javax.inject.Inject;
 import org.apache.commons.configuration2.HierarchicalConfiguration;
 import org.apache.commons.configuration2.tree.ImmutableNode;
 import org.apache.james.core.Username;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
 import org.apache.james.eventsourcing.Command;
 import org.apache.james.eventsourcing.CommandHandler;
 import org.apache.james.eventsourcing.EventSourcingSystem;
 import org.apache.james.eventsourcing.Subscriber;
 import org.apache.james.eventsourcing.eventstore.EventStore;
 import org.apache.james.filesystem.api.FileSystem;
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.Group;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.quota.mailing.QuotaMailingListenerConfiguration;
 import org.apache.james.mailbox.quota.mailing.commands.DetectThresholdCrossing;
 import org.apache.james.mailbox.quota.mailing.commands.DetectThresholdCrossingHandler;
@@ -45,7 +46,7 @@ import com.google.common.collect.ImmutableSet;
 
 import reactor.core.publisher.Mono;
 
-public class QuotaThresholdCrossingListener implements MailboxListener.ReactiveGroupMailboxListener {
+public class QuotaThresholdCrossingListener implements EventListener.ReactiveGroupEventListener {
     public static class QuotaThresholdCrossingListenerGroup extends Group {
 
     }
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java
index 1691454..7fc047d 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java
@@ -28,8 +28,8 @@ import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture._75;
 import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture.mailetContext;
 import static org.assertj.core.api.Assertions.assertThat;
 
+import org.apache.james.events.Event;
 import org.apache.james.eventsourcing.eventstore.EventStore;
-import org.apache.james.mailbox.events.Event;
 import org.apache.james.mailbox.quota.QuotaFixture.Counts;
 import org.apache.james.mailbox.quota.QuotaFixture.Sizes;
 import org.apache.james.mailbox.quota.mailing.QuotaMailingListenerConfiguration;
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdCrossingListenerTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdCrossingListenerTest.java
index 6b76fd5..3a8b32b 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdCrossingListenerTest.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdCrossingListenerTest.java
@@ -21,7 +21,7 @@ package org.apache.james.mailbox.quota.mailing.listeners;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import org.apache.james.mailbox.events.Group;
+import org.apache.james.events.Group;
 import org.junit.jupiter.api.Test;
 
 class QuotaThresholdCrossingListenerTest {
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdListenersTestSystem.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdListenersTestSystem.java
index 7969d46..8cea5bc 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdListenersTestSystem.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdListenersTestSystem.java
@@ -20,14 +20,14 @@
 package org.apache.james.mailbox.quota.mailing.listeners;
 
 import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventBus;
+import org.apache.james.events.RegistrationKey;
 import org.apache.james.eventsourcing.eventstore.EventStore;
 import org.apache.james.filesystem.api.FileSystem;
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.EventBusTestFixture;
 import org.apache.james.mailbox.events.InVMEventBus;
 import org.apache.james.mailbox.events.MemoryEventDeadLetters;
-import org.apache.james.mailbox.events.RegistrationKey;
 import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.quota.mailing.QuotaMailingListenerConfiguration;
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java
index ff891eb..3a44044 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java
@@ -37,8 +37,8 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 import java.time.Duration;
 
+import org.apache.james.events.Event;
 import org.apache.james.eventsourcing.eventstore.EventStore;
-import org.apache.james.mailbox.events.Event;
 import org.apache.james.mailbox.quota.QuotaFixture.Counts;
 import org.apache.james.mailbox.quota.QuotaFixture.Sizes;
 import org.apache.james.mailbox.quota.mailing.QuotaMailingListenerConfiguration;
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java
index fe585c6..f12af37 100644
--- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java
+++ b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java
@@ -25,16 +25,17 @@ import org.apache.james.backends.es.DocumentId;
 import org.apache.james.backends.es.ElasticSearchIndexer;
 import org.apache.james.backends.es.RoutingKey;
 import org.apache.james.core.Username;
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.Group;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
+import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.quota.search.elasticsearch.QuotaRatioElasticSearchConstants;
 import org.apache.james.quota.search.elasticsearch.json.QuotaRatioToElasticSearchJson;
 import org.reactivestreams.Publisher;
 
 import reactor.core.publisher.Mono;
 
-public class ElasticSearchQuotaMailboxListener implements MailboxListener.ReactiveGroupMailboxListener {
+public class ElasticSearchQuotaMailboxListener implements EventListener.ReactiveGroupEventListener {
     public static class ElasticSearchQuotaMailboxListenerGroup extends Group {
 
     }
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java
index 7bbe25c..39b7a0d 100644
--- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java
+++ b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java
@@ -22,7 +22,7 @@ package org.apache.james.quota.search.elasticsearch.json;
 import javax.inject.Inject;
 
 import org.apache.james.core.Domain;
-import org.apache.james.mailbox.events.MailboxListener.QuotaUsageUpdatedEvent;
+import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.model.QuotaRatio;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java
index 9e5671b..1011b07 100644
--- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java
+++ b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java
@@ -31,8 +31,8 @@ import org.apache.james.backends.es.ElasticSearchConfiguration;
 import org.apache.james.backends.es.ElasticSearchIndexer;
 import org.apache.james.backends.es.NodeMappingFactory;
 import org.apache.james.backends.es.ReactorElasticSearchClient;
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.Group;
+import org.apache.james.events.Event;
+import org.apache.james.events.Group;
 import org.apache.james.mailbox.quota.QuotaFixture.Counts;
 import org.apache.james.mailbox.quota.QuotaFixture.Sizes;
 import org.apache.james.mailbox.store.event.EventFactory;
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java
index a992127..6432375 100644
--- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java
+++ b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java
@@ -27,8 +27,8 @@ import java.util.Optional;
 
 import org.apache.james.core.Domain;
 import org.apache.james.core.Username;
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.MailboxListener.QuotaUsageUpdatedEvent;
+import org.apache.james.events.Event;
+import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.model.QuotaRoot;
 import org.apache.james.mailbox.quota.QuotaFixture;
 import org.apache.james.mailbox.store.event.EventFactory;
diff --git a/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassinListener.java b/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassinListener.java
index a842a30..3d7b4d3 100644
--- a/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassinListener.java
+++ b/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassinListener.java
@@ -25,12 +25,13 @@ import java.util.stream.Stream;
 import javax.inject.Inject;
 
 import org.apache.james.core.Username;
+import org.apache.james.events.Event;
+import org.apache.james.events.Group;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.Role;
 import org.apache.james.mailbox.SystemMailboxesProvider;
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.Group;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
 import org.apache.james.mailbox.events.MessageMoveEvent;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
diff --git a/mailbox/plugin/spamassassin/src/test/java/org/apache/james/mailbox/spamassassin/SpamAssassinListenerTest.java b/mailbox/plugin/spamassassin/src/test/java/org/apache/james/mailbox/spamassassin/SpamAssassinListenerTest.java
index c24ee8e..ce3a993 100644
--- a/mailbox/plugin/spamassassin/src/test/java/org/apache/james/mailbox/spamassassin/SpamAssassinListenerTest.java
+++ b/mailbox/plugin/spamassassin/src/test/java/org/apache/james/mailbox/spamassassin/SpamAssassinListenerTest.java
@@ -33,11 +33,12 @@ import javax.mail.Flags;
 import javax.mail.util.SharedByteArrayInputStream;
 
 import org.apache.james.core.Username;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
 import org.apache.james.mailbox.DefaultMailboxes;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
-import org.apache.james.mailbox.events.Group;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
 import org.apache.james.mailbox.events.MessageMoveEvent;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
@@ -95,7 +96,7 @@ class SpamAssassinListenerTest {
         spamCapitalMailboxId = mailboxMapper.create(MailboxPath.forUser(USER, "SPAM"), UID_VALIDITY).block().getMailboxId();
         trashMailboxId = mailboxMapper.create(MailboxPath.forUser(USER, "Trash"), UID_VALIDITY).block().getMailboxId();
 
-        listener = new SpamAssassinListener(spamAssassin, systemMailboxesProvider, mailboxManager, mapperFactory, MailboxListener.ExecutionMode.SYNCHRONOUS);
+        listener = new SpamAssassinListener(spamAssassin, systemMailboxesProvider, mailboxManager, mapperFactory, EventListener.ExecutionMode.SYNCHRONOUS);
     }
 
     @Test
@@ -238,7 +239,7 @@ class SpamAssassinListenerTest {
     void eventShouldCallSpamAssassinHamLearningWhenTheMessageIsAddedInInbox() throws Exception {
         SimpleMailboxMessage message = createMessage(inbox);
 
-        MailboxListener.Added addedEvent = EventFactory.added()
+        Added addedEvent = EventFactory.added()
             .randomEventId()
             .mailboxSession(MAILBOX_SESSION)
             .mailbox(inbox)
@@ -254,7 +255,7 @@ class SpamAssassinListenerTest {
     void eventShouldNotCallSpamAssassinHamLearningWhenTheMessageIsAddedInAMailboxOtherThanInbox() throws Exception {
         SimpleMailboxMessage message = createMessage(mailbox1);
 
-        MailboxListener.Added addedEvent = EventFactory.added()
+        Added addedEvent = EventFactory.added()
             .randomEventId()
             .mailboxSession(MAILBOX_SESSION)
             .mailbox(mailbox1)
diff --git a/mailbox/spring/src/main/java/org/apache/james/mailbox/spring/MailboxInitializer.java b/mailbox/spring/src/main/java/org/apache/james/mailbox/spring/MailboxInitializer.java
index 7d8453b..91938c7 100644
--- a/mailbox/spring/src/main/java/org/apache/james/mailbox/spring/MailboxInitializer.java
+++ b/mailbox/spring/src/main/java/org/apache/james/mailbox/spring/MailboxInitializer.java
@@ -21,9 +21,9 @@ package org.apache.james.mailbox.spring;
 
 import javax.inject.Inject;
 
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.SessionProvider;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.event.MailboxAnnotationListener;
 import org.apache.james.mailbox.store.quota.ListeningCurrentQuotaUpdater;
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
index 3ec0836..df7eb76 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
@@ -38,6 +38,7 @@ import javax.inject.Inject;
 import org.apache.james.core.Username;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeUsage;
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxAnnotationManager;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxPathLocker;
@@ -46,7 +47,6 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MetadataWithMailboxId;
 import org.apache.james.mailbox.SessionProvider;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.exception.InboxAlreadyCreated;
 import org.apache.james.mailbox.exception.InsufficientRightsException;
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
index eecc808..9083844 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
@@ -34,6 +34,7 @@ import java.util.stream.Stream;
 import javax.inject.Inject;
 import javax.mail.Flags;
 
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.MessageManager;
@@ -41,7 +42,6 @@ import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.MetadataWithMailboxId;
 import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.RightManager;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MailboxNotFoundException;
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
index cb17d19..0437b04 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
@@ -45,6 +45,8 @@ import javax.mail.util.SharedFileInputStream;
 
 import org.apache.commons.io.input.TeeInputStream;
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.james.events.EventBus;
+import org.apache.james.events.EventListener;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxManager.MessageCapabilities;
 import org.apache.james.mailbox.MailboxPathLocker;
@@ -53,9 +55,7 @@ import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.MetadataWithMailboxId;
 import org.apache.james.mailbox.ModSeq;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
-import org.apache.james.mailbox.events.MailboxListener;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.ReadOnlyException;
 import org.apache.james.mailbox.exception.UnsupportedRightException;
@@ -114,7 +114,7 @@ import reactor.core.scheduler.Schedulers;
  * implementations.
  * 
  * This base class take care of dispatching events to the registered
- * {@link MailboxListener} and so help with handling concurrent
+ * {@link EventListener} and so help with handling concurrent
  * {@link MailboxSession}'s.
  */
 public class StoreMessageManager implements MessageManager {
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java
index 89a2213..43578ea 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java
@@ -31,11 +31,11 @@ import javax.mail.Flags;
 
 import org.apache.james.core.Domain;
 import org.apache.james.core.Username;
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.RightManager;
 import org.apache.james.mailbox.acl.GroupMembershipResolver;
 import org.apache.james.mailbox.acl.MailboxACLResolver;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.exception.DifferentDomainException;
 import org.apache.james.mailbox.exception.InsufficientRightsException;
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/EventFactory.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/EventFactory.java
index ad2fbed..3caaa3e 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/EventFactory.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/EventFactory.java
@@ -29,11 +29,18 @@ import org.apache.james.core.quota.QuotaCountLimit;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
+import org.apache.james.events.Event;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.acl.ACLDiff;
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxACLUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxRenamed;
+import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.events.MessageMoveEvent;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxACL;
@@ -203,13 +210,13 @@ public class EventFactory {
             this.sessionId = sessionId;
         }
 
-        public MailboxListener.MailboxAdded build() {
+        public MailboxAdded build() {
             Preconditions.checkNotNull(path);
             Preconditions.checkNotNull(mailboxId);
             Preconditions.checkNotNull(username);
             Preconditions.checkNotNull(sessionId);
 
-            return new MailboxListener.MailboxAdded(sessionId, username, path, mailboxId, eventId);
+            return new MailboxAdded(sessionId, username, path, mailboxId, eventId);
         }
     }
 
@@ -230,14 +237,14 @@ public class EventFactory {
             this.metaData = ImmutableSortedMap.copyOf(metaData);
         }
 
-        public MailboxListener.Added build() {
+        public Added build() {
             Preconditions.checkNotNull(path);
             Preconditions.checkNotNull(mailboxId);
             Preconditions.checkNotNull(username);
             Preconditions.checkNotNull(sessionId);
             Preconditions.checkNotNull(metaData);
 
-            return new MailboxListener.Added(sessionId, username, path, mailboxId, metaData, eventId);
+            return new Added(sessionId, username, path, mailboxId, metaData, eventId);
         }
     }
 
@@ -258,14 +265,14 @@ public class EventFactory {
             this.metaData = ImmutableSortedMap.copyOf(metaData);
         }
 
-        public MailboxListener.Expunged build() {
+        public Expunged build() {
             Preconditions.checkNotNull(path);
             Preconditions.checkNotNull(mailboxId);
             Preconditions.checkNotNull(username);
             Preconditions.checkNotNull(sessionId);
             Preconditions.checkNotNull(metaData);
 
-            return new MailboxListener.Expunged(sessionId, username, path, mailboxId, metaData, eventId);
+            return new Expunged(sessionId, username, path, mailboxId, metaData, eventId);
         }
     }
 
@@ -286,14 +293,14 @@ public class EventFactory {
             this.aclDiff = aclDiff;
         }
 
-        public MailboxListener.MailboxACLUpdated build() {
+        public MailboxACLUpdated build() {
             Preconditions.checkNotNull(path);
             Preconditions.checkNotNull(mailboxId);
             Preconditions.checkNotNull(username);
             Preconditions.checkNotNull(sessionId);
             Preconditions.checkNotNull(aclDiff);
 
-            return new MailboxListener.MailboxACLUpdated(sessionId, username, path, aclDiff, mailboxId, eventId);
+            return new MailboxACLUpdated(sessionId, username, path, aclDiff, mailboxId, eventId);
         }
     }
 
@@ -320,7 +327,7 @@ public class EventFactory {
             this.totalDeletedSize = totalDeletedSize;
         }
 
-        public MailboxListener.MailboxDeletion build() {
+        public MailboxDeletion build() {
             Preconditions.checkNotNull(path);
             Preconditions.checkNotNull(mailboxId);
             Preconditions.checkNotNull(username);
@@ -329,7 +336,7 @@ public class EventFactory {
             Preconditions.checkNotNull(deletedMessageCount);
             Preconditions.checkNotNull(totalDeletedSize);
 
-            return new MailboxListener.MailboxDeletion(sessionId, username, path, mailboxACL, quotaRoot, deletedMessageCount, totalDeletedSize, mailboxId, eventId);
+            return new MailboxDeletion(sessionId, username, path, mailboxACL, quotaRoot, deletedMessageCount, totalDeletedSize, mailboxId, eventId);
         }
     }
 
@@ -351,14 +358,14 @@ public class EventFactory {
         }
 
 
-        public MailboxListener.MailboxRenamed build() {
+        public MailboxRenamed build() {
             Preconditions.checkNotNull(oldPath);
             Preconditions.checkNotNull(newPath);
             Preconditions.checkNotNull(mailboxId);
             Preconditions.checkNotNull(username);
             Preconditions.checkNotNull(sessionId);
 
-            return new MailboxListener.MailboxRenamed(sessionId, username, oldPath, mailboxId, newPath, eventId);
+            return new MailboxRenamed(sessionId, username, oldPath, mailboxId, newPath, eventId);
         }
     }
 
@@ -380,14 +387,14 @@ public class EventFactory {
         }
 
 
-        public MailboxListener.FlagsUpdated build() {
+        public FlagsUpdated build() {
             Preconditions.checkNotNull(path);
             Preconditions.checkNotNull(mailboxId);
             Preconditions.checkNotNull(username);
             Preconditions.checkNotNull(sessionId);
             Preconditions.checkNotNull(updatedFlags);
 
-            return new MailboxListener.FlagsUpdated(sessionId, username, path, mailboxId, updatedFlags, eventId);
+            return new FlagsUpdated(sessionId, username, path, mailboxId, updatedFlags, eventId);
         }
     }
 
@@ -408,8 +415,8 @@ public class EventFactory {
             this.instant = instant;
         }
 
-        public MailboxListener.QuotaUsageUpdatedEvent build() {
-            return new MailboxListener.QuotaUsageUpdatedEvent(eventId, username, quotaRoot, countQuota, sizeQuota, instant);
+        public QuotaUsageUpdatedEvent build() {
+            return new QuotaUsageUpdatedEvent(eventId, username, quotaRoot, countQuota, sizeQuota, instant);
         }
     }
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxAnnotationListener.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxAnnotationListener.java
index a26717a..1935b08 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxAnnotationListener.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxAnnotationListener.java
@@ -22,17 +22,18 @@ import java.util.List;
 
 import javax.inject.Inject;
 
+import org.apache.james.events.Event;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.SessionProvider;
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.Group;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
 import org.apache.james.mailbox.model.MailboxAnnotation;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.mail.AnnotationMapper;
 
-public class MailboxAnnotationListener implements MailboxListener.GroupMailboxListener {
+public class MailboxAnnotationListener implements EventListener.GroupEventListener {
     public static final class MailboxAnnotationListenerGroup extends Group {
 
     }
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/SpamEventListener.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/SpamEventListener.java
index 4e8e9c9..3eb5d2d 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/SpamEventListener.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/SpamEventListener.java
@@ -18,8 +18,8 @@
  ****************************************************************/
 package org.apache.james.mailbox.store.event;
 
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.events.EventListener;
 
-public interface SpamEventListener extends MailboxListener.GroupMailboxListener {
+public interface SpamEventListener extends EventListener.GroupEventListener {
 
 }
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdater.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdater.java
index d7cbb35..2bafe64 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdater.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdater.java
@@ -25,11 +25,15 @@ import javax.inject.Inject;
 import org.apache.james.core.Username;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeUsage;
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.EventBus;
-import org.apache.james.mailbox.events.Group;
-import org.apache.james.mailbox.events.MailboxListener;
-import org.apache.james.mailbox.events.RegistrationKey;
+import org.apache.james.events.Event;
+import org.apache.james.events.EventBus;
+import org.apache.james.events.EventListener;
+import org.apache.james.events.Group;
+import org.apache.james.events.RegistrationKey;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
+import org.apache.james.mailbox.events.MailboxEvents.MetaDataHoldingEvent;
 import org.apache.james.mailbox.model.QuotaOperation;
 import org.apache.james.mailbox.model.QuotaRoot;
 import org.apache.james.mailbox.quota.CurrentQuotaManager;
@@ -43,7 +47,7 @@ import com.google.common.collect.ImmutableSet;
 import reactor.core.publisher.Mono;
 import reactor.core.scheduler.Schedulers;
 
-public class ListeningCurrentQuotaUpdater implements MailboxListener.ReactiveGroupMailboxListener, QuotaUpdater {
+public class ListeningCurrentQuotaUpdater implements EventListener.ReactiveGroupEventListener, QuotaUpdater {
     public static class ListeningCurrentQuotaUpdaterGroup extends Group {
 
     }
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/LazyMessageSearchIndex.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/LazyMessageSearchIndex.java
index 65c588b..6b71496 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/LazyMessageSearchIndex.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/LazyMessageSearchIndex.java
@@ -26,12 +26,12 @@ import java.util.concurrent.ConcurrentHashMap;
 
 import javax.mail.Flags;
 
+import org.apache.james.events.Group;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxManager.SearchCapabilities;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.SessionProvider;
-import org.apache.james.mailbox.events.Group;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.UnsupportedSearchException;
 import org.apache.james.mailbox.model.Mailbox;
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java
index 5f06c3d..1eae3e9 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java
@@ -23,11 +23,16 @@ import java.util.List;
 
 import javax.mail.Flags;
 
+import org.apache.james.events.Event;
+import org.apache.james.events.EventListener;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.SessionProvider;
-import org.apache.james.mailbox.events.Event;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxEvent;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageRange;
@@ -42,10 +47,10 @@ import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 
 /**
- * {@link MessageSearchIndex} which needs to get registered as global {@link MailboxListener} and so get
+ * {@link MessageSearchIndex} which needs to get registered as global {@link EventListener} and so get
  * notified about message changes. This will then allow to update the underlying index.
  */
-public abstract class ListeningMessageSearchIndex implements MessageSearchIndex, MailboxListener.ReactiveGroupMailboxListener {
+public abstract class ListeningMessageSearchIndex implements MessageSearchIndex, EventListener.ReactiveGroupEventListener {
     protected static final int UNLIMITED = -1;
     private final MailboxSessionMapperFactory factory;
     private final SessionProvider sessionProvider;
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
index 63e87f1..8381a1e 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
@@ -38,6 +38,7 @@ import org.apache.james.core.quota.QuotaCountLimit;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageIdManager;
@@ -46,10 +47,12 @@ import org.apache.james.mailbox.MessageManager.FlagsUpdateMode;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.MetadataWithMailboxId;
 import org.apache.james.mailbox.ModSeq;
-import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.EventBusTestFixture;
 import org.apache.james.mailbox.events.InVMEventBus;
-import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxEvent;
 import org.apache.james.mailbox.events.MemoryEventDeadLetters;
 import org.apache.james.mailbox.events.MessageMoveEvent;
 import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
@@ -143,10 +146,10 @@ public abstract class AbstractMessageIdManagerSideEffectTest {
         messageIdManager.delete(messageId, ImmutableList.of(mailbox1.getMailboxId()), session);
 
         assertThat(eventCollector.getEvents())
-            .filteredOn(event -> event instanceof MailboxListener.Expunged)
+            .filteredOn(event -> event instanceof Expunged)
             .hasSize(1).first()
             .satisfies(e -> {
-                MailboxListener.Expunged event = (MailboxListener.Expunged) e;
+                Expunged event = (Expunged) e;
                 assertThat(event.getMailboxId()).isEqualTo(mailbox1.getMailboxId());
                 assertThat(event.getMailboxPath()).isEqualTo(mailbox1.generateAssociatedPath());
                 assertThat(event.getExpunged().values()).containsOnly(simpleMessageMetaData);
@@ -168,13 +171,13 @@ public abstract class AbstractMessageIdManagerSideEffectTest {
         eventBus.register(eventCollector);
         messageIdManager.delete(ImmutableList.of(messageId1, messageId2), session);
 
-        AbstractListAssert<?, List<? extends MailboxListener.Expunged>, MailboxListener.Expunged, ObjectAssert<MailboxListener.Expunged>> events =
+        AbstractListAssert<?, List<? extends Expunged>, Expunged, ObjectAssert<Expunged>> events =
             assertThat(eventCollector.getEvents())
-                .filteredOn(event -> event instanceof MailboxListener.Expunged)
+                .filteredOn(event -> event instanceof Expunged)
                 .hasSize(2)
-                .extracting(event -> (MailboxListener.Expunged) event);
-        events.extracting(MailboxListener.MailboxEvent::getMailboxId).containsOnly(mailbox1.getMailboxId(), mailbox1.getMailboxId());
-        events.extracting(MailboxListener.Expunged::getExpunged)
+                .extracting(event -> (Expunged) event);
+        events.extracting(MailboxEvent::getMailboxId).containsOnly(mailbox1.getMailboxId(), mailbox1.getMailboxId());
+        events.extracting(Expunged::getExpunged)
             .containsOnly(ImmutableSortedMap.of(simpleMessageMetaData1.getUid(), simpleMessageMetaData1),
                 ImmutableSortedMap.of(simpleMessageMetaData2.getUid(), simpleMessageMetaData2));
     }
@@ -332,8 +335,8 @@ public abstract class AbstractMessageIdManagerSideEffectTest {
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
         assertThat(eventCollector.getEvents()).filteredOn(event -> event instanceof MessageMoveEvent).hasSize(1);
-        assertThat(eventCollector.getEvents()).filteredOn(event -> event instanceof MailboxListener.Added).hasSize(1)
-            .extracting(event -> (MailboxListener.Added) event).extracting(MailboxListener.Added::getMailboxId)
+        assertThat(eventCollector.getEvents()).filteredOn(event -> event instanceof Added).hasSize(1)
+            .extracting(event -> (Added) event).extracting(Added::getMailboxId)
             .containsOnly(mailbox1.getMailboxId());
     }
 
@@ -348,8 +351,8 @@ public abstract class AbstractMessageIdManagerSideEffectTest {
         messageIdManager.getMessage(messageId, FetchGroup.MINIMAL, session);
 
         assertThat(eventCollector.getEvents()).filteredOn(event -> event instanceof MessageMoveEvent).hasSize(1);
-        assertThat(eventCollector.getEvents()).filteredOn(event -> event instanceof MailboxListener.Added).hasSize(2)
-            .extracting(event -> (MailboxListener.Added) event).extracting(MailboxListener.Added::getMailboxId)
+        assertThat(eventCollector.getEvents()).filteredOn(event -> event instanceof Added).hasSize(2)
+            .extracting(event -> (Added) event).extracting(Added::getMailboxId)
             .containsOnly(mailbox1.getMailboxId(), mailbox3.getMailboxId());
     }
 
@@ -381,11 +384,11 @@ public abstract class AbstractMessageIdManagerSideEffectTest {
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox3.getMailboxId()), session);
 
         assertThat(eventCollector.getEvents()).filteredOn(event -> event instanceof MessageMoveEvent).hasSize(1);
-        assertThat(eventCollector.getEvents()).filteredOn(event -> event instanceof MailboxListener.Added).hasSize(1)
-            .extracting(event -> (MailboxListener.Added) event).extracting(MailboxListener.Added::getMailboxId)
+        assertThat(eventCollector.getEvents()).filteredOn(event -> event instanceof Added).hasSize(1)
+            .extracting(event -> (Added) event).extracting(Added::getMailboxId)
             .containsOnly(mailbox3.getMailboxId());
-        assertThat(eventCollector.getEvents()).filteredOn(event -> event instanceof MailboxListener.Expunged).hasSize(1)
-            .extracting(event -> (MailboxListener.Expunged) event).extracting(MailboxListener.Expunged::getMailboxId)
+        assertThat(eventCollector.getEvents()).filteredOn(event -> event instanceof Expunged).hasSize(1)
+            .extracting(event -> (Expunged) event).extracting(Expunged::getMailboxId)
             .containsOnly(mailbox2.getMailboxId());
     }
 
@@ -448,7 +451,7 @@ public abstract class AbstractMessageIdManagerSideEffectTest {
         eventBus.register(eventCollector);
         messageIdManager.setFlags(newFlags, MessageManager.FlagsUpdateMode.ADD, messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
-        assertThat(eventCollector.getEvents()).hasSize(2).allSatisfy(event -> assertThat(event).isInstanceOf(MailboxListener.FlagsUpdated.class));
+        assertThat(eventCollector.getEvents()).hasSize(2).allSatisfy(event -> assertThat(event).isInstanceOf(FlagsUpdated.class));
     }
 
     @Test
@@ -473,9 +476,9 @@ public abstract class AbstractMessageIdManagerSideEffectTest {
             .newFlags(newFlags)
             .build();
 
-        assertThat(eventCollector.getEvents()).hasSize(1).first().isInstanceOf(MailboxListener.FlagsUpdated.class)
+        assertThat(eventCollector.getEvents()).hasSize(1).first().isInstanceOf(FlagsUpdated.class)
             .satisfies(e -> {
-                MailboxListener.FlagsUpdated event = (MailboxListener.FlagsUpdated) e;
+                FlagsUpdated event = (FlagsUpdated) e;
                 assertThat(event.getUpdatedFlags()).containsOnly(updatedFlags);
                 assertThat(event.getMailboxId()).isEqualTo(mailbox2.getMailboxId());
             });
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreRightManagerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreRightManagerTest.java
index a315927..8d78e2c 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreRightManagerTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreRightManagerTest.java
@@ -31,13 +31,13 @@ import static org.mockito.Mockito.when;
 import javax.mail.Flags;
 
 import org.apache.james.core.Username;
+import org.apache.james.events.EventBus;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.acl.GroupMembershipResolver;
 import org.apache.james.mailbox.acl.MailboxACLResolver;
... 2036 lines suppressed ...


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


[james-project] 08/18: JAMES-3498 event-bus-cassandra POM ordering

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 1484bec9eee37ae31341eab6844482f404829d89
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 25 15:48:36 2021 +0700

    JAMES-3498 event-bus-cassandra POM ordering
---
 event-bus/cassandra/pom.xml                        | 28 ++++----
 .../events/CassandraEventDeadLettersGroupDAO.java  |  2 -
 examples/custom-mailets/pom.xml                    | 78 ++++++++++------------
 examples/pom.xml                                   | 51 ++++++--------
 mpt/impl/imap-mailbox/jpa/pom.xml                  | 10 +--
 mpt/impl/imap-mailbox/lucenesearch/pom.xml         |  8 +--
 pom.xml                                            |  2 +-
 server/protocols/webadmin/webadmin-mailbox/pom.xml | 10 +--
 8 files changed, 87 insertions(+), 102 deletions(-)

diff --git a/event-bus/cassandra/pom.xml b/event-bus/cassandra/pom.xml
index b085d77..c65d376 100644
--- a/event-bus/cassandra/pom.xml
+++ b/event-bus/cassandra/pom.xml
@@ -17,13 +17,11 @@
     specific language governing permissions and limitations
     under the License.
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
-        <artifactId>event-bus</artifactId>
         <groupId>org.apache.james</groupId>
+        <artifactId>event-bus</artifactId>
         <version>3.6.0-SNAPSHOT</version>
     </parent>
 
@@ -33,16 +31,6 @@
 
     <dependencies>
         <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-backends-cassandra</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>apache-james-backends-cassandra</artifactId>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-api</artifactId>
         </dependency>
@@ -58,9 +46,19 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-backends-cassandra</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-backends-cassandra</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.testcontainers</groupId>
             <artifactId>testcontainers</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
-</project>
\ No newline at end of file
+</project>
diff --git a/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersGroupDAO.java b/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersGroupDAO.java
index 766d507..2fefd3c 100644
--- a/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersGroupDAO.java
+++ b/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersGroupDAO.java
@@ -20,8 +20,6 @@
 package org.apache.james.events;
 
 import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
-import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
-import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
 
 import javax.inject.Inject;
 
diff --git a/examples/custom-mailets/pom.xml b/examples/custom-mailets/pom.xml
index dfceb5d..779a3db 100644
--- a/examples/custom-mailets/pom.xml
+++ b/examples/custom-mailets/pom.xml
@@ -1,44 +1,40 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <artifactId>examples</artifactId>
-        <groupId>org.apache.james.examples</groupId>
-        <version>3.6.0-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-    <name>Apache James :: Examples :: Custom Mailets</name>
-
-    <artifactId>custom-mailets</artifactId>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.james</groupId>
-            <artifactId>apache-mailet-api</artifactId>
-            <version>${james.baseVersion}</version>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
-            <artifactId>apache-mailet-base</artifactId>
-            <version>${james.baseVersion}</version>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
-            <artifactId>james-server-util</artifactId>
-            <version>${james.baseVersion}</version>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <source>11</source>
-                    <target>11</target>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.james.examples</groupId>
+    <artifactId>examples</artifactId>
+    <version>3.6.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>custom-mailets</artifactId>
+  <name>Apache James :: Examples :: Custom Mailets</name>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.james</groupId>
+      <artifactId>apache-mailet-api</artifactId>
+      <version>${james.baseVersion}</version>
+    </dependency>
+    <dependency>
+      <groupId>${james.groupId}</groupId>
+      <artifactId>apache-mailet-base</artifactId>
+      <version>${james.baseVersion}</version>
+    </dependency>
+    <dependency>
+      <groupId>${james.groupId}</groupId>
+      <artifactId>james-server-util</artifactId>
+      <version>${james.baseVersion}</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>11</source>
+          <target>11</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/examples/pom.xml b/examples/pom.xml
index b6345b2..843f552 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -18,33 +18,26 @@
     under the License.
 -->
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache</groupId>
-        <artifactId>apache</artifactId>
-        <version>23</version>
-        <relativePath></relativePath>
-    </parent>
-
-    <packaging>pom</packaging>
-    <groupId>org.apache.james.examples</groupId>
-    <artifactId>examples</artifactId>
-    <version>3.6.0-SNAPSHOT</version>
-
-    <name>Apache James :: Examples</name>
-
-    <modules>
-        <module>custom-listeners</module>
-        <module>custom-mailets</module>
-    </modules>
-
-    <properties>
-        <james.groupId>org.apache.james</james.groupId>
-        <james.baseVersion>${project.version}</james.baseVersion>
-
-        <maven.compiler.target>1.11</maven.compiler.target>
-        <maven.compiler.source>1.11</maven.compiler.source>
-    </properties>
-
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache</groupId>
+    <artifactId>apache</artifactId>
+    <version>23</version>
+    <relativePath></relativePath>
+  </parent>
+  <groupId>org.apache.james.examples</groupId>
+  <artifactId>examples</artifactId>
+  <version>3.6.0-SNAPSHOT</version>
+  <packaging>pom</packaging>
+  <name>Apache James :: Examples</name>
+  <modules>
+    <module>custom-listeners</module>
+    <module>custom-mailets</module>
+  </modules>
+  <properties>
+    <james.groupId>org.apache.james</james.groupId>
+    <james.baseVersion>${project.version}</james.baseVersion>
+    <maven.compiler.target>1.11</maven.compiler.target>
+    <maven.compiler.source>1.11</maven.compiler.source>
+  </properties>
 </project>
diff --git a/mpt/impl/imap-mailbox/jpa/pom.xml b/mpt/impl/imap-mailbox/jpa/pom.xml
index 054d0ab..ee202b7 100644
--- a/mpt/impl/imap-mailbox/jpa/pom.xml
+++ b/mpt/impl/imap-mailbox/jpa/pom.xml
@@ -45,11 +45,6 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>event-bus-in-vm</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
             <artifactId>apache-james-mailbox-jpa</artifactId>
             <scope>test</scope>
         </dependency>
@@ -70,6 +65,11 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-in-vm</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>metrics-tests</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mpt/impl/imap-mailbox/lucenesearch/pom.xml b/mpt/impl/imap-mailbox/lucenesearch/pom.xml
index 65130fb..31f8d87 100644
--- a/mpt/impl/imap-mailbox/lucenesearch/pom.xml
+++ b/mpt/impl/imap-mailbox/lucenesearch/pom.xml
@@ -42,10 +42,6 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>event-bus-in-vm</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
             <artifactId>apache-james-mailbox-lucene</artifactId>
             <type>test-jar</type>
         </dependency>
@@ -72,6 +68,10 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-in-vm</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>metrics-tests</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/pom.xml b/pom.xml
index dd59b37..5e7a4d3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1157,8 +1157,8 @@
             <dependency>
                 <groupId>${james.groupId}</groupId>
                 <artifactId>event-bus-api</artifactId>
-                <type>test-jar</type>
                 <version>${project.version}</version>
+                <type>test-jar</type>
             </dependency>
             <dependency>
                 <groupId>${james.groupId}</groupId>
diff --git a/server/protocols/webadmin/webadmin-mailbox/pom.xml b/server/protocols/webadmin/webadmin-mailbox/pom.xml
index 0ea715a..6f229e1 100644
--- a/server/protocols/webadmin/webadmin-mailbox/pom.xml
+++ b/server/protocols/webadmin/webadmin-mailbox/pom.xml
@@ -59,11 +59,6 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>event-bus-in-vm</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
             <artifactId>apache-james-mailbox-memory</artifactId>
             <scope>test</scope>
         </dependency>
@@ -137,6 +132,11 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-in-vm</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-json</artifactId>
             <type>test-jar</type>
             <scope>test</scope>


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


[james-project] 04/18: JAMES-3498 Move as is the Cassandra implementation

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 f9312dfd6ecb3050f205a7a5c69a08d60f5bb28c
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 25 14:00:54 2021 +0700

    JAMES-3498 Move as is the Cassandra implementation
---
 .../event/event-cassandra => event-bus/cassandra}/pom.xml | 15 +++++++--------
 .../apache/james/events/CassandraEventDeadLetters.java    |  0
 .../apache/james/events/CassandraEventDeadLettersDAO.java |  0
 .../james/events/CassandraEventDeadLettersGroupDAO.java   |  0
 .../james/events/CassandraEventDeadLettersModule.java     |  0
 .../tables/CassandraEventDeadLettersGroupTable.java       |  0
 .../events/tables/CassandraEventDeadLettersTable.java     |  0
 .../james/events/CassandraEventDeadLettersDAOTest.java    |  0
 .../events/CassandraEventDeadLettersGroupDAOTest.java     |  0
 .../events/CassandraEventDeadLettersHealthCheckTest.java  |  0
 .../james/events/CassandraEventDeadLettersTest.java       |  0
 event-bus/pom.xml                                         |  1 +
 mailbox/pom.xml                                           |  1 -
 pom.xml                                                   | 10 +++++-----
 server/container/guice/cassandra-guice/pom.xml            |  8 ++++----
 15 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/mailbox/event/event-cassandra/pom.xml b/event-bus/cassandra/pom.xml
similarity index 84%
rename from mailbox/event/event-cassandra/pom.xml
rename to event-bus/cassandra/pom.xml
index fd72ca4..12763a8 100644
--- a/mailbox/event/event-cassandra/pom.xml
+++ b/event-bus/cassandra/pom.xml
@@ -17,18 +17,18 @@
     specific language governing permissions and limitations
     under the License.
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
-
     <parent>
+        <artifactId>event-bus</artifactId>
         <groupId>org.apache.james</groupId>
-        <artifactId>apache-james-mailbox</artifactId>
         <version>3.6.0-SNAPSHOT</version>
-        <relativePath>../../pom.xml</relativePath>
     </parent>
 
-    <artifactId>apache-james-mailbox-event-cassandra</artifactId>
-    <name>Apache James :: Mailbox :: Event :: In Cassandra implementation</name>
+    <artifactId>dead-letter-cassandra</artifactId>
+    <name>Apache James :: Event Bus :: Dead Letter :: Cassandra</name>
     <description>In Cassandra implementation for the eventDeadLetter API</description>
 
     <dependencies>
@@ -72,5 +72,4 @@
             <scope>test</scope>
         </dependency>
     </dependencies>
-
-</project>
+</project>
\ No newline at end of file
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLetters.java b/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLetters.java
similarity index 100%
rename from mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLetters.java
rename to event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLetters.java
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java b/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java
similarity index 100%
rename from mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java
rename to event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersGroupDAO.java b/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersGroupDAO.java
similarity index 100%
rename from mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersGroupDAO.java
rename to event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersGroupDAO.java
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersModule.java b/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersModule.java
similarity index 100%
rename from mailbox/event/event-cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersModule.java
rename to event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersModule.java
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/tables/CassandraEventDeadLettersGroupTable.java b/event-bus/cassandra/src/main/java/org/apache/james/events/tables/CassandraEventDeadLettersGroupTable.java
similarity index 100%
rename from mailbox/event/event-cassandra/src/main/java/org/apache/james/events/tables/CassandraEventDeadLettersGroupTable.java
rename to event-bus/cassandra/src/main/java/org/apache/james/events/tables/CassandraEventDeadLettersGroupTable.java
diff --git a/mailbox/event/event-cassandra/src/main/java/org/apache/james/events/tables/CassandraEventDeadLettersTable.java b/event-bus/cassandra/src/main/java/org/apache/james/events/tables/CassandraEventDeadLettersTable.java
similarity index 100%
rename from mailbox/event/event-cassandra/src/main/java/org/apache/james/events/tables/CassandraEventDeadLettersTable.java
rename to event-bus/cassandra/src/main/java/org/apache/james/events/tables/CassandraEventDeadLettersTable.java
diff --git a/mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java
similarity index 100%
rename from mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java
rename to event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersDAOTest.java
diff --git a/mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersGroupDAOTest.java b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersGroupDAOTest.java
similarity index 100%
rename from mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersGroupDAOTest.java
rename to event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersGroupDAOTest.java
diff --git a/mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java
similarity index 100%
rename from mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java
rename to event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java
diff --git a/mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersTest.java b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersTest.java
similarity index 100%
rename from mailbox/event/event-cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersTest.java
rename to event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersTest.java
diff --git a/event-bus/pom.xml b/event-bus/pom.xml
index 4e36b39..95a420c 100644
--- a/event-bus/pom.xml
+++ b/event-bus/pom.xml
@@ -33,6 +33,7 @@
 
     <modules>
         <module>api</module>
+        <module>cassandra</module>
         <module>distributed</module>
         <module>in-vm</module>
     </modules>
diff --git a/mailbox/pom.xml b/mailbox/pom.xml
index f5bb377..e73b5e8 100644
--- a/mailbox/pom.xml
+++ b/mailbox/pom.xml
@@ -40,7 +40,6 @@
         <module>cassandra</module>
         <module>elasticsearch</module>
 
-        <module>event/event-cassandra</module>
         <module>event/json</module>
 
         <module>jpa</module>
diff --git a/pom.xml b/pom.xml
index 5245d5e..146ba5a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -760,11 +760,6 @@
             </dependency>
             <dependency>
                 <groupId>${james.groupId}</groupId>
-                <artifactId>apache-james-mailbox-event-cassandra</artifactId>
-                <version>${project.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>${james.groupId}</groupId>
                 <artifactId>apache-james-mailbox-event-json</artifactId>
                 <version>${project.version}</version>
             </dependency>
@@ -1151,6 +1146,11 @@
             </dependency>
             <dependency>
                 <groupId>${james.groupId}</groupId>
+                <artifactId>dead-letter-cassandra</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${james.groupId}</groupId>
                 <artifactId>event-bus-api</artifactId>
                 <version>${project.version}</version>
             </dependency>
diff --git a/server/container/guice/cassandra-guice/pom.xml b/server/container/guice/cassandra-guice/pom.xml
index 28ee945..66b277f 100644
--- a/server/container/guice/cassandra-guice/pom.xml
+++ b/server/container/guice/cassandra-guice/pom.xml
@@ -77,10 +77,6 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>apache-james-mailbox-event-cassandra</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${james.groupId}</groupId>
             <artifactId>apache-james-mailbox-quota-search-elasticsearch</artifactId>
         </dependency>
         <dependency>
@@ -128,6 +124,10 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>dead-letter-cassandra</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-sourcing-event-store-cassandra</artifactId>
         </dependency>
         <dependency>


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


[james-project] 11/18: JAMES-3498 custom-listeners POM ordering

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 267dd3850fe24ede8bb732444080c4265081b8b2
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 25 15:52:22 2021 +0700

    JAMES-3498 custom-listeners POM ordering
---
 examples/custom-listeners/pom.xml | 52 ++++++++++++++-------
 examples/custom-mailets/pom.xml   | 95 ++++++++++++++++++++++++---------------
 examples/pom.xml                  | 48 +++++++++++---------
 3 files changed, 119 insertions(+), 76 deletions(-)

diff --git a/examples/custom-listeners/pom.xml b/examples/custom-listeners/pom.xml
index 93540fa..a76b3f6 100644
--- a/examples/custom-listeners/pom.xml
+++ b/examples/custom-listeners/pom.xml
@@ -1,29 +1,34 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
     <parent>
-        <artifactId>examples</artifactId>
         <groupId>org.apache.james.examples</groupId>
+        <artifactId>examples</artifactId>
         <version>3.6.0-SNAPSHOT</version>
     </parent>
-    <modelVersion>4.0.0</modelVersion>
 
     <artifactId>custom-listeners</artifactId>
 
     <name>Apache James :: Examples :: Custom Listeners</name>
 
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <source>11</source>
-                    <target>11</target>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
     <dependencies>
         <dependency>
             <groupId>${james.groupId}</groupId>
@@ -34,15 +39,15 @@
             <groupId>${james.groupId}</groupId>
             <artifactId>apache-james-mailbox-api</artifactId>
             <version>${james.baseVersion}</version>
-            <scope>test</scope>
             <type>test-jar</type>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
             <artifactId>apache-james-mailbox-memory</artifactId>
             <version>${james.baseVersion}</version>
-            <scope>test</scope>
             <type>test-jar</type>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
@@ -63,4 +68,17 @@
             <scope>test</scope>
         </dependency>
     </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>11</source>
+                    <target>11</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/examples/custom-mailets/pom.xml b/examples/custom-mailets/pom.xml
index 779a3db..22093a4 100644
--- a/examples/custom-mailets/pom.xml
+++ b/examples/custom-mailets/pom.xml
@@ -1,40 +1,61 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.james.examples</groupId>
-    <artifactId>examples</artifactId>
-    <version>3.6.0-SNAPSHOT</version>
-  </parent>
-  <artifactId>custom-mailets</artifactId>
-  <name>Apache James :: Examples :: Custom Mailets</name>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.james</groupId>
-      <artifactId>apache-mailet-api</artifactId>
-      <version>${james.baseVersion}</version>
-    </dependency>
-    <dependency>
-      <groupId>${james.groupId}</groupId>
-      <artifactId>apache-mailet-base</artifactId>
-      <version>${james.baseVersion}</version>
-    </dependency>
-    <dependency>
-      <groupId>${james.groupId}</groupId>
-      <artifactId>james-server-util</artifactId>
-      <version>${james.baseVersion}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <configuration>
-          <source>11</source>
-          <target>11</target>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.james.examples</groupId>
+        <artifactId>examples</artifactId>
+        <version>3.6.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>custom-mailets</artifactId>
+    <name>Apache James :: Examples :: Custom Mailets</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-mailet-api</artifactId>
+            <version>${james.baseVersion}</version>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>apache-mailet-base</artifactId>
+            <version>${james.baseVersion}</version>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-util</artifactId>
+            <version>${james.baseVersion}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>11</source>
+                    <target>11</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/examples/pom.xml b/examples/pom.xml
index 843f552..2a913a7 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -18,26 +18,30 @@
     under the License.
 -->
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache</groupId>
-    <artifactId>apache</artifactId>
-    <version>23</version>
-    <relativePath></relativePath>
-  </parent>
-  <groupId>org.apache.james.examples</groupId>
-  <artifactId>examples</artifactId>
-  <version>3.6.0-SNAPSHOT</version>
-  <packaging>pom</packaging>
-  <name>Apache James :: Examples</name>
-  <modules>
-    <module>custom-listeners</module>
-    <module>custom-mailets</module>
-  </modules>
-  <properties>
-    <james.groupId>org.apache.james</james.groupId>
-    <james.baseVersion>${project.version}</james.baseVersion>
-    <maven.compiler.target>1.11</maven.compiler.target>
-    <maven.compiler.source>1.11</maven.compiler.source>
-  </properties>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache</groupId>
+        <artifactId>apache</artifactId>
+        <version>23</version>
+        <relativePath></relativePath>
+    </parent>
+
+    <groupId>org.apache.james.examples</groupId>
+    <artifactId>examples</artifactId>
+    <version>3.6.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+
+    <name>Apache James :: Examples</name>
+
+    <modules>
+        <module>custom-listeners</module>
+        <module>custom-mailets</module>
+    </modules>
+
+    <properties>
+        <james.groupId>org.apache.james</james.groupId>
+        <james.baseVersion>${project.version}</james.baseVersion>
+        <maven.compiler.target>1.11</maven.compiler.target>
+        <maven.compiler.source>1.11</maven.compiler.source>
+    </properties>
 </project>


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


[james-project] 10/18: JAMES-3498 Mailbox event api should be in org.apache.james.mailbox.events

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 082a63f9bb4eae731b0d30d064f6b00c2b0cfb15
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 25 19:07:02 2021 +0700

    JAMES-3498 Mailbox event api should be in org.apache.james.mailbox.events
---
 .../custom/listeners/SetCustomFlagOnBigMessages.java   |  2 +-
 .../james/{ => mailbox}/events/MailboxEvents.java      |  2 +-
 .../{ => mailbox}/events/MailboxIdRegistrationKey.java |  3 ++-
 .../james/{ => mailbox}/events/MessageMoveEvent.java   |  3 ++-
 .../test/java/org/apache/james/mailbox/EventTest.java  |  2 +-
 .../org/apache/james/mailbox/MailboxListenerTest.java  | 16 ++++++++--------
 .../james/mailbox/MailboxManagerStressContract.java    |  4 ++--
 .../org/apache/james/mailbox/MailboxManagerTest.java   | 16 ++++++++--------
 .../org/apache/james/mailbox/MessageMoveEventTest.java |  2 +-
 .../events/MailboxIdRegistrationKeyTest.java           |  2 +-
 .../apache/james/mailbox/model/MessageMovesTest.java   |  2 +-
 .../james/mailbox/cassandra/DeleteMessageListener.java |  4 ++--
 .../cassandra/MailboxOperationLoggingListener.java     |  6 +++---
 .../james/event/json/MailboxEventSerializer.scala      |  5 +++--
 .../james/event/json/AddedSerializationTest.java       |  2 +-
 .../james/event/json/ExpungedSerializationTest.java    |  2 +-
 .../event/json/FlagsUpdatedSerializationTest.java      |  2 +-
 .../json/MailboxACLUpdatedEventSerializationTest.java  |  2 +-
 .../event/json/MailboxAddedSerializationTest.java      |  2 +-
 .../event/json/MailboxDeletionSerializationTest.java   |  2 +-
 .../event/json/MailboxRenamedSerializationTest.java    |  2 +-
 .../event/json/MessageMoveEventSerializationTest.java  |  2 +-
 .../json/QuotaUsageUpdatedEventSerializationTest.java  |  2 +-
 .../listeners/QuotaThresholdCrossingListener.java      |  2 +-
 .../events/ElasticSearchQuotaMailboxListener.java      |  2 +-
 .../json/QuotaRatioToElasticSearchJson.java            |  2 +-
 .../json/QuotaRatioToElasticSearchJsonTest.java        |  2 +-
 .../mailbox/spamassassin/SpamAssassinListener.java     |  4 ++--
 .../mailbox/spamassassin/SpamAssassinListenerTest.java |  4 ++--
 .../james/mailbox/store/StoreMailboxManager.java       |  2 +-
 .../james/mailbox/store/StoreMessageIdManager.java     |  2 +-
 .../james/mailbox/store/StoreMessageManager.java       |  2 +-
 .../apache/james/mailbox/store/StoreRightManager.java  |  2 +-
 .../apache/james/mailbox/store/event/EventFactory.java | 18 +++++++++---------
 .../mailbox/store/event/MailboxAnnotationListener.java |  2 +-
 .../store/quota/ListeningCurrentQuotaUpdater.java      |  8 ++++----
 .../store/search/ListeningMessageSearchIndex.java      | 10 +++++-----
 .../store/AbstractMessageIdManagerSideEffectTest.java  | 10 +++++-----
 .../mailbox/store/MessageIdManagerTestSystem.java      |  2 +-
 .../store/event/MailboxAnnotationListenerTest.java     |  4 ++--
 .../store/quota/ListeningCurrentQuotaUpdaterTest.java  |  6 +++---
 .../rabbitmq/host/RabbitMQEventBusHostSystem.java      |  2 +-
 .../org/apache/james/imap/processor/IdleProcessor.java |  8 ++++----
 .../james/imap/processor/base/SelectedMailboxImpl.java | 14 +++++++-------
 .../imap/processor/base/MailboxEventAnalyserTest.java  |  8 ++++----
 .../imap/processor/base/SelectedMailboxImplTest.java   |  4 ++--
 .../james/modules/event/RabbitMQEventBusModule.java    |  2 +-
 .../org/apache/james/jmap/api/change/EmailChange.java  |  6 +++---
 .../apache/james/jmap/api/change/MailboxChange.java    | 14 +++++++-------
 .../methods/integration/SetMessagesMethodTest.java     |  2 +-
 .../ComputeMessageFastViewProjectionListener.java      |  2 +-
 .../jmap/event/PopulateEmailQueryViewListener.java     |  6 +++---
 .../james/jmap/event/PropagateLookupRightListener.java |  4 ++--
 .../james/jmap/change/MailboxChangeListener.scala      |  2 +-
 ...WebAdminServerTaskSerializationIntegrationTest.java |  2 +-
 .../webadmin/routes/EventDeadLettersRoutesTest.java    |  2 +-
 56 files changed, 126 insertions(+), 123 deletions(-)

diff --git a/examples/custom-listeners/src/main/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessages.java b/examples/custom-listeners/src/main/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessages.java
index 6c942ce..d7223c1 100644
--- a/examples/custom-listeners/src/main/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessages.java
+++ b/examples/custom-listeners/src/main/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessages.java
@@ -25,12 +25,12 @@ import javax.mail.Flags;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventListener;
 import org.apache.james.events.Group;
-import org.apache.james.events.MailboxEvents.Added;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageManager.FlagsUpdateMode;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MessageRange;
 import org.slf4j.Logger;
diff --git a/mailbox/api/src/main/java/org/apache/james/events/MailboxEvents.java b/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxEvents.java
similarity index 99%
rename from mailbox/api/src/main/java/org/apache/james/events/MailboxEvents.java
rename to mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxEvents.java
index 20dbe89..d544e35 100644
--- a/mailbox/api/src/main/java/org/apache/james/events/MailboxEvents.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxEvents.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.events;
+package org.apache.james.mailbox.events;
 
 import java.time.Instant;
 import java.util.Collection;
diff --git a/mailbox/api/src/main/java/org/apache/james/events/MailboxIdRegistrationKey.java b/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxIdRegistrationKey.java
similarity index 96%
rename from mailbox/api/src/main/java/org/apache/james/events/MailboxIdRegistrationKey.java
rename to mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxIdRegistrationKey.java
index 44387cb..cbbd20b 100644
--- a/mailbox/api/src/main/java/org/apache/james/events/MailboxIdRegistrationKey.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxIdRegistrationKey.java
@@ -17,12 +17,13 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.events;
+package org.apache.james.mailbox.events;
 
 import java.util.Objects;
 
 import javax.inject.Inject;
 
+import org.apache.james.events.RegistrationKey;
 import org.apache.james.mailbox.model.MailboxId;
 
 public class MailboxIdRegistrationKey implements RegistrationKey {
diff --git a/mailbox/api/src/main/java/org/apache/james/events/MessageMoveEvent.java b/mailbox/api/src/main/java/org/apache/james/mailbox/events/MessageMoveEvent.java
similarity index 98%
rename from mailbox/api/src/main/java/org/apache/james/events/MessageMoveEvent.java
rename to mailbox/api/src/main/java/org/apache/james/mailbox/events/MessageMoveEvent.java
index 2c2f89f..69173d2 100644
--- a/mailbox/api/src/main/java/org/apache/james/events/MessageMoveEvent.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/events/MessageMoveEvent.java
@@ -16,13 +16,14 @@
  * specific language governing permissions and limitations      *
  * under the License.                                           *
  ****************************************************************/
-package org.apache.james.events;
+package org.apache.james.mailbox.events;
 
 import java.util.Collection;
 import java.util.Objects;
 import java.util.Optional;
 
 import org.apache.james.core.Username;
+import org.apache.james.events.Event;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageId;
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/EventTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/EventTest.java
index 1d36cd7..c25f7df 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/EventTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/EventTest.java
@@ -28,7 +28,7 @@ import javax.mail.Flags;
 
 import org.apache.james.core.Username;
 import org.apache.james.events.Event;
-import org.apache.james.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.TestId;
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxListenerTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxListenerTest.java
index 5ff940d..13fa417 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxListenerTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxListenerTest.java
@@ -34,15 +34,15 @@ import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
 import org.apache.james.events.Event;
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.events.MailboxEvents.Expunged;
-import org.apache.james.events.MailboxEvents.FlagsUpdated;
-import org.apache.james.events.MailboxEvents.MailboxACLUpdated;
-import org.apache.james.events.MailboxEvents.MailboxAdded;
-import org.apache.james.events.MailboxEvents.MailboxDeletion;
-import org.apache.james.events.MailboxEvents.MailboxRenamed;
-import org.apache.james.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.acl.ACLDiff;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxACLUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxRenamed;
+import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageMetaData;
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java
index bd95fd3..d8667e2 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java
@@ -33,8 +33,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.james.core.Username;
 import org.apache.james.events.EventBus;
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.events.MailboxIdRegistrationKey;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.MailboxId;
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
index 03c5a46..7a23c69 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
@@ -47,17 +47,17 @@ import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
 import org.apache.james.events.EventBus;
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.events.MailboxEvents.Expunged;
-import org.apache.james.events.MailboxEvents.FlagsUpdated;
-import org.apache.james.events.MailboxEvents.MailboxAdded;
-import org.apache.james.events.MailboxEvents.MailboxDeletion;
-import org.apache.james.events.MailboxEvents.QuotaUsageUpdatedEvent;
-import org.apache.james.events.MailboxIdRegistrationKey;
-import org.apache.james.events.MessageMoveEvent;
 import org.apache.james.mailbox.MailboxManager.MailboxCapabilities;
 import org.apache.james.mailbox.MailboxManager.MailboxRenamedResult;
 import org.apache.james.mailbox.MessageManager.AppendCommand;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
+import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
+import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
+import org.apache.james.mailbox.events.MessageMoveEvent;
 import org.apache.james.mailbox.exception.AnnotationException;
 import org.apache.james.mailbox.exception.HasEmptyMailboxNameInHierarchyException;
 import org.apache.james.mailbox.exception.InboxAlreadyCreated;
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MessageMoveEventTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MessageMoveEventTest.java
index 73859f4..0069e62 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MessageMoveEventTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MessageMoveEventTest.java
@@ -22,7 +22,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import org.apache.james.core.Username;
-import org.apache.james.events.MessageMoveEvent;
+import org.apache.james.mailbox.events.MessageMoveEvent;
 import org.apache.james.mailbox.model.MessageMoves;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
diff --git a/mailbox/api/src/test/java/org/apache/james/events/MailboxIdRegistrationKeyTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/MailboxIdRegistrationKeyTest.java
similarity index 98%
rename from mailbox/api/src/test/java/org/apache/james/events/MailboxIdRegistrationKeyTest.java
rename to mailbox/api/src/test/java/org/apache/james/mailbox/events/MailboxIdRegistrationKeyTest.java
index 0fb1de2..0a361b6 100644
--- a/mailbox/api/src/test/java/org/apache/james/events/MailboxIdRegistrationKeyTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/events/MailboxIdRegistrationKeyTest.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.events;
+package org.apache.james.mailbox.events;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageMovesTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageMovesTest.java
index 1710ceb..8787db5 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageMovesTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageMovesTest.java
@@ -19,7 +19,7 @@
 
 package org.apache.james.mailbox.model;
 
-import org.apache.james.events.MessageMoveEvent;
+import org.apache.james.mailbox.events.MessageMoveEvent;
 import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java
index 4b2f084..728bd81 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java
@@ -31,8 +31,6 @@ import org.apache.james.blob.api.BlobStore;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventListener;
 import org.apache.james.events.Group;
-import org.apache.james.events.MailboxEvents.Expunged;
-import org.apache.james.events.MailboxEvents.MailboxDeletion;
 import org.apache.james.mailbox.acl.ACLDiff;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
@@ -52,6 +50,8 @@ import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraUserMailboxRightsDAO;
 import org.apache.james.mailbox.cassandra.mail.MessageAttachmentRepresentation;
 import org.apache.james.mailbox.cassandra.mail.MessageRepresentation;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
 import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MessageMetaData;
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListener.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListener.java
index b48508f..dcfd070 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListener.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListener.java
@@ -26,9 +26,9 @@ import static org.apache.james.mailbox.cassandra.GhostMailbox.TYPE;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventListener;
 import org.apache.james.events.Group;
-import org.apache.james.events.MailboxEvents.MailboxAdded;
-import org.apache.james.events.MailboxEvents.MailboxDeletion;
-import org.apache.james.events.MailboxEvents.MailboxRenamed;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxRenamed;
 
 /**
  * See https://issues.apache.org/jira/browse/MAILBOX-322 for reading about the Ghost mailbox bug.
diff --git a/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala b/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala
index 4a97b73..cee6dc3 100644
--- a/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala
+++ b/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala
@@ -30,9 +30,10 @@ import org.apache.james.event.json.DTOs.SystemFlag.SystemFlag
 import org.apache.james.event.json.DTOs._
 import org.apache.james.events
 import org.apache.james.events.Event.EventId
-import org.apache.james.events.MailboxEvents.{Added => JavaAdded, Expunged => JavaExpunged, FlagsUpdated => JavaFlagsUpdated, MailboxACLUpdated => JavaMailboxACLUpdated, MailboxAdded => JavaMailboxAdded, MailboxDeletion => JavaMailboxDeletion, MailboxRenamed => JavaMailboxRenamed, QuotaUsageUpdatedEvent => JavaQuotaUsageUpdatedEvent}
-import org.apache.james.events.{EventSerializer, MessageMoveEvent => JavaMessageMoveEvent}
+import org.apache.james.events.EventSerializer
 import org.apache.james.mailbox.MailboxSession.SessionId
+import org.apache.james.mailbox.events.MailboxEvents.{Added => JavaAdded, Expunged => JavaExpunged, FlagsUpdated => JavaFlagsUpdated, MailboxACLUpdated => JavaMailboxACLUpdated, MailboxAdded => JavaMailboxAdded, MailboxDeletion => JavaMailboxDeletion, MailboxRenamed => JavaMailboxRenamed, QuotaUsageUpdatedEvent => JavaQuotaUsageUpdatedEvent}
+import org.apache.james.mailbox.events.{MessageMoveEvent => JavaMessageMoveEvent}
 import org.apache.james.mailbox.model.{MailboxId, MessageId, MessageMoves, QuotaRoot, MailboxACL => JavaMailboxACL, MessageMetaData => JavaMessageMetaData, Quota => JavaQuota}
 import org.apache.james.mailbox.quota.QuotaRootDeserializer
 import org.apache.james.mailbox.{MessageUid, ModSeq}
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
index 2f9c48a..7477cad 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
@@ -33,11 +33,11 @@ import java.util.SortedMap;
 import javax.mail.Flags;
 
 import org.apache.james.core.Username;
-import org.apache.james.events.MailboxEvents.Added;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java
index ab5bd33..866f241 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java
@@ -33,11 +33,11 @@ import java.util.NoSuchElementException;
 import javax.mail.Flags;
 
 import org.apache.james.core.Username;
-import org.apache.james.events.MailboxEvents.Expunged;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java
index 2e5fbf1..d90e7df 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java
@@ -31,11 +31,11 @@ import java.util.NoSuchElementException;
 import javax.mail.Flags;
 
 import org.apache.james.core.Username;
-import org.apache.james.events.MailboxEvents.FlagsUpdated;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java
index 20e1888..e957e53 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java
@@ -28,9 +28,9 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import java.util.NoSuchElementException;
 
 import org.apache.james.core.Username;
-import org.apache.james.events.MailboxEvents.MailboxACLUpdated;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.acl.ACLDiff;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxACLUpdated;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxAddedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxAddedSerializationTest.java
index 6ebc085..1063d2f 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxAddedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxAddedSerializationTest.java
@@ -28,8 +28,8 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import java.util.NoSuchElementException;
 
 import org.apache.james.core.Username;
-import org.apache.james.events.MailboxEvents.MailboxAdded;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.TestId;
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxDeletionSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxDeletionSerializationTest.java
index 4ee6d75..99f7072 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxDeletionSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxDeletionSerializationTest.java
@@ -34,8 +34,8 @@ import org.apache.james.core.Domain;
 import org.apache.james.core.Username;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeUsage;
-import org.apache.james.events.MailboxEvents.MailboxDeletion;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxRenamedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxRenamedSerializationTest.java
index 9f48940..18e55d4 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxRenamedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxRenamedSerializationTest.java
@@ -29,8 +29,8 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import java.util.NoSuchElementException;
 
 import org.apache.james.core.Username;
-import org.apache.james.events.MailboxEvents.MailboxRenamed;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxRenamed;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.TestId;
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageMoveEventSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageMoveEventSerializationTest.java
index 9a74194..b24bc93 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageMoveEventSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageMoveEventSerializationTest.java
@@ -29,7 +29,7 @@ import java.util.NoSuchElementException;
 
 import org.apache.james.core.Username;
 import org.apache.james.events.Event;
-import org.apache.james.events.MessageMoveEvent;
+import org.apache.james.mailbox.events.MessageMoveEvent;
 import org.apache.james.mailbox.model.MessageMoves;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/QuotaUsageUpdatedEventSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/QuotaUsageUpdatedEventSerializationTest.java
index 0295738..7991349 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/QuotaUsageUpdatedEventSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/QuotaUsageUpdatedEventSerializationTest.java
@@ -34,7 +34,7 @@ import org.apache.james.core.quota.QuotaCountLimit;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
-import org.apache.james.events.MailboxEvents.QuotaUsageUpdatedEvent;
+import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.mailbox.model.QuotaRoot;
 import org.junit.jupiter.api.Test;
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdCrossingListener.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdCrossingListener.java
index 01fd912..da86cd6 100644
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdCrossingListener.java
+++ b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdCrossingListener.java
@@ -27,13 +27,13 @@ import org.apache.james.core.Username;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventListener;
 import org.apache.james.events.Group;
-import org.apache.james.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.eventsourcing.Command;
 import org.apache.james.eventsourcing.CommandHandler;
 import org.apache.james.eventsourcing.EventSourcingSystem;
 import org.apache.james.eventsourcing.Subscriber;
 import org.apache.james.eventsourcing.eventstore.EventStore;
 import org.apache.james.filesystem.api.FileSystem;
+import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.quota.mailing.QuotaMailingListenerConfiguration;
 import org.apache.james.mailbox.quota.mailing.commands.DetectThresholdCrossing;
 import org.apache.james.mailbox.quota.mailing.commands.DetectThresholdCrossingHandler;
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java
index c476ef1..f12af37 100644
--- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java
+++ b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java
@@ -28,7 +28,7 @@ import org.apache.james.core.Username;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventListener;
 import org.apache.james.events.Group;
-import org.apache.james.events.MailboxEvents.QuotaUsageUpdatedEvent;
+import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.quota.search.elasticsearch.QuotaRatioElasticSearchConstants;
 import org.apache.james.quota.search.elasticsearch.json.QuotaRatioToElasticSearchJson;
 import org.reactivestreams.Publisher;
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java
index 230a974..39b7a0d 100644
--- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java
+++ b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java
@@ -22,7 +22,7 @@ package org.apache.james.quota.search.elasticsearch.json;
 import javax.inject.Inject;
 
 import org.apache.james.core.Domain;
-import org.apache.james.events.MailboxEvents.QuotaUsageUpdatedEvent;
+import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.model.QuotaRatio;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java
index a78f4cd..6432375 100644
--- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java
+++ b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java
@@ -28,7 +28,7 @@ import java.util.Optional;
 import org.apache.james.core.Domain;
 import org.apache.james.core.Username;
 import org.apache.james.events.Event;
-import org.apache.james.events.MailboxEvents.QuotaUsageUpdatedEvent;
+import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.model.QuotaRoot;
 import org.apache.james.mailbox.quota.QuotaFixture;
 import org.apache.james.mailbox.store.event.EventFactory;
diff --git a/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassinListener.java b/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassinListener.java
index f97dd39..3d7b4d3 100644
--- a/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassinListener.java
+++ b/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassinListener.java
@@ -27,12 +27,12 @@ import javax.inject.Inject;
 import org.apache.james.core.Username;
 import org.apache.james.events.Event;
 import org.apache.james.events.Group;
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.events.MessageMoveEvent;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.Role;
 import org.apache.james.mailbox.SystemMailboxesProvider;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MessageMoveEvent;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxId;
diff --git a/mailbox/plugin/spamassassin/src/test/java/org/apache/james/mailbox/spamassassin/SpamAssassinListenerTest.java b/mailbox/plugin/spamassassin/src/test/java/org/apache/james/mailbox/spamassassin/SpamAssassinListenerTest.java
index 810f71c..ce3a993 100644
--- a/mailbox/plugin/spamassassin/src/test/java/org/apache/james/mailbox/spamassassin/SpamAssassinListenerTest.java
+++ b/mailbox/plugin/spamassassin/src/test/java/org/apache/james/mailbox/spamassassin/SpamAssassinListenerTest.java
@@ -35,11 +35,11 @@ import javax.mail.util.SharedByteArrayInputStream;
 import org.apache.james.core.Username;
 import org.apache.james.events.EventListener;
 import org.apache.james.events.Group;
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.events.MessageMoveEvent;
 import org.apache.james.mailbox.DefaultMailboxes;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MessageMoveEvent;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
 import org.apache.james.mailbox.model.Mailbox;
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
index 532ed5e..df7eb76 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
@@ -39,7 +39,6 @@ import org.apache.james.core.Username;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeUsage;
 import org.apache.james.events.EventBus;
-import org.apache.james.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.MailboxAnnotationManager;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxPathLocker;
@@ -48,6 +47,7 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MetadataWithMailboxId;
 import org.apache.james.mailbox.SessionProvider;
+import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.exception.InboxAlreadyCreated;
 import org.apache.james.mailbox.exception.InsufficientRightsException;
 import org.apache.james.mailbox.exception.MailboxException;
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
index 715ed3f..9083844 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
@@ -35,7 +35,6 @@ import javax.inject.Inject;
 import javax.mail.Flags;
 
 import org.apache.james.events.EventBus;
-import org.apache.james.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.MessageManager;
@@ -43,6 +42,7 @@ import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.MetadataWithMailboxId;
 import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.RightManager;
+import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MailboxNotFoundException;
 import org.apache.james.mailbox.extension.PreDeletionHook;
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
index 0a04397..0437b04 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
@@ -47,7 +47,6 @@ import org.apache.commons.io.input.TeeInputStream;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.james.events.EventBus;
 import org.apache.james.events.EventListener;
-import org.apache.james.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxManager.MessageCapabilities;
 import org.apache.james.mailbox.MailboxPathLocker;
@@ -56,6 +55,7 @@ import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.MetadataWithMailboxId;
 import org.apache.james.mailbox.ModSeq;
+import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.ReadOnlyException;
 import org.apache.james.mailbox.exception.UnsupportedRightException;
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java
index 25174ed..43578ea 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java
@@ -32,11 +32,11 @@ import javax.mail.Flags;
 import org.apache.james.core.Domain;
 import org.apache.james.core.Username;
 import org.apache.james.events.EventBus;
-import org.apache.james.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.RightManager;
 import org.apache.james.mailbox.acl.GroupMembershipResolver;
 import org.apache.james.mailbox.acl.MailboxACLResolver;
+import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.exception.DifferentDomainException;
 import org.apache.james.mailbox.exception.InsufficientRightsException;
 import org.apache.james.mailbox.exception.MailboxException;
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/EventFactory.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/EventFactory.java
index 2445e7f..3caaa3e 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/EventFactory.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/EventFactory.java
@@ -30,18 +30,18 @@ import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
 import org.apache.james.events.Event;
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.events.MailboxEvents.Expunged;
-import org.apache.james.events.MailboxEvents.FlagsUpdated;
-import org.apache.james.events.MailboxEvents.MailboxACLUpdated;
-import org.apache.james.events.MailboxEvents.MailboxAdded;
-import org.apache.james.events.MailboxEvents.MailboxDeletion;
-import org.apache.james.events.MailboxEvents.MailboxRenamed;
-import org.apache.james.events.MailboxEvents.QuotaUsageUpdatedEvent;
-import org.apache.james.events.MessageMoveEvent;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.acl.ACLDiff;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxACLUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxRenamed;
+import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
+import org.apache.james.mailbox.events.MessageMoveEvent;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxId;
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxAnnotationListener.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxAnnotationListener.java
index db0c0eb..1935b08 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxAnnotationListener.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxAnnotationListener.java
@@ -25,9 +25,9 @@ import javax.inject.Inject;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventListener;
 import org.apache.james.events.Group;
-import org.apache.james.events.MailboxEvents.MailboxDeletion;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.SessionProvider;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
 import org.apache.james.mailbox.model.MailboxAnnotation;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdater.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdater.java
index 3db9583..2bafe64 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdater.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdater.java
@@ -29,11 +29,11 @@ import org.apache.james.events.Event;
 import org.apache.james.events.EventBus;
 import org.apache.james.events.EventListener;
 import org.apache.james.events.Group;
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.events.MailboxEvents.Expunged;
-import org.apache.james.events.MailboxEvents.MailboxDeletion;
-import org.apache.james.events.MailboxEvents.MetaDataHoldingEvent;
 import org.apache.james.events.RegistrationKey;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
+import org.apache.james.mailbox.events.MailboxEvents.MetaDataHoldingEvent;
 import org.apache.james.mailbox.model.QuotaOperation;
 import org.apache.james.mailbox.model.QuotaRoot;
 import org.apache.james.mailbox.quota.CurrentQuotaManager;
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java
index da60a2d..1eae3e9 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java
@@ -25,14 +25,14 @@ import javax.mail.Flags;
 
 import org.apache.james.events.Event;
 import org.apache.james.events.EventListener;
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.events.MailboxEvents.Expunged;
-import org.apache.james.events.MailboxEvents.FlagsUpdated;
-import org.apache.james.events.MailboxEvents.MailboxDeletion;
-import org.apache.james.events.MailboxEvents.MailboxEvent;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.SessionProvider;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxEvent;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageRange;
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
index a32c06e..63ec65e 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
@@ -40,12 +40,7 @@ import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
 import org.apache.james.events.EventBus;
 import org.apache.james.events.InVMEventBus;
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.events.MailboxEvents.Expunged;
-import org.apache.james.events.MailboxEvents.FlagsUpdated;
-import org.apache.james.events.MailboxEvents.MailboxEvent;
 import org.apache.james.events.MemoryEventDeadLetters;
-import org.apache.james.events.MessageMoveEvent;
 import org.apache.james.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
@@ -55,6 +50,11 @@ import org.apache.james.mailbox.MessageManager.FlagsUpdateMode;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.MetadataWithMailboxId;
 import org.apache.james.mailbox.ModSeq;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxEvent;
+import org.apache.james.mailbox.events.MessageMoveEvent;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.OverQuotaException;
 import org.apache.james.mailbox.extension.PreDeletionHook;
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageIdManagerTestSystem.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageIdManagerTestSystem.java
index fa620a6..7728ed3 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageIdManagerTestSystem.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageIdManagerTestSystem.java
@@ -25,11 +25,11 @@ import java.util.Date;
 import javax.mail.Flags;
 import javax.mail.util.SharedByteArrayInputStream;
 
-import org.apache.james.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
+import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxACL;
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/MailboxAnnotationListenerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/MailboxAnnotationListenerTest.java
index be34240..ede6600 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/MailboxAnnotationListenerTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/MailboxAnnotationListenerTest.java
@@ -35,11 +35,11 @@ import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeUsage;
 import org.apache.james.events.Event;
 import org.apache.james.events.Group;
-import org.apache.james.events.MailboxEvents.MailboxAdded;
-import org.apache.james.events.MailboxEvents.MailboxEvent;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.SessionProvider;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxEvent;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxAnnotation;
 import org.apache.james.mailbox.model.MailboxAnnotationKey;
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdaterTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdaterTest.java
index bc80ef0..26452e2 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdaterTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdaterTest.java
@@ -40,11 +40,11 @@ import org.apache.james.core.quota.QuotaSizeUsage;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventBus;
 import org.apache.james.events.Group;
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.events.MailboxEvents.Expunged;
-import org.apache.james.events.MailboxEvents.MailboxDeletion;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.QuotaOperation;
diff --git a/mpt/impl/imap-mailbox/rabbitmq/src/test/java/org/apache/james/mpt/imapmailbox/rabbitmq/host/RabbitMQEventBusHostSystem.java b/mpt/impl/imap-mailbox/rabbitmq/src/test/java/org/apache/james/mpt/imapmailbox/rabbitmq/host/RabbitMQEventBusHostSystem.java
index 7fe9406..d6a451d 100644
--- a/mpt/impl/imap-mailbox/rabbitmq/src/test/java/org/apache/james/mpt/imapmailbox/rabbitmq/host/RabbitMQEventBusHostSystem.java
+++ b/mpt/impl/imap-mailbox/rabbitmq/src/test/java/org/apache/james/mpt/imapmailbox/rabbitmq/host/RabbitMQEventBusHostSystem.java
@@ -32,7 +32,6 @@ import org.apache.james.core.quota.QuotaCountLimit;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.event.json.MailboxEventSerializer;
 import org.apache.james.events.EventBusId;
-import org.apache.james.events.MailboxIdRegistrationKey;
 import org.apache.james.events.MemoryEventDeadLetters;
 import org.apache.james.events.RabbitMQEventBus;
 import org.apache.james.events.RetryBackoffConfiguration;
@@ -42,6 +41,7 @@ import org.apache.james.imap.encode.main.DefaultImapEncoderFactory;
 import org.apache.james.imap.main.DefaultImapDecoderFactory;
 import org.apache.james.imap.processor.main.DefaultImapProcessorFactory;
 import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
 import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
index db1c7d8..0b5a933 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
@@ -33,10 +33,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventBus;
 import org.apache.james.events.EventListener;
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.events.MailboxEvents.Expunged;
-import org.apache.james.events.MailboxEvents.FlagsUpdated;
-import org.apache.james.events.MailboxIdRegistrationKey;
 import org.apache.james.events.Registration;
 import org.apache.james.imap.api.ImapConfiguration;
 import org.apache.james.imap.api.ImapSessionState;
@@ -50,6 +46,10 @@ import org.apache.james.imap.api.process.SelectedMailbox;
 import org.apache.james.imap.message.request.IdleRequest;
 import org.apache.james.imap.message.response.ContinuationResponse;
 import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
+import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.util.MDCBuilder;
 import org.apache.james.util.concurrent.NamedThreadFactory;
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java
index 7ff20c7..8b8989d 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java
@@ -39,13 +39,6 @@ import javax.mail.Flags.Flag;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventBus;
 import org.apache.james.events.EventListener;
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.events.MailboxEvents.Expunged;
-import org.apache.james.events.MailboxEvents.FlagsUpdated;
-import org.apache.james.events.MailboxEvents.MailboxDeletion;
-import org.apache.james.events.MailboxEvents.MailboxEvent;
-import org.apache.james.events.MailboxEvents.MessageEvent;
-import org.apache.james.events.MailboxIdRegistrationKey;
 import org.apache.james.events.Registration;
 import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.api.process.SelectedMailbox;
@@ -55,6 +48,13 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.NullableMessageSequenceNumber;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxEvent;
+import org.apache.james.mailbox.events.MailboxEvents.MessageEvent;
+import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/processor/base/MailboxEventAnalyserTest.java b/protocols/imap/src/test/java/org/apache/james/imap/processor/base/MailboxEventAnalyserTest.java
index 3bb17a5..4eae25b 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/processor/base/MailboxEventAnalyserTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/processor/base/MailboxEventAnalyserTest.java
@@ -33,10 +33,6 @@ import org.apache.james.core.Username;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventBusTestFixture;
 import org.apache.james.events.InVMEventBus;
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.events.MailboxEvents.FlagsUpdated;
-import org.apache.james.events.MailboxEvents.MailboxAdded;
-import org.apache.james.events.MailboxEvents.MailboxEvent;
 import org.apache.james.events.MemoryEventDeadLetters;
 import org.apache.james.events.delivery.InVmEventDelivery;
 import org.apache.james.imap.encode.FakeImapSession;
@@ -46,6 +42,10 @@ import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxEvent;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxId;
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/processor/base/SelectedMailboxImplTest.java b/protocols/imap/src/test/java/org/apache/james/imap/processor/base/SelectedMailboxImplTest.java
index 30a1e71..a38aa36 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/processor/base/SelectedMailboxImplTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/processor/base/SelectedMailboxImplTest.java
@@ -44,8 +44,6 @@ import org.apache.james.core.Username;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventBus;
 import org.apache.james.events.EventListener;
-import org.apache.james.events.MailboxEvents.FlagsUpdated;
-import org.apache.james.events.MailboxIdRegistrationKey;
 import org.apache.james.events.Registration;
 import org.apache.james.imap.encode.FakeImapSession;
 import org.apache.james.imap.processor.base.SelectedMailboxImpl.ApplicableFlags;
@@ -56,6 +54,8 @@ import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
+import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageMetaData;
diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java
index 3b83a14..8dc2e5e 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java
@@ -25,10 +25,10 @@ import org.apache.james.events.EventBus;
 import org.apache.james.events.EventBusId;
 import org.apache.james.events.EventSerializer;
 import org.apache.james.events.KeyReconnectionHandler;
-import org.apache.james.events.MailboxIdRegistrationKey;
 import org.apache.james.events.RabbitMQEventBus;
 import org.apache.james.events.RegistrationKey;
 import org.apache.james.events.RetryBackoffConfiguration;
+import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.utils.InitializationOperation;
 import org.apache.james.utils.InitilizationOperationBuilder;
 
diff --git a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/change/EmailChange.java b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/change/EmailChange.java
index b5ba2d6..375899d 100644
--- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/change/EmailChange.java
+++ b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/change/EmailChange.java
@@ -27,10 +27,10 @@ import java.util.stream.Stream;
 
 import javax.inject.Inject;
 
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.events.MailboxEvents.Expunged;
-import org.apache.james.events.MailboxEvents.FlagsUpdated;
 import org.apache.james.jmap.api.model.AccountId;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
 import org.apache.james.mailbox.model.MessageId;
 
 import com.github.steveash.guavate.Guavate;
diff --git a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/change/MailboxChange.java b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/change/MailboxChange.java
index fb02b5c..c1deef5 100644
--- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/change/MailboxChange.java
+++ b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/change/MailboxChange.java
@@ -28,14 +28,14 @@ import java.util.stream.Stream;
 import javax.inject.Inject;
 import javax.mail.Flags;
 
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.events.MailboxEvents.Expunged;
-import org.apache.james.events.MailboxEvents.FlagsUpdated;
-import org.apache.james.events.MailboxEvents.MailboxACLUpdated;
-import org.apache.james.events.MailboxEvents.MailboxAdded;
-import org.apache.james.events.MailboxEvents.MailboxDeletion;
-import org.apache.james.events.MailboxEvents.MailboxRenamed;
 import org.apache.james.jmap.api.model.AccountId;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxACLUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxRenamed;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxId;
 
diff --git a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
index 57de2c9..c283f23 100644
--- a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
+++ b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
@@ -79,7 +79,6 @@ import org.apache.james.core.Domain;
 import org.apache.james.core.Username;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.events.Event;
-import org.apache.james.events.MailboxEvents.Added;
 import org.apache.james.jmap.AccessToken;
 import org.apache.james.jmap.HttpJmapAuthentication;
 import org.apache.james.jmap.JmapCommonRequests;
@@ -90,6 +89,7 @@ import org.apache.james.junit.categories.BasicFeature;
 import org.apache.james.mailbox.DefaultMailboxes;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.Role;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.AttachmentMetadata;
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/ComputeMessageFastViewProjectionListener.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/ComputeMessageFastViewProjectionListener.java
index aec0560..a098304 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/ComputeMessageFastViewProjectionListener.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/ComputeMessageFastViewProjectionListener.java
@@ -29,12 +29,12 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventListener;
 import org.apache.james.events.Group;
-import org.apache.james.events.MailboxEvents.Added;
 import org.apache.james.jmap.api.projections.MessageFastViewPrecomputedProperties;
 import org.apache.james.jmap.api.projections.MessageFastViewProjection;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.SessionProvider;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.FetchGroup;
 import org.apache.james.mailbox.model.MessageResult;
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/PopulateEmailQueryViewListener.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/PopulateEmailQueryViewListener.java
index a14c163..8dbf751 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/PopulateEmailQueryViewListener.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/PopulateEmailQueryViewListener.java
@@ -29,13 +29,13 @@ import javax.inject.Inject;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventListener.ReactiveGroupEventListener;
 import org.apache.james.events.Group;
-import org.apache.james.events.MailboxEvents.Added;
-import org.apache.james.events.MailboxEvents.Expunged;
-import org.apache.james.events.MailboxEvents.MailboxDeletion;
 import org.apache.james.jmap.api.projections.EmailQueryView;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.SessionProvider;
+import org.apache.james.mailbox.events.MailboxEvents.Added;
+import org.apache.james.mailbox.events.MailboxEvents.Expunged;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.FetchGroup;
 import org.apache.james.mailbox.model.MessageId;
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/PropagateLookupRightListener.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/PropagateLookupRightListener.java
index d39e5a6..e359ee7 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/PropagateLookupRightListener.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/PropagateLookupRightListener.java
@@ -27,12 +27,12 @@ import javax.inject.Inject;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventListener;
 import org.apache.james.events.Group;
-import org.apache.james.events.MailboxEvents.MailboxACLUpdated;
-import org.apache.james.events.MailboxEvents.MailboxRenamed;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.RightManager;
 import org.apache.james.mailbox.acl.ACLDiff;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxACLUpdated;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxRenamed;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxACL.Entry;
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/change/MailboxChangeListener.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/change/MailboxChangeListener.scala
index 8b9f44c..1f6986c 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/change/MailboxChangeListener.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/change/MailboxChangeListener.scala
@@ -24,11 +24,11 @@ import java.time.{Clock, ZonedDateTime}
 import javax.inject.Inject
 import org.apache.james.core.Username
 import org.apache.james.events.EventListener.ReactiveGroupEventListener
-import org.apache.james.events.MailboxEvents.{Added, Expunged, FlagsUpdated, MailboxACLUpdated, MailboxAdded, MailboxDeletion, MailboxEvent, MailboxRenamed}
 import org.apache.james.events.{Event, Group}
 import org.apache.james.jmap.api.change.{EmailChange, EmailChangeRepository, JmapChange, MailboxChange, MailboxChangeRepository}
 import org.apache.james.jmap.api.model.AccountId
 import org.apache.james.jmap.change.MailboxChangeListener.LOGGER
+import org.apache.james.mailbox.events.MailboxEvents.{Added, Expunged, FlagsUpdated, MailboxACLUpdated, MailboxAdded, MailboxDeletion, MailboxEvent, MailboxRenamed}
 import org.apache.james.mailbox.exception.MailboxException
 import org.apache.james.mailbox.model.{MailboxACL, MailboxId}
 import org.apache.james.mailbox.{MailboxManager, MailboxSession}
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerTaskSerializationIntegrationTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerTaskSerializationIntegrationTest.java
index 6f4d53e..b20b6c0 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerTaskSerializationIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerTaskSerializationIntegrationTest.java
@@ -52,10 +52,10 @@ import org.apache.james.core.builder.MimeMessageBuilder;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventDeadLetters;
 import org.apache.james.events.Group;
-import org.apache.james.events.MailboxEvents.MailboxAdded;
 import org.apache.james.junit.categories.BasicFeature;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.events.GenericGroup;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
 import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.MailboxConstants;
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/EventDeadLettersRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/EventDeadLettersRoutesTest.java
index 84366e8..e0eb519 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/EventDeadLettersRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/EventDeadLettersRoutesTest.java
@@ -39,12 +39,12 @@ import org.apache.james.events.EventBusTestFixture;
 import org.apache.james.events.EventDeadLetters;
 import org.apache.james.events.Group;
 import org.apache.james.events.InVMEventBus;
-import org.apache.james.events.MailboxEvents.MailboxAdded;
 import org.apache.james.events.MemoryEventDeadLetters;
 import org.apache.james.events.RetryBackoffConfiguration;
 import org.apache.james.events.delivery.InVmEventDelivery;
 import org.apache.james.json.DTOConverter;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.events.MailboxEvents.MailboxAdded;
 import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
 import org.apache.james.mailbox.model.MailboxPath;


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


[james-project] 12/18: JAMES-3498 Compilation fix: depend on event-bus-api test-jar

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 7528019427bc2531b9e2afec1c13dd23c8767267
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 25 17:25:26 2021 +0700

    JAMES-3498 Compilation fix: depend on event-bus-api test-jar
---
 examples/custom-listeners/pom.xml                              |  7 +++++++
 mailbox/backup/pom.xml                                         |  6 ++++++
 mailbox/cassandra/pom.xml                                      |  6 ++++++
 mailbox/elasticsearch/pom.xml                                  |  6 ++++++
 mailbox/jpa/pom.xml                                            |  6 ++++++
 mailbox/lucene/pom.xml                                         |  6 ++++++
 mailbox/memory/pom.xml                                         |  6 ++++++
 mailbox/plugin/deleted-messages-vault-cassandra/pom.xml        |  6 ++++++
 mailbox/plugin/deleted-messages-vault/pom.xml                  |  7 +++++++
 mailbox/plugin/quota-mailing-cassandra/pom.xml                 |  6 ++++++
 mailbox/plugin/quota-mailing-memory/pom.xml                    |  6 ++++++
 mailbox/plugin/quota-mailing/pom.xml                           |  6 ++++++
 mailbox/plugin/quota-search-elasticsearch/pom.xml              |  6 ++++++
 mailbox/plugin/quota-search-scanning/pom.xml                   |  6 ++++++
 mailbox/plugin/quota-search/pom.xml                            |  6 ++++++
 mailbox/plugin/spamassassin/pom.xml                            |  6 ++++++
 mailbox/scanning-search/pom.xml                                |  6 ++++++
 mailbox/tools/copier/pom.xml                                   |  6 ++++++
 mailbox/tools/indexer/pom.xml                                  |  6 ++++++
 mpt/impl/imap-mailbox/cassandra/pom.xml                        |  6 ++++++
 mpt/impl/imap-mailbox/elasticsearch/pom.xml                    |  6 ++++++
 mpt/impl/imap-mailbox/inmemory/pom.xml                         |  6 ++++++
 mpt/impl/imap-mailbox/jpa/pom.xml                              |  6 ++++++
 mpt/impl/imap-mailbox/lucenesearch/pom.xml                     |  6 ++++++
 mpt/impl/imap-mailbox/maildir/pom.xml                          |  6 ++++++
 mpt/impl/imap-mailbox/rabbitmq/pom.xml                         | 10 ++++++++++
 server/container/guice/mailbox/pom.xml                         | 10 ++++++++++
 server/container/mailbox-jmx/pom.xml                           |  6 ++++++
 server/mailet/mailets/pom.xml                                  |  6 ++++++
 server/protocols/jmap-draft/pom.xml                            |  6 ++++++
 server/protocols/jmap-rfc-8621/pom.xml                         |  6 ++++++
 server/protocols/protocols-pop3/pom.xml                        |  7 +++++++
 server/protocols/webadmin/webadmin-jmap/pom.xml                |  6 ++++++
 .../webadmin/webadmin-mailbox-deleted-message-vault/pom.xml    |  6 ++++++
 server/protocols/webadmin/webadmin-mailbox/pom.xml             |  6 ++++++
 35 files changed, 221 insertions(+)

diff --git a/examples/custom-listeners/pom.xml b/examples/custom-listeners/pom.xml
index a76b3f6..48359f3 100644
--- a/examples/custom-listeners/pom.xml
+++ b/examples/custom-listeners/pom.xml
@@ -57,6 +57,13 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <version>${james.baseVersion}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>metrics-tests</artifactId>
             <version>${james.baseVersion}</version>
             <scope>test</scope>
diff --git a/mailbox/backup/pom.xml b/mailbox/backup/pom.xml
index 9f1cf45..854b934 100644
--- a/mailbox/backup/pom.xml
+++ b/mailbox/backup/pom.xml
@@ -56,6 +56,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-server-testing</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mailbox/cassandra/pom.xml b/mailbox/cassandra/pom.xml
index f596178..cfbf60a 100644
--- a/mailbox/cassandra/pom.xml
+++ b/mailbox/cassandra/pom.xml
@@ -84,6 +84,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-in-vm</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mailbox/elasticsearch/pom.xml b/mailbox/elasticsearch/pom.xml
index f4b06b7..c52c8bd 100644
--- a/mailbox/elasticsearch/pom.xml
+++ b/mailbox/elasticsearch/pom.xml
@@ -86,6 +86,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-in-vm</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mailbox/jpa/pom.xml b/mailbox/jpa/pom.xml
index a063405..3a61146 100644
--- a/mailbox/jpa/pom.xml
+++ b/mailbox/jpa/pom.xml
@@ -75,6 +75,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-in-vm</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mailbox/lucene/pom.xml b/mailbox/lucene/pom.xml
index bc59f6a..badf286 100644
--- a/mailbox/lucene/pom.xml
+++ b/mailbox/lucene/pom.xml
@@ -65,6 +65,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-in-vm</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mailbox/memory/pom.xml b/mailbox/memory/pom.xml
index 20eb170..3a78ac7 100644
--- a/mailbox/memory/pom.xml
+++ b/mailbox/memory/pom.xml
@@ -65,6 +65,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-server-data-memory</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mailbox/plugin/deleted-messages-vault-cassandra/pom.xml b/mailbox/plugin/deleted-messages-vault-cassandra/pom.xml
index db1e6a6..66861fa 100644
--- a/mailbox/plugin/deleted-messages-vault-cassandra/pom.xml
+++ b/mailbox/plugin/deleted-messages-vault-cassandra/pom.xml
@@ -71,6 +71,12 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
             <scope>test</scope>
diff --git a/mailbox/plugin/deleted-messages-vault/pom.xml b/mailbox/plugin/deleted-messages-vault/pom.xml
index 69222ab..54672cd 100644
--- a/mailbox/plugin/deleted-messages-vault/pom.xml
+++ b/mailbox/plugin/deleted-messages-vault/pom.xml
@@ -85,6 +85,13 @@
             <artifactId>blob-memory</artifactId>
             <scope>test</scope>
         </dependency>
+
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
             <artifactId>james-server-core</artifactId>
diff --git a/mailbox/plugin/quota-mailing-cassandra/pom.xml b/mailbox/plugin/quota-mailing-cassandra/pom.xml
index 91e1616..d23df63 100644
--- a/mailbox/plugin/quota-mailing-cassandra/pom.xml
+++ b/mailbox/plugin/quota-mailing-cassandra/pom.xml
@@ -70,6 +70,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-sourcing-core</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mailbox/plugin/quota-mailing-memory/pom.xml b/mailbox/plugin/quota-mailing-memory/pom.xml
index 26fa21a..f5f064f 100644
--- a/mailbox/plugin/quota-mailing-memory/pom.xml
+++ b/mailbox/plugin/quota-mailing-memory/pom.xml
@@ -66,6 +66,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-sourcing-core</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mailbox/plugin/quota-mailing/pom.xml b/mailbox/plugin/quota-mailing/pom.xml
index 64dc33d..bae4953 100644
--- a/mailbox/plugin/quota-mailing/pom.xml
+++ b/mailbox/plugin/quota-mailing/pom.xml
@@ -58,6 +58,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-in-vm</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mailbox/plugin/quota-search-elasticsearch/pom.xml b/mailbox/plugin/quota-search-elasticsearch/pom.xml
index ada1865..cfe9651 100644
--- a/mailbox/plugin/quota-search-elasticsearch/pom.xml
+++ b/mailbox/plugin/quota-search-elasticsearch/pom.xml
@@ -75,6 +75,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-core</artifactId>
             <type>test-jar</type>
             <scope>test</scope>
diff --git a/mailbox/plugin/quota-search-scanning/pom.xml b/mailbox/plugin/quota-search-scanning/pom.xml
index ac4c6b9..36c278a 100644
--- a/mailbox/plugin/quota-search-scanning/pom.xml
+++ b/mailbox/plugin/quota-search-scanning/pom.xml
@@ -61,6 +61,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-core</artifactId>
             <type>test-jar</type>
             <scope>test</scope>
diff --git a/mailbox/plugin/quota-search/pom.xml b/mailbox/plugin/quota-search/pom.xml
index 40a67de..fc808c0 100644
--- a/mailbox/plugin/quota-search/pom.xml
+++ b/mailbox/plugin/quota-search/pom.xml
@@ -49,6 +49,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-core</artifactId>
         </dependency>
         <dependency>
diff --git a/mailbox/plugin/spamassassin/pom.xml b/mailbox/plugin/spamassassin/pom.xml
index 0985acf..43b9952 100644
--- a/mailbox/plugin/spamassassin/pom.xml
+++ b/mailbox/plugin/spamassassin/pom.xml
@@ -69,6 +69,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>metrics-tests</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mailbox/scanning-search/pom.xml b/mailbox/scanning-search/pom.xml
index 235dc75..76b4054 100644
--- a/mailbox/scanning-search/pom.xml
+++ b/mailbox/scanning-search/pom.xml
@@ -65,6 +65,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>metrics-tests</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mailbox/tools/copier/pom.xml b/mailbox/tools/copier/pom.xml
index 0296205..bfd40a1 100644
--- a/mailbox/tools/copier/pom.xml
+++ b/mailbox/tools/copier/pom.xml
@@ -58,6 +58,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>metrics-tests</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mailbox/tools/indexer/pom.xml b/mailbox/tools/indexer/pom.xml
index 5e8b498..a34f43c 100644
--- a/mailbox/tools/indexer/pom.xml
+++ b/mailbox/tools/indexer/pom.xml
@@ -86,6 +86,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-json</artifactId>
             <type>test-jar</type>
             <scope>test</scope>
diff --git a/mpt/impl/imap-mailbox/cassandra/pom.xml b/mpt/impl/imap-mailbox/cassandra/pom.xml
index 47630d5..a2753cf 100644
--- a/mpt/impl/imap-mailbox/cassandra/pom.xml
+++ b/mpt/impl/imap-mailbox/cassandra/pom.xml
@@ -67,6 +67,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-in-vm</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mpt/impl/imap-mailbox/elasticsearch/pom.xml b/mpt/impl/imap-mailbox/elasticsearch/pom.xml
index b3e8c4a..7b6fc3a 100644
--- a/mpt/impl/imap-mailbox/elasticsearch/pom.xml
+++ b/mpt/impl/imap-mailbox/elasticsearch/pom.xml
@@ -73,6 +73,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-in-vm</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mpt/impl/imap-mailbox/inmemory/pom.xml b/mpt/impl/imap-mailbox/inmemory/pom.xml
index 0b15aca..0edd035 100644
--- a/mpt/impl/imap-mailbox/inmemory/pom.xml
+++ b/mpt/impl/imap-mailbox/inmemory/pom.xml
@@ -54,6 +54,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>metrics-tests</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mpt/impl/imap-mailbox/jpa/pom.xml b/mpt/impl/imap-mailbox/jpa/pom.xml
index ee202b7..77e815a 100644
--- a/mpt/impl/imap-mailbox/jpa/pom.xml
+++ b/mpt/impl/imap-mailbox/jpa/pom.xml
@@ -65,6 +65,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-in-vm</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mpt/impl/imap-mailbox/lucenesearch/pom.xml b/mpt/impl/imap-mailbox/lucenesearch/pom.xml
index 31f8d87..0111b39 100644
--- a/mpt/impl/imap-mailbox/lucenesearch/pom.xml
+++ b/mpt/impl/imap-mailbox/lucenesearch/pom.xml
@@ -68,6 +68,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-in-vm</artifactId>
         </dependency>
         <dependency>
diff --git a/mpt/impl/imap-mailbox/maildir/pom.xml b/mpt/impl/imap-mailbox/maildir/pom.xml
index 3d5e78d..f9293bd 100644
--- a/mpt/impl/imap-mailbox/maildir/pom.xml
+++ b/mpt/impl/imap-mailbox/maildir/pom.xml
@@ -48,6 +48,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-in-vm</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/mpt/impl/imap-mailbox/rabbitmq/pom.xml b/mpt/impl/imap-mailbox/rabbitmq/pom.xml
index e2332fd..2a9a2a4 100644
--- a/mpt/impl/imap-mailbox/rabbitmq/pom.xml
+++ b/mpt/impl/imap-mailbox/rabbitmq/pom.xml
@@ -44,6 +44,10 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>apache-james-mailbox-event-json</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>apache-james-mailbox-memory</artifactId>
             <scope>test</scope>
         </dependency>
@@ -59,6 +63,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-distributed</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/server/container/guice/mailbox/pom.xml b/server/container/guice/mailbox/pom.xml
index c64be19..18fef20 100644
--- a/server/container/guice/mailbox/pom.xml
+++ b/server/container/guice/mailbox/pom.xml
@@ -44,6 +44,10 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>apache-james-mailbox-event-json</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>apache-james-mailbox-store</artifactId>
         </dependency>
         <dependency>
@@ -52,6 +56,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-in-vm</artifactId>
         </dependency>
         <dependency>
diff --git a/server/container/mailbox-jmx/pom.xml b/server/container/mailbox-jmx/pom.xml
index 1c1aba1..eb436ca 100644
--- a/server/container/mailbox-jmx/pom.xml
+++ b/server/container/mailbox-jmx/pom.xml
@@ -56,6 +56,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-server-task-memory</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/server/mailet/mailets/pom.xml b/server/mailet/mailets/pom.xml
index 7926369..67680ef 100644
--- a/server/mailet/mailets/pom.xml
+++ b/server/mailet/mailets/pom.xml
@@ -90,6 +90,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-mdn</artifactId>
         </dependency>
         <dependency>
diff --git a/server/protocols/jmap-draft/pom.xml b/server/protocols/jmap-draft/pom.xml
index 9da08e2..c0ed85f 100644
--- a/server/protocols/jmap-draft/pom.xml
+++ b/server/protocols/jmap-draft/pom.xml
@@ -65,6 +65,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-sourcing-event-store-memory</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/server/protocols/jmap-rfc-8621/pom.xml b/server/protocols/jmap-rfc-8621/pom.xml
index c8ae1da..6d700c2 100644
--- a/server/protocols/jmap-rfc-8621/pom.xml
+++ b/server/protocols/jmap-rfc-8621/pom.xml
@@ -55,6 +55,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-core</artifactId>
         </dependency>
         <dependency>
diff --git a/server/protocols/protocols-pop3/pom.xml b/server/protocols/protocols-pop3/pom.xml
index 96a0ec8..2c2e801 100644
--- a/server/protocols/protocols-pop3/pom.xml
+++ b/server/protocols/protocols-pop3/pom.xml
@@ -59,6 +59,13 @@
             <artifactId>apache-james-mailbox-store</artifactId>
             <scope>test</scope>
         </dependency>
+
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
             <artifactId>james-server-data-api</artifactId>
diff --git a/server/protocols/webadmin/webadmin-jmap/pom.xml b/server/protocols/webadmin/webadmin-jmap/pom.xml
index 2a09cb0..5155bd2 100644
--- a/server/protocols/webadmin/webadmin-jmap/pom.xml
+++ b/server/protocols/webadmin/webadmin-jmap/pom.xml
@@ -33,6 +33,12 @@
     <dependencies>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-json</artifactId>
             <type>test-jar</type>
             <scope>test</scope>
diff --git a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/pom.xml b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/pom.xml
index d175379..3caae80 100644
--- a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/pom.xml
+++ b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/pom.xml
@@ -84,6 +84,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-json</artifactId>
             <type>test-jar</type>
             <scope>test</scope>
diff --git a/server/protocols/webadmin/webadmin-mailbox/pom.xml b/server/protocols/webadmin/webadmin-mailbox/pom.xml
index 6f229e1..ba61107 100644
--- a/server/protocols/webadmin/webadmin-mailbox/pom.xml
+++ b/server/protocols/webadmin/webadmin-mailbox/pom.xml
@@ -132,6 +132,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>event-bus-in-vm</artifactId>
             <scope>test</scope>
         </dependency>


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