You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2019/01/09 03:01:13 UTC

[3/3] james-project git commit: MAILBOX-366 Events should carry an EventId

MAILBOX-366 Events should carry an EventId


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

Branch: refs/heads/master
Commit: 60919d8591622d2f53365cdb2d2db5138e6a7065
Parents: a4533f0
Author: Benoit Tellier <bt...@linagora.com>
Authored: Tue Dec 25 08:43:23 2018 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Tue Jan 8 15:43:14 2019 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/mailbox/Event.java    |   2 +
 .../apache/james/mailbox/MailboxListener.java   |  96 +++++++++------
 .../apache/james/mailbox/MessageMoveEvent.java  |  24 +++-
 .../james/mailbox/MailboxListenerTest.java      |  36 +++---
 .../james/mailbox/events/EventBusContract.java  |  11 +-
 .../james/event/json/EventSerializer.scala      |  54 ++++++---
 .../event/json/AddedSerializationTest.java      |  45 ++++++-
 .../event/json/ExpungedSerializationTest.java   |  34 +++++-
 .../json/FlagsUpdatedSerializationTest.java     |  30 ++++-
 ...MailboxACLUpdatedEventSerializationTest.java |  31 ++++-
 .../json/MailboxAddedSerializationTest.java     |  26 ++++-
 .../json/MailboxDeletionSerializationTest.java  |  33 +++++-
 .../json/MailboxRenamedSerializationTest.java   |  34 +++++-
 .../json/MessageMoveEventSerializationTest.java |  33 ++++++
 ...QuotaUsageUpdatedEventSerializationTest.java |  14 ++-
 .../james/event/json/SerializerFixture.java     |   5 +
 .../james/event/json/dtos/EventIdTest.java      |  65 +++++++++++
 .../QuotaThresholdConfigurationChangesTest.java | 105 ++++++-----------
 .../QuotaThresholdMailingIntegrationTest.java   | 117 ++++++-------------
 .../ElasticSearchQuotaMailboxListenerTest.java  |   2 +
 .../json/QuotaRatioToElasticSearchJsonTest.java |   5 +-
 .../spamassassin/SpamAssassinListenerTest.java  |   2 +
 .../mailbox/store/StoreMailboxManager.java      |   4 +
 .../mailbox/store/StoreMessageIdManager.java    |   4 +
 .../mailbox/store/StoreMessageManager.java      |   6 +
 .../james/mailbox/store/StoreRightManager.java  |   2 +
 .../james/mailbox/store/event/EventFactory.java |  82 ++++++++-----
 .../quota/ListeningCurrentQuotaUpdater.java     |   2 +
 .../store/MessageIdManagerTestSystem.java       |   1 +
 .../DefaultDelegatingMailboxListenerTest.java   |  25 ++--
 .../event/MailboxAnnotationListenerTest.java    |   4 +-
 .../base/MailboxEventAnalyserTest.java          |  10 +-
 .../processor/base/SelectedMailboxImplTest.java |   1 +
 33 files changed, 660 insertions(+), 285 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/60919d85/mailbox/api/src/main/java/org/apache/james/mailbox/Event.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/Event.java b/mailbox/api/src/main/java/org/apache/james/mailbox/Event.java
index 8658653..bb26f1e 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/Event.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/Event.java
@@ -78,4 +78,6 @@ public interface Event {
     User getUser();
 
     boolean isNoop();
+
+    EventId getEventId();
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/60919d85/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxListener.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxListener.java b/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxListener.java
index 9e66023..7eb3709 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxListener.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxListener.java
@@ -77,13 +77,15 @@ public interface MailboxListener {
     }
 
     class QuotaUsageUpdatedEvent implements QuotaEvent {
+        private final EventId eventId;
         private final User user;
         private final QuotaRoot quotaRoot;
         private final Quota<QuotaCount> countQuota;
         private final Quota<QuotaSize> sizeQuota;
         private final Instant instant;
 
-        public QuotaUsageUpdatedEvent(User user, QuotaRoot quotaRoot, Quota<QuotaCount> countQuota, Quota<QuotaSize> sizeQuota, Instant instant) {
+        public QuotaUsageUpdatedEvent(EventId eventId, User user, QuotaRoot quotaRoot, Quota<QuotaCount> countQuota, Quota<QuotaSize> sizeQuota, Instant instant) {
+            this.eventId = eventId;
             this.user = user;
             this.quotaRoot = quotaRoot;
             this.countQuota = countQuota;
@@ -119,11 +121,17 @@ public interface MailboxListener {
         }
 
         @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.user, that.user)
+                return Objects.equals(this.eventId, that.eventId)
+                    && Objects.equals(this.user, that.user)
                     && Objects.equals(this.quotaRoot, that.quotaRoot)
                     && Objects.equals(this.countQuota, that.countQuota)
                     && Objects.equals(this.sizeQuota, that.sizeQuota)
@@ -134,7 +142,7 @@ public interface MailboxListener {
 
         @Override
         public final int hashCode() {
-            return Objects.hash(user, quotaRoot, countQuota, sizeQuota, instant);
+            return Objects.hash(eventId, user, quotaRoot, countQuota, sizeQuota, instant);
         }
 
     }
@@ -147,12 +155,14 @@ public interface MailboxListener {
         protected final MailboxId mailboxId;
         protected final User user;
         protected final MailboxSession.SessionId sessionId;
+        protected final EventId eventId;
 
-        public MailboxEvent(MailboxSession.SessionId sessionId, User user, MailboxPath path, MailboxId mailboxId) {
+        public MailboxEvent(MailboxSession.SessionId sessionId, User user, MailboxPath path, MailboxId mailboxId, EventId eventId) {
             this.user = user;
             this.path = path;
             this.mailboxId = mailboxId;
             this.sessionId = sessionId;
+            this.eventId = eventId;
         }
 
         /**
@@ -166,6 +176,11 @@ public interface MailboxListener {
             return user;
         }
 
+        @Override
+        public EventId getEventId() {
+            return eventId;
+        }
+
         /**
          * Gets the sessionId in which's context the {@link MailboxEvent}
          * happened
@@ -204,8 +219,8 @@ public interface MailboxListener {
         private final QuotaSize totalDeletedSize;
 
         public MailboxDeletion(MailboxSession.SessionId sessionId, User user, MailboxPath path, QuotaRoot quotaRoot, QuotaCount deletedMessageCount, QuotaSize totalDeletedSize,
-                               MailboxId mailboxId) {
-            super(sessionId, user, path, mailboxId);
+                               MailboxId mailboxId, EventId eventId) {
+            super(sessionId, user, path, mailboxId, eventId);
             this.quotaRoot = quotaRoot;
             this.deletedMessageCount = deletedMessageCount;
             this.totalDeletedSize = totalDeletedSize;
@@ -233,7 +248,8 @@ public interface MailboxListener {
             if (o instanceof MailboxDeletion) {
                 MailboxDeletion that = (MailboxDeletion) o;
 
-                return Objects.equals(this.sessionId, that.sessionId)
+                return Objects.equals(this.eventId, that.eventId)
+                    && Objects.equals(this.sessionId, that.sessionId)
                     && Objects.equals(this.user, that.user)
                     && Objects.equals(this.path, that.path)
                     && Objects.equals(this.mailboxId, that.mailboxId)
@@ -246,7 +262,7 @@ public interface MailboxListener {
 
         @Override
         public final int hashCode() {
-            return Objects.hash(sessionId, user, path, mailboxId, quotaRoot, deletedMessageCount, totalDeletedSize);
+            return Objects.hash(eventId, sessionId, user, path, mailboxId, quotaRoot, deletedMessageCount, totalDeletedSize);
         }
     }
 
@@ -255,8 +271,8 @@ public interface MailboxListener {
      */
     class MailboxAdded extends MailboxEvent {
 
-        public MailboxAdded(MailboxSession.SessionId sessionId, User user, MailboxPath path, MailboxId mailboxId) {
-            super(sessionId, user, path, mailboxId);
+        public MailboxAdded(MailboxSession.SessionId sessionId, User user, MailboxPath path, MailboxId mailboxId, EventId eventId) {
+            super(sessionId, user, path, mailboxId, eventId);
         }
 
         @Override
@@ -269,7 +285,8 @@ public interface MailboxListener {
             if (o instanceof MailboxAdded) {
                 MailboxAdded that = (MailboxAdded) o;
 
-                return Objects.equals(this.sessionId, that.sessionId)
+                return Objects.equals(this.eventId, that.eventId)
+                    && Objects.equals(this.sessionId, that.sessionId)
                     && Objects.equals(this.user, that.user)
                     && Objects.equals(this.path, that.path)
                     && Objects.equals(this.mailboxId, that.mailboxId);
@@ -279,7 +296,7 @@ public interface MailboxListener {
 
         @Override
         public final int hashCode() {
-            return Objects.hash(sessionId, user, path, mailboxId);
+            return Objects.hash(eventId, sessionId, user, path, mailboxId);
         }
     }
 
@@ -289,8 +306,8 @@ public interface MailboxListener {
     class MailboxRenamed extends MailboxEvent {
         private final MailboxPath newPath;
 
-        public MailboxRenamed(MailboxSession.SessionId sessionId, User user, MailboxPath path, MailboxId mailboxId, MailboxPath newPath) {
-            super(sessionId, user, path, mailboxId);
+        public MailboxRenamed(MailboxSession.SessionId sessionId, User user, MailboxPath path, MailboxId mailboxId, MailboxPath newPath, EventId eventId) {
+            super(sessionId, user, path, mailboxId, eventId);
             this.newPath = newPath;
         }
 
@@ -313,7 +330,8 @@ public interface MailboxListener {
             if (o instanceof MailboxRenamed) {
                 MailboxRenamed that = (MailboxRenamed) o;
 
-                return Objects.equals(this.sessionId, that.sessionId)
+                return Objects.equals(this.eventId, that.eventId)
+                    && Objects.equals(this.sessionId, that.sessionId)
                     && Objects.equals(this.user, that.user)
                     && Objects.equals(this.path, that.path)
                     && Objects.equals(this.mailboxId, that.mailboxId)
@@ -324,7 +342,7 @@ public interface MailboxListener {
 
         @Override
         public final int hashCode() {
-            return Objects.hash(sessionId, user, path, mailboxId, newPath);
+            return Objects.hash(eventId, sessionId, user, path, mailboxId, newPath);
         }
     }
 
@@ -335,8 +353,8 @@ public interface MailboxListener {
     class MailboxACLUpdated extends MailboxEvent {
         private final ACLDiff aclDiff;
 
-        public MailboxACLUpdated(MailboxSession.SessionId sessionId, User user, MailboxPath path, ACLDiff aclDiff, MailboxId mailboxId) {
-            super(sessionId, user, path, mailboxId);
+        public MailboxACLUpdated(MailboxSession.SessionId sessionId, User user, MailboxPath path, ACLDiff aclDiff, MailboxId mailboxId, EventId eventId) {
+            super(sessionId, user, path, mailboxId, eventId);
             this.aclDiff = aclDiff;
         }
 
@@ -354,7 +372,8 @@ public interface MailboxListener {
             if (o instanceof MailboxACLUpdated) {
                 MailboxACLUpdated that = (MailboxACLUpdated) o;
 
-                return Objects.equals(this.sessionId, that.sessionId)
+                return Objects.equals(this.eventId, that.eventId)
+                    && Objects.equals(this.sessionId, that.sessionId)
                     && Objects.equals(this.user, that.user)
                     && Objects.equals(this.path, that.path)
                     && Objects.equals(this.aclDiff, that.aclDiff)
@@ -365,7 +384,7 @@ public interface MailboxListener {
 
         @Override
         public final int hashCode() {
-            return Objects.hash(sessionId, user, path, aclDiff, mailboxId);
+            return Objects.hash(eventId, sessionId, user, path, aclDiff, mailboxId);
         }
 
     }
@@ -375,8 +394,8 @@ public interface MailboxListener {
      */
     abstract class MessageEvent extends MailboxEvent {
 
-        public MessageEvent(MailboxSession.SessionId sessionId, User user, MailboxPath path, MailboxId mailboxId) {
-            super(sessionId, user, path, mailboxId);
+        public MessageEvent(MailboxSession.SessionId sessionId, User user, MailboxPath path, MailboxId mailboxId, EventId eventId) {
+            super(sessionId, user, path, mailboxId, eventId);
         }
 
         /**
@@ -389,8 +408,8 @@ public interface MailboxListener {
 
     abstract class MetaDataHoldingEvent extends MessageEvent {
 
-        public MetaDataHoldingEvent(MailboxSession.SessionId sessionId, User user, MailboxPath path, MailboxId mailboxId) {
-            super(sessionId, user, path, mailboxId);
+        public MetaDataHoldingEvent(MailboxSession.SessionId sessionId, User user, MailboxPath path, MailboxId mailboxId, EventId eventId) {
+            super(sessionId, user, path, mailboxId, eventId);
         }
 
         /**
@@ -405,8 +424,8 @@ public interface MailboxListener {
     class Expunged extends MetaDataHoldingEvent {
         private final Map<MessageUid, MessageMetaData> expunged;
 
-        public Expunged(MailboxSession.SessionId sessionId, User user, MailboxPath path, MailboxId mailboxId, Map<MessageUid, MessageMetaData> uids) {
-            super(sessionId, user, path, mailboxId);
+        public Expunged(MailboxSession.SessionId sessionId, User user, MailboxPath path, MailboxId mailboxId, Map<MessageUid, MessageMetaData> uids, EventId eventId) {
+            super(sessionId, user, path, mailboxId, eventId);
             this.expunged = ImmutableMap.copyOf(uids);
         }
 
@@ -439,7 +458,8 @@ public interface MailboxListener {
             if (o instanceof Expunged) {
                 Expunged that = (Expunged) o;
 
-                return Objects.equals(this.sessionId, that.sessionId)
+                return Objects.equals(this.eventId, that.eventId)
+                    && Objects.equals(this.sessionId, that.sessionId)
                     && Objects.equals(this.user, that.user)
                     && Objects.equals(this.path, that.path)
                     && Objects.equals(this.mailboxId, that.mailboxId)
@@ -450,7 +470,7 @@ public interface MailboxListener {
 
         @Override
         public final int hashCode() {
-            return Objects.hash(sessionId, user, path, mailboxId, expunged);
+            return Objects.hash(eventId, sessionId, user, path, mailboxId, expunged);
         }
     }
 
@@ -461,8 +481,9 @@ public interface MailboxListener {
         private final List<MessageUid> uids;
         private final List<UpdatedFlags> updatedFlags;
 
-        public FlagsUpdated(MailboxSession.SessionId sessionId, User user, MailboxPath path, MailboxId mailboxId, List<UpdatedFlags> updatedFlags) {
-            super(sessionId, user, path, mailboxId);
+        public FlagsUpdated(MailboxSession.SessionId sessionId, User user, MailboxPath path, MailboxId mailboxId, List<UpdatedFlags> updatedFlags,
+                            EventId eventId) {
+            super(sessionId, user, path, mailboxId, eventId);
             this.updatedFlags = ImmutableList.copyOf(updatedFlags);
             this.uids = updatedFlags.stream()
                 .map(UpdatedFlags::getUid)
@@ -488,7 +509,8 @@ public interface MailboxListener {
             if (o instanceof FlagsUpdated) {
                 FlagsUpdated that = (FlagsUpdated) o;
 
-                return Objects.equals(this.sessionId, that.sessionId)
+                return Objects.equals(this.eventId, that.eventId)
+                    && Objects.equals(this.sessionId, that.sessionId)
                     && Objects.equals(this.user, that.user)
                     && Objects.equals(this.path, that.path)
                     && Objects.equals(this.mailboxId, that.mailboxId)
@@ -500,7 +522,7 @@ public interface MailboxListener {
 
         @Override
         public final int hashCode() {
-            return Objects.hash(sessionId, user, path, mailboxId, uids, updatedFlags);
+            return Objects.hash(eventId, sessionId, user, path, mailboxId, uids, updatedFlags);
         }
     }
 
@@ -510,8 +532,9 @@ public interface MailboxListener {
     class Added extends MetaDataHoldingEvent {
         private final Map<MessageUid, MessageMetaData> added;
 
-        public Added(MailboxSession.SessionId sessionId, User user, MailboxPath path, MailboxId mailboxId, SortedMap<MessageUid, MessageMetaData> uids) {
-            super(sessionId, user, path, mailboxId);
+        public Added(MailboxSession.SessionId sessionId, User user, MailboxPath path, MailboxId mailboxId,
+                     SortedMap<MessageUid, MessageMetaData> uids, EventId eventId) {
+            super(sessionId, user, path, mailboxId, eventId);
             this.added = ImmutableMap.copyOf(uids);
         }
 
@@ -543,7 +566,8 @@ public interface MailboxListener {
             if (o instanceof Added) {
                 Added that = (Added) o;
 
-                return Objects.equals(this.sessionId, that.sessionId)
+                return Objects.equals(this.eventId, that.eventId)
+                    && Objects.equals(this.sessionId, that.sessionId)
                     && Objects.equals(this.user, that.user)
                     && Objects.equals(this.path, that.path)
                     && Objects.equals(this.mailboxId, that.mailboxId)
@@ -554,7 +578,7 @@ public interface MailboxListener {
 
         @Override
         public final int hashCode() {
-            return Objects.hash(sessionId, user, path, mailboxId, added);
+            return Objects.hash(eventId, sessionId, user, path, mailboxId, added);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/60919d85/mailbox/api/src/main/java/org/apache/james/mailbox/MessageMoveEvent.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/MessageMoveEvent.java b/mailbox/api/src/main/java/org/apache/james/mailbox/MessageMoveEvent.java
index e5e8e82..8b72378 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/MessageMoveEvent.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/MessageMoveEvent.java
@@ -20,6 +20,7 @@ package org.apache.james.mailbox;
 
 import java.util.Collection;
 import java.util.Objects;
+import java.util.Optional;
 
 import org.apache.james.core.User;
 import org.apache.james.mailbox.model.MailboxId;
@@ -40,9 +41,11 @@ public class MessageMoveEvent implements Event {
         private ImmutableList.Builder<MessageId> messageIds;
         private User user;
         private MessageMoves messageMoves;
+        private Optional<EventId> eventId;
 
         private Builder() {
             messageIds = ImmutableList.builder();
+            eventId = Optional.empty();
         }
 
         public Builder session(MailboxSession session) {
@@ -65,6 +68,11 @@ public class MessageMoveEvent implements Event {
             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;
@@ -74,16 +82,18 @@ public class MessageMoveEvent implements Event {
             Preconditions.checkNotNull(user, "'user' is mandatory");
             Preconditions.checkNotNull(messageMoves, "'messageMoves' is mandatory");
 
-            return new MessageMoveEvent(user, messageMoves, messageIds.build());
+            return new MessageMoveEvent(eventId.orElse(EventId.random()), user, messageMoves, messageIds.build());
         }
     }
 
+    private final EventId eventId;
     private final User user;
     private final MessageMoves messageMoves;
     private final Collection<MessageId> messageIds;
 
     @VisibleForTesting
-    MessageMoveEvent(User user, MessageMoves messageMoves, Collection<MessageId> messageIds) {
+    MessageMoveEvent(EventId eventId, User user, MessageMoves messageMoves, Collection<MessageId> messageIds) {
+        this.eventId = eventId;
         this.user = user;
         this.messageMoves = messageMoves;
         this.messageIds = messageIds;
@@ -99,6 +109,11 @@ public class MessageMoveEvent implements Event {
     }
 
     @Override
+    public EventId getEventId() {
+        return eventId;
+    }
+
+    @Override
     public User getUser() {
         return user;
     }
@@ -122,7 +137,8 @@ public class MessageMoveEvent implements Event {
         if (o instanceof MessageMoveEvent) {
             MessageMoveEvent that = (MessageMoveEvent) o;
 
-            return Objects.equals(this.user, that.user)
+            return Objects.equals(this.eventId, that.eventId)
+                && Objects.equals(this.user, that.user)
                 && Objects.equals(this.messageMoves, that.messageMoves)
                 && Objects.equals(this.messageIds, that.messageIds);
         }
@@ -131,6 +147,6 @@ public class MessageMoveEvent implements Event {
 
     @Override
     public final int hashCode() {
-        return Objects.hash(user, messageMoves, messageIds);
+        return Objects.hash(eventId, user, messageMoves, messageIds);
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/60919d85/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxListenerTest.java
----------------------------------------------------------------------
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 b91f5b0..9db71ba 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
@@ -100,21 +100,24 @@ class MailboxListenerTest {
 
     @Test
     void renameWithSameNameShouldBeNoop() {
-        MailboxListener.MailboxRenamed mailboxRenamed = new MailboxListener.MailboxRenamed(SESSION_ID, BOB, PATH, MAILBOX_ID, PATH);
+        MailboxListener.MailboxRenamed mailboxRenamed = new MailboxListener.MailboxRenamed(SESSION_ID, BOB, PATH, MAILBOX_ID, PATH,
+            Event.EventId.random());
 
         assertThat(mailboxRenamed.isNoop()).isTrue();
     }
 
     @Test
     void renameWithDifferentNameShouldNotBeNoop() {
-        MailboxListener.MailboxRenamed mailboxRenamed = new MailboxListener.MailboxRenamed(SESSION_ID, BOB, PATH, MAILBOX_ID, OTHER_PATH);
+        MailboxListener.MailboxRenamed mailboxRenamed = new MailboxListener.MailboxRenamed(SESSION_ID, BOB, PATH, MAILBOX_ID, OTHER_PATH,
+            Event.EventId.random());
 
         assertThat(mailboxRenamed.isNoop()).isFalse();
     }
 
     @Test
     void addedShouldNotBeNoop() {
-        MailboxListener.MailboxAdded added = new MailboxListener.MailboxAdded(SESSION_ID, BOB, PATH, MAILBOX_ID);
+        MailboxListener.MailboxAdded added = new MailboxListener.MailboxAdded(SESSION_ID, BOB, PATH, MAILBOX_ID,
+            Event.EventId.random());
 
         assertThat(added.isNoop()).isFalse();
     }
@@ -122,56 +125,62 @@ class MailboxListenerTest {
     @Test
     void removedShouldNotBeNoop() {
         MailboxListener.MailboxDeletion deletion = new MailboxListener.MailboxDeletion(SESSION_ID, BOB, PATH, QUOTA_ROOT,
-            QUOTA_COUNT, QUOTA_SIZE, MAILBOX_ID);
+            QUOTA_COUNT, QUOTA_SIZE, MAILBOX_ID, Event.EventId.random());
 
         assertThat(deletion.isNoop()).isFalse();
     }
 
     @Test
     void aclDiffWithSameAclShouldBeNoop() {
-        MailboxListener.MailboxACLUpdated aclUpdated = new MailboxListener.MailboxACLUpdated(SESSION_ID, BOB, PATH, ACLDiff.computeDiff(ACL_1, ACL_1), MAILBOX_ID);
+        MailboxListener.MailboxACLUpdated aclUpdated = new MailboxListener.MailboxACLUpdated(SESSION_ID, BOB, PATH, ACLDiff.computeDiff(ACL_1, ACL_1), MAILBOX_ID,
+            Event.EventId.random());
 
         assertThat(aclUpdated.isNoop()).isTrue();
     }
 
     @Test
     void aclDiffWithDifferentAclShouldNotBeNoop() {
-        MailboxListener.MailboxACLUpdated aclUpdated = new MailboxListener.MailboxACLUpdated(SESSION_ID, BOB, PATH, ACLDiff.computeDiff(ACL_1, ACL_2), MAILBOX_ID);
+        MailboxListener.MailboxACLUpdated aclUpdated = new MailboxListener.MailboxACLUpdated(SESSION_ID, BOB, PATH, ACLDiff.computeDiff(ACL_1, ACL_2), MAILBOX_ID,
+            Event.EventId.random());
 
         assertThat(aclUpdated.isNoop()).isFalse();
     }
 
     @Test
     void addedShouldBeNoopWhenEmpty() {
-        MailboxListener.Added added = new MailboxListener.Added(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableSortedMap.of());
+        MailboxListener.Added added = new MailboxListener.Added(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableSortedMap.of(),
+            Event.EventId.random());
 
         assertThat(added.isNoop()).isTrue();
     }
 
     @Test
     void addedShouldNotBeNoopWhenNotEmpty() {
-        MailboxListener.Added added = new MailboxListener.Added(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableSortedMap.of(UID, META_DATA));
+        MailboxListener.Added added = new MailboxListener.Added(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableSortedMap.of(UID, META_DATA),
+            Event.EventId.random());
 
         assertThat(added.isNoop()).isFalse();
     }
 
     @Test
     void expungedShouldBeNoopWhenEmpty() {
-        MailboxListener.Expunged expunged = new MailboxListener.Expunged(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableSortedMap.of());
+        MailboxListener.Expunged expunged = new MailboxListener.Expunged(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableSortedMap.of(),
+            Event.EventId.random());
 
         assertThat(expunged.isNoop()).isTrue();
     }
 
     @Test
     void expungedShouldNotBeNoopWhenNotEmpty() {
-        MailboxListener.Expunged expunged = new MailboxListener.Expunged(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableSortedMap.of(UID, META_DATA));
+        MailboxListener.Expunged expunged = new MailboxListener.Expunged(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableSortedMap.of(UID, META_DATA),
+            Event.EventId.random());
 
         assertThat(expunged.isNoop()).isFalse();
     }
 
     @Test
     void flagsUpdatedShouldBeNoopWhenEmpty() {
-        MailboxListener.FlagsUpdated flagsUpdated = new MailboxListener.FlagsUpdated(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableList.of());
+        MailboxListener.FlagsUpdated flagsUpdated = new MailboxListener.FlagsUpdated(SESSION_ID, BOB, PATH, MAILBOX_ID, ImmutableList.of(), Event.EventId.random());
 
         assertThat(flagsUpdated.isNoop()).isTrue();
     }
@@ -184,14 +193,15 @@ class MailboxListenerTest {
                 .modSeq(45)
                 .newFlags(new Flags())
                 .oldFlags(new Flags(Flags.Flag.ANSWERED))
-                .build()));
+                .build()),
+            Event.EventId.random());
 
         assertThat(flagsUpdated.isNoop()).isFalse();
     }
 
     @Test
     void quotaUsageUpdatedEventShouldNotBeNoop() {
-        MailboxListener.QuotaUsageUpdatedEvent event = new MailboxListener.QuotaUsageUpdatedEvent(BOB, QUOTA_ROOT,
+        MailboxListener.QuotaUsageUpdatedEvent event = new MailboxListener.QuotaUsageUpdatedEvent(Event.EventId.random(), BOB, QUOTA_ROOT,
             Quota.<QuotaCount>builder()
                 .used(QUOTA_COUNT)
                 .computedLimit(QuotaCount.unlimited())

http://git-wip-us.apache.org/repos/asf/james-project/blob/60919d85/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusContract.java
----------------------------------------------------------------------
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 465ed77..ab54208 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
@@ -37,6 +37,7 @@ import java.util.List;
 import java.util.concurrent.CountDownLatch;
 
 import org.apache.james.core.User;
+import org.apache.james.mailbox.Event;
 import org.apache.james.mailbox.MailboxListener;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.model.MailboxConstants;
@@ -54,7 +55,9 @@ public interface EventBusContract {
         MailboxSession.SessionId.of(42),
         User.fromUsername("user"),
         new MailboxPath(MailboxConstants.USER_NAMESPACE, "user", "mailboxName"),
-        TestId.of(18));
+        TestId.of(18),
+        Event.EventId.random());
+    MailboxListener.Added NOOP_EVENT = new MailboxListener.Added(MailboxSession.SessionId.of(18), User.fromUsername("bob"), MailboxPath.forUser("bob", "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
 
     class GroupA extends Group {}
 
@@ -94,8 +97,7 @@ public interface EventBusContract {
 
         eventBus().register(listener, new GroupA());
 
-        MailboxListener.Added noopEvent = new MailboxListener.Added(MailboxSession.SessionId.of(18), User.fromUsername("bob"), MailboxPath.forUser("bob", "mailbox"), TestId.of(58), ImmutableSortedMap.of());
-        eventBus().dispatch(noopEvent, NO_KEYS).block();
+        eventBus().dispatch(NOOP_EVENT, NO_KEYS).block();
 
         verifyNoMoreInteractions(listener);
     }
@@ -106,8 +108,7 @@ public interface EventBusContract {
 
         eventBus().register(listener, KEY_1);
 
-        MailboxListener.Added noopEvent = new MailboxListener.Added(MailboxSession.SessionId.of(18), User.fromUsername("bob"), MailboxPath.forUser("bob", "mailbox"), TestId.of(58), ImmutableSortedMap.of());
-        eventBus().dispatch(noopEvent, KEY_1).block();
+        eventBus().dispatch(NOOP_EVENT, KEY_1).block();
 
         verifyNoMoreInteractions(listener);
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/60919d85/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala
----------------------------------------------------------------------
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 3d63c76..03c62eb 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
@@ -27,6 +27,7 @@ import org.apache.james.core.quota.{QuotaCount, QuotaSize, QuotaValue}
 import org.apache.james.core.{Domain, User}
 import org.apache.james.event.json.DTOs.SystemFlag.SystemFlag
 import org.apache.james.event.json.DTOs.{ACLDiff, Flags, MailboxPath, Quota, SystemFlag, UserFlag}
+import org.apache.james.mailbox.Event.EventId
 import org.apache.james.mailbox.MailboxListener.{Added => JavaAdded, Expunged => JavaExpunged, FlagsUpdated => JavaFlagsUpdated, MailboxACLUpdated => JavaMailboxACLUpdated, MailboxAdded => JavaMailboxAdded, MailboxDeletion => JavaMailboxDeletion, MailboxRenamed => JavaMailboxRenamed, QuotaUsageUpdatedEvent => JavaQuotaUsageUpdatedEvent}
 import org.apache.james.mailbox.MailboxSession.SessionId
 import org.apache.james.mailbox.model.{MailboxId, MessageId, MessageMoves, QuotaRoot, MailboxACL => JavaMailboxACL, MessageMetaData => JavaMessageMetaData, Quota => JavaQuota}
@@ -40,53 +41,55 @@ private sealed trait Event {
 }
 
 private object DTO {
-  case class MailboxACLUpdated(sessionId: SessionId, user: User, mailboxPath: MailboxPath, aclDiff: ACLDiff, mailboxId: MailboxId) extends Event {
-    override def toJava: JavaEvent = new JavaMailboxACLUpdated(sessionId, user, mailboxPath.toJava, aclDiff.toJava, mailboxId)
+  case class MailboxACLUpdated(eventId: EventId, sessionId: SessionId, user: User, mailboxPath: MailboxPath, aclDiff: ACLDiff, mailboxId: MailboxId) extends Event {
+    override def toJava: JavaEvent = new JavaMailboxACLUpdated(sessionId, user, mailboxPath.toJava, aclDiff.toJava, mailboxId, eventId)
   }
 
-  case class MailboxAdded(mailboxPath: MailboxPath, mailboxId: MailboxId, user: User, sessionId: SessionId) extends Event {
-    override def toJava: JavaEvent = new JavaMailboxAdded(sessionId, user, mailboxPath.toJava, mailboxId)
+  case class MailboxAdded(eventId: EventId, mailboxPath: MailboxPath, mailboxId: MailboxId, user: User, sessionId: SessionId) extends Event {
+    override def toJava: JavaEvent = new JavaMailboxAdded(sessionId, user, mailboxPath.toJava, mailboxId, eventId)
   }
 
-  case class MailboxDeletion(sessionId: SessionId, user: User, path: MailboxPath, quotaRoot: QuotaRoot,
+  case class MailboxDeletion(eventId: EventId, sessionId: SessionId, user: User, path: MailboxPath, quotaRoot: QuotaRoot,
                              deletedMessageCount: QuotaCount, totalDeletedSize: QuotaSize, mailboxId: MailboxId) extends Event {
     override def toJava: JavaEvent = new JavaMailboxDeletion(sessionId, user, path.toJava, quotaRoot, deletedMessageCount,
-      totalDeletedSize,
-      mailboxId)
+      totalDeletedSize, mailboxId, eventId)
   }
 
-  case class MailboxRenamed(sessionId: SessionId, user: User, path: MailboxPath, mailboxId: MailboxId, newPath: MailboxPath) extends Event {
-    override def toJava: JavaEvent = new JavaMailboxRenamed(sessionId, user, path.toJava, mailboxId, newPath.toJava)
+  case class MailboxRenamed(eventId: EventId, sessionId: SessionId, user: User, path: MailboxPath, mailboxId: MailboxId, newPath: MailboxPath) extends Event {
+    override def toJava: JavaEvent = new JavaMailboxRenamed(sessionId, user, path.toJava, mailboxId, newPath.toJava, eventId)
   }
 
-  case class QuotaUsageUpdatedEvent(user: User, quotaRoot: QuotaRoot, countQuota: Quota[QuotaCount],
+  case class QuotaUsageUpdatedEvent(eventId: EventId, user: User, quotaRoot: QuotaRoot, countQuota: Quota[QuotaCount],
                                     sizeQuota: Quota[QuotaSize], time: Instant) extends Event {
-    override def toJava: JavaEvent = new JavaQuotaUsageUpdatedEvent(user, quotaRoot, countQuota.toJava, sizeQuota.toJava, time)
+    override def toJava: JavaEvent = new JavaQuotaUsageUpdatedEvent(eventId, user, quotaRoot, countQuota.toJava, sizeQuota.toJava, time)
   }
 
-  case class Added(sessionId: SessionId, user: User, path: MailboxPath, mailboxId: MailboxId,
+  case class Added(eventId: EventId, sessionId: SessionId, user: User, path: MailboxPath, mailboxId: MailboxId,
                    added: Map[MessageUid, DTOs.MessageMetaData]) extends Event {
     override def toJava: JavaEvent = new JavaAdded(
       sessionId,
       user,
       path.toJava,
       mailboxId,
-      new JavaTreeMap[MessageUid, JavaMessageMetaData](added.mapValues(_.toJava).asJava))
+      new JavaTreeMap[MessageUid, JavaMessageMetaData](added.mapValues(_.toJava).asJava),
+      eventId)
   }
 
-  case class Expunged(sessionId: SessionId, user: User, path: MailboxPath, mailboxId: MailboxId,
+  case class Expunged(eventId: EventId, sessionId: SessionId, user: User, path: MailboxPath, mailboxId: MailboxId,
                       expunged: Map[MessageUid, DTOs.MessageMetaData]) extends Event {
     override def toJava: JavaEvent = new JavaExpunged(
       sessionId,
       user,
       path.toJava,
       mailboxId,
-      expunged.mapValues(_.toJava).asJava)
+      expunged.mapValues(_.toJava).asJava,
+      eventId)
   }
 
-  case class MessageMoveEvent(user: User, previousMailboxIds: Iterable[MailboxId], targetMailboxIds: Iterable[MailboxId],
+  case class MessageMoveEvent(eventId: EventId, user: User, previousMailboxIds: Iterable[MailboxId], targetMailboxIds: Iterable[MailboxId],
                               messageIds: Iterable[MessageId]) extends Event {
     override def toJava: JavaEvent = JavaMessageMoveEvent.builder()
+      .eventId(eventId)
       .user(user)
       .messageId(messageIds.asJava)
       .messageMoves(MessageMoves.builder()
@@ -96,19 +99,21 @@ private object DTO {
       .build()
   }
 
-  case class FlagsUpdated(sessionId: SessionId, user: User, path: MailboxPath, mailboxId: MailboxId,
+  case class FlagsUpdated(eventId: EventId, sessionId: SessionId, user: User, path: MailboxPath, mailboxId: MailboxId,
                           updatedFlags: List[DTOs.UpdatedFlags]) extends Event {
     override def toJava: JavaEvent = new JavaFlagsUpdated(
       sessionId,
       user,
       path.toJava,
       mailboxId,
-      updatedFlags.map(_.toJava).asJava)
+      updatedFlags.map(_.toJava).asJava,
+      eventId)
   }
 }
 
 private object ScalaConverter {
   private def toScala(event: JavaMailboxACLUpdated): DTO.MailboxACLUpdated = DTO.MailboxACLUpdated(
+    eventId = event.getEventId,
     sessionId = event.getSessionId,
     user = event.getUser,
     mailboxPath = MailboxPath.fromJava(event.getMailboxPath),
@@ -116,12 +121,14 @@ private object ScalaConverter {
     mailboxId = event.getMailboxId)
 
   private def toScala(event: JavaMailboxAdded): DTO.MailboxAdded = DTO.MailboxAdded(
+    eventId = event.getEventId,
     mailboxPath = MailboxPath.fromJava(event.getMailboxPath),
     mailboxId = event.getMailboxId,
     user = event.getUser,
     sessionId = event.getSessionId)
 
   private def toScala(event: JavaMailboxDeletion): DTO.MailboxDeletion = DTO.MailboxDeletion(
+    eventId = event.getEventId,
     sessionId = event.getSessionId,
     user = event.getUser,
     quotaRoot = event.getQuotaRoot,
@@ -131,6 +138,7 @@ private object ScalaConverter {
     mailboxId = event.getMailboxId)
 
   private def toScala(event: JavaMailboxRenamed): DTO.MailboxRenamed = DTO.MailboxRenamed(
+    eventId = event.getEventId,
     sessionId = event.getSessionId,
     user = event.getUser,
     path = MailboxPath.fromJava(event.getMailboxPath),
@@ -138,6 +146,7 @@ private object ScalaConverter {
     newPath = MailboxPath.fromJava(event.getNewPath))
 
   private def toScala(event: JavaQuotaUsageUpdatedEvent): DTO.QuotaUsageUpdatedEvent = DTO.QuotaUsageUpdatedEvent(
+    eventId = event.getEventId,
     user = event.getUser,
     quotaRoot = event.getQuotaRoot,
     countQuota = Quota.toScala(event.getCountQuota),
@@ -145,6 +154,7 @@ private object ScalaConverter {
     time = event.getInstant)
 
   private def toScala(event: JavaAdded): DTO.Added = DTO.Added(
+    eventId = event.getEventId,
     sessionId = event.getSessionId,
     user = event.getUser,
     path = MailboxPath.fromJava(event.getMailboxPath),
@@ -152,6 +162,7 @@ private object ScalaConverter {
     added = event.getAdded.asScala.mapValues(DTOs.MessageMetaData.fromJava).toMap)
 
   private def toScala(event: JavaExpunged): DTO.Expunged = DTO.Expunged(
+    eventId = event.getEventId,
     sessionId = event.getSessionId,
     user = event.getUser,
     path = MailboxPath.fromJava(event.getMailboxPath),
@@ -159,12 +170,14 @@ private object ScalaConverter {
     expunged = event.getExpunged.asScala.mapValues(DTOs.MessageMetaData.fromJava).toMap)
 
   private def toScala(event: JavaMessageMoveEvent): DTO.MessageMoveEvent = DTO.MessageMoveEvent(
+    eventId = event.getEventId,
     user = event.getUser,
     previousMailboxIds = event.getMessageMoves.getPreviousMailboxIds.asScala,
     targetMailboxIds = event.getMessageMoves.getTargetMailboxIds.asScala,
     messageIds = event.getMessageIds.asScala)
 
   private def toScala(event: JavaFlagsUpdated): DTO.FlagsUpdated = DTO.FlagsUpdated(
+    eventId = event.getEventId,
     sessionId = event.getSessionId,
     user = event.getUser,
     path = DTOs.MailboxPath.fromJava(event.getMailboxPath),
@@ -203,6 +216,7 @@ class JsonSerialize(mailboxIdFactory: MailboxId.Factory, messageIdFactory: Messa
   implicit val messageUidWrites: Writes[MessageUid] = value => JsNumber(value.asLong())
   implicit val userFlagWrites: Writes[UserFlag] = value => JsString(value.value)
   implicit val flagWrites: Writes[Flags] = Json.writes[Flags]
+  implicit val eventIdWrites: Writes[EventId] = value => JsString(value.getId.toString)
 
   implicit val messageMetaDataWrites: Writes[DTOs.MessageMetaData] = Json.writes[DTOs.MessageMetaData]
   implicit val updatedFlagsWrites: Writes[DTOs.UpdatedFlags] = Json.writes[DTOs.UpdatedFlags]
@@ -259,6 +273,10 @@ class JsonSerialize(mailboxIdFactory: MailboxId.Factory, messageIdFactory: Messa
     case JsString(x) => JsSuccess(UserFlag(x))
     case _ => JsError()
   }
+  implicit val eventIdReads: Reads[EventId] = {
+    case JsString(x) => JsSuccess(EventId.of(x))
+    case _ => JsError()
+  }
 
   implicit def scopeMapReads[V](implicit vr: Reads[V]): Reads[Map[JavaQuota.Scope, V]] =
     Reads.mapReads[JavaQuota.Scope, V] { str =>

http://git-wip-us.apache.org/repos/asf/james-project/blob/60919d85/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
----------------------------------------------------------------------
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 7760523..4429a1f 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
@@ -20,6 +20,7 @@
 package org.apache.james.event.json;
 
 import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
+import static org.apache.james.event.json.SerializerFixture.EVENT_ID;
 import static org.apache.james.event.json.SerializerFixture.EVENT_SERIALIZER;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -66,10 +67,12 @@ 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, USER, MAILBOX_PATH, MAILBOX_ID, ADDED);
+    private static final MailboxListener.Added DEFAULT_ADDED_EVENT = new MailboxListener.Added(SESSION_ID, USER,
+        MAILBOX_PATH, MAILBOX_ID, ADDED, EVENT_ID);
     private static final String DEFAULT_ADDED_EVENT_JSON = 
         "{" +
         "  \"Added\": {" +
+        "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
         "    \"path\": {" +
         "      \"namespace\": \"#private\"," +
         "      \"user\": \"user\"," +
@@ -108,10 +111,12 @@ class AddedSerializationTest {
     @Nested
     class WithEmptyAddedMap {
 
-        private final MailboxListener.Added emptyAddedEvent = new MailboxListener.Added(SESSION_ID, USER, MAILBOX_PATH, MAILBOX_ID, ImmutableSortedMap.of());
+        private final MailboxListener.Added emptyAddedEvent = new MailboxListener.Added(SESSION_ID, USER, MAILBOX_PATH,
+            MAILBOX_ID, ImmutableSortedMap.of(), EVENT_ID);
         private final String emptyAddedEventJson =
             "{" +
             "  \"Added\": {" +
+            "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
             "    \"path\": {" +
             "      \"namespace\": \"#private\"," +
             "      \"user\": \"user\"," +
@@ -140,10 +145,41 @@ class AddedSerializationTest {
     @Nested
     class DeserializationErrors {
         @Test
+        void addedShouldThrowWhenMissingEventId() {
+            assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                "{" +
+                    "  \"Added\": {" +
+                    "    \"sessionId\":42," +
+                    "    \"path\": {" +
+                    "      \"namespace\": \"#private\"," +
+                    "      \"user\": \"user\"," +
+                    "      \"name\": \"mailboxName\"" +
+                    "    }," +
+                    "    \"mailboxId\": \"18\"," +
+                    "    \"added\": {" +
+                    "      \"123456\": {" +
+                    "        \"uid\": 123456," +
+                    "        \"modSeq\": 35," +
+                    "        \"flags\": {" +
+                    "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                    "          \"userFlags\":[\"User Custom Flag\"]}," +
+                    "        \"size\": 45,  " +
+                    "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
+                    "        \"messageId\": \"42\"" +
+                    "      }" +
+                    "    }," +
+                    "    \"user\": \"user\"" +
+                    "  }" +
+                    "}").get())
+                .isInstanceOf(NoSuchElementException.class);
+        }
+
+        @Test
         void addedShouldThrowWhenMissingSessionId() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"Added\": {" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"path\": {" +
                     "      \"namespace\": \"#private\"," +
                     "      \"user\": \"user\"," +
@@ -173,6 +209,7 @@ class AddedSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"Added\": {" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"path\": {" +
                     "      \"namespace\": \"#private\"," +
                     "      \"user\": \"user\"," +
@@ -202,6 +239,7 @@ class AddedSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"Added\": {" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"path\": {" +
                     "      \"namespace\": \"#private\"," +
                     "      \"user\": \"user\"," +
@@ -231,6 +269,7 @@ class AddedSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"Added\": {" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"mailboxId\": \"18\"," +
                     "    \"added\": {" +
                     "      \"123456\": {" +
@@ -256,6 +295,7 @@ class AddedSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"Added\": {" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"path\": {" +
                     "      \"namespace\": \"#private\"," +
                     "      \"user\": \"user\"," +
@@ -275,6 +315,7 @@ class AddedSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"Added\": {" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"path\": {" +
                     "      \"namespace\": \"#private\"," +
                     "      \"user\": \"user\"," +

http://git-wip-us.apache.org/repos/asf/james-project/blob/60919d85/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java
----------------------------------------------------------------------
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 85e0365..b04b552 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
@@ -20,6 +20,7 @@
 package org.apache.james.event.json;
 
 import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
+import static org.apache.james.event.json.SerializerFixture.EVENT_ID;
 import static org.apache.james.event.json.SerializerFixture.EVENT_SERIALIZER;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -66,10 +67,12 @@ 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, USER, MAILBOX_PATH, MAILBOX_ID, EXPUNGED);
+    private static final MailboxListener.Expunged DEFAULT_EXPUNGED_EVENT = new MailboxListener.Expunged(SESSION_ID, USER,
+        MAILBOX_PATH, MAILBOX_ID, EXPUNGED, EVENT_ID);
     private static final String DEFAULT_EXPUNGED_EVENT_JSON =
         "{" +
         "  \"Expunged\": {" +
+        "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
         "    \"path\": {" +
         "      \"namespace\": \"#private\"," +
         "      \"user\": \"user\"," +
@@ -108,10 +111,12 @@ class ExpungedSerializationTest {
     @Nested
     class WithEmptyExpungedMap {
 
-        private final MailboxListener.Expunged emptyExpungedEvent = new MailboxListener.Expunged(SESSION_ID, USER, MAILBOX_PATH, MAILBOX_ID, ImmutableMap.of());
+        private final MailboxListener.Expunged emptyExpungedEvent = new MailboxListener.Expunged(SESSION_ID, USER,
+            MAILBOX_PATH, MAILBOX_ID, ImmutableMap.of(), EVENT_ID);
         private final String emptyExpungedEventJson =
             "{" +
             "  \"Expunged\": {" +
+            "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
             "    \"path\": {" +
             "      \"namespace\": \"#private\"," +
             "      \"user\": \"user\"," +
@@ -144,6 +149,7 @@ class ExpungedSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"Expunged\": {" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"path\": {" +
                     "      \"namespace\": \"#private\"," +
                     "      \"user\": \"user\"," +
@@ -169,10 +175,30 @@ class ExpungedSerializationTest {
         }
 
         @Test
+        void expungedShouldThrowWhenMissingEventId() {
+            assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                "{" +
+                    "  \"Expunged\": {" +
+                    "    \"sessionId\":42," +
+                    "    \"path\": {" +
+                    "      \"namespace\": \"#private\"," +
+                    "      \"user\": \"user\"," +
+                    "      \"name\": \"mailboxName\"" +
+                    "    }," +
+                    "    \"mailboxId\": \"18\"," +
+                    "    \"expunged\": {}," +
+                    "    \"user\": \"user\"" +
+                    "  }" +
+                    "}").get())
+                .isInstanceOf(NoSuchElementException.class);
+        }
+
+        @Test
         void expungedShouldThrowWhenMissingUser() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"Expunged\": {" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"path\": {" +
                     "      \"namespace\": \"#private\"," +
                     "      \"user\": \"user\"," +
@@ -202,6 +228,7 @@ class ExpungedSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"Expunged\": {" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"path\": {" +
                     "      \"namespace\": \"#private\"," +
                     "      \"user\": \"user\"," +
@@ -231,6 +258,7 @@ class ExpungedSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"Expunged\": {" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"mailboxId\": \"18\"," +
                     "    \"expunged\": {" +
                     "      \"123456\": {" +
@@ -256,6 +284,7 @@ class ExpungedSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"Expunged\": {" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"path\": {" +
                     "      \"namespace\": \"#private\"," +
                     "      \"user\": \"user\"," +
@@ -275,6 +304,7 @@ class ExpungedSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"Expunged\": {" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"path\": {" +
                     "      \"namespace\": \"#private\"," +
                     "      \"user\": \"user\"," +

http://git-wip-us.apache.org/repos/asf/james-project/blob/60919d85/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java
----------------------------------------------------------------------
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 941a5de..5e7fd38 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
@@ -20,6 +20,7 @@
 package org.apache.james.event.json;
 
 import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
+import static org.apache.james.event.json.SerializerFixture.EVENT_ID;
 import static org.apache.james.event.json.SerializerFixture.EVENT_SERIALIZER;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -91,10 +92,11 @@ 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, USER,
-        MAILBOX_PATH, MAILBOX_ID, UPDATED_FLAGS_LIST);
+        MAILBOX_PATH, MAILBOX_ID, UPDATED_FLAGS_LIST, EVENT_ID);
     private static final String DEFAULT_EVENT_JSON =
         "{" +
         "  \"FlagsUpdated\": {" +
+        "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
         "    \"path\": {" +
         "      \"namespace\": \"#private\"," +
         "      \"user\": \"user\"," +
@@ -137,11 +139,12 @@ class FlagsUpdatedSerializationTest {
     class WithEmptyUpdatedFlags {
         private final List<UpdatedFlags> emptyUpdatedFlags = ImmutableList.of();
         private final MailboxListener.FlagsUpdated emptyUpdatedFlagsEvent = new MailboxListener.FlagsUpdated(SESSION_ID, USER, MAILBOX_PATH,
-            MAILBOX_ID, emptyUpdatedFlags);
+            MAILBOX_ID, emptyUpdatedFlags, EVENT_ID);
 
         private static final String EVENT_JSON_WITH_EMPTY_UPDATED_FLAGS =
             "{" +
                 "  \"FlagsUpdated\": {" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                 "    \"path\": {" +
                 "      \"namespace\": \"#private\"," +
                 "      \"user\": \"user\"," +
@@ -175,6 +178,7 @@ class FlagsUpdatedSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"FlagsUpdated\": {" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"path\": {" +
                     "      \"namespace\": \"#private\"," +
                     "      \"user\": \"user\"," +
@@ -202,10 +206,30 @@ class FlagsUpdatedSerializationTest {
         }
 
         @Test
+        void flagsUpdatedShouldThrowWhenMissingEventId() {
+            assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                "{" +
+                    "  \"FlagsUpdated\": {" +
+                    "    \"sessionId\":42," +
+                    "    \"path\": {" +
+                    "      \"namespace\": \"#private\"," +
+                    "      \"user\": \"user\"," +
+                    "      \"name\": \"mailboxName\"" +
+                    "    }," +
+                    "    \"mailboxId\": \"18\"," +
+                    "    \"updatedFlags\": []," +
+                    "    \"user\": \"user\"" +
+                    "  }" +
+                    "}").get())
+                .isInstanceOf(NoSuchElementException.class);
+        }
+
+        @Test
         void flagsUpdatedShouldThrowWhenMissingUser() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"FlagsUpdated\": {" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"path\": {" +
                     "      \"namespace\": \"#private\"," +
                     "      \"user\": \"user\"," +
@@ -237,6 +261,7 @@ class FlagsUpdatedSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"FlagsUpdated\": {" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"path\": {" +
                     "      \"namespace\": \"#private\"," +
                     "      \"user\": \"user\"," +
@@ -268,6 +293,7 @@ class FlagsUpdatedSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"FlagsUpdated\": {" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"path\": {" +
                     "      \"namespace\": 482," +
                     "      \"user\": \"user\"," +

http://git-wip-us.apache.org/repos/asf/james-project/blob/60919d85/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java
----------------------------------------------------------------------
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 8feb069..7436899 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
@@ -20,6 +20,7 @@
 package org.apache.james.event.json;
 
 import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
+import static org.apache.james.event.json.SerializerFixture.EVENT_ID;
 import static org.apache.james.event.json.SerializerFixture.EVENT_SERIALIZER;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -52,10 +53,12 @@ class MailboxACLUpdatedEventSerializationTest {
                 USER,
                 new MailboxPath(MailboxConstants.USER_NAMESPACE, "bob", "mailboxName"),
                 ACLDiff.computeDiff(MailboxACL.EMPTY, MAILBOX_ACL),
-                TestId.of(23));
+                TestId.of(23),
+                EVENT_ID);
 
     private static final String MAILBOX_ACL_UPDATED_JSON = "{" +
         "  \"MailboxACLUpdated\":{" +
+        "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
         "    \"mailboxPath\":{" +
         "       \"namespace\":\"#private\"," +
         "       \"user\":\"bob\"," +
@@ -89,6 +92,28 @@ class MailboxACLUpdatedEventSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"MailboxACLUpdated\":{" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
+                    "    \"mailboxPath\":{" +
+                    "       \"namespace\":\"#private\"," +
+                    "       \"user\":\"bob\"," +
+                    "       \"name\":\"mailboxName\"" +
+                    "      }," +
+                    "    \"aclDiff\":{" +
+                    "       \"oldACL\":{}," +
+                    "       \"newACL\":{\"$any\":\"ar\"}}," +
+                    "    \"mailboxId\":\"23\"," +
+                    "    \"user\":\"user\"" +
+                    "   }" +
+                    "}").get())
+                .isInstanceOf(NoSuchElementException.class);
+        }
+
+        @Test
+        void mailboxACLUpdatedShouldThrowWhenMissingEventId() {
+            assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                "{" +
+                    "  \"MailboxACLUpdated\":{" +
+                    "    \"sessionId\":42," +
                     "    \"mailboxPath\":{" +
                     "       \"namespace\":\"#private\"," +
                     "       \"user\":\"bob\"," +
@@ -109,6 +134,7 @@ class MailboxACLUpdatedEventSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"MailboxACLUpdated\":{" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"mailboxPath\":{" +
                     "       \"namespace\":\"#private\"," +
                     "       \"name\":\"mailboxName\"" +
@@ -128,6 +154,7 @@ class MailboxACLUpdatedEventSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"MailboxACLUpdated\":{" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"mailboxPath\":{" +
                     "       \"namespace\":\"#private\"," +
                     "       \"name\":\"mailboxName\"" +
@@ -145,6 +172,7 @@ class MailboxACLUpdatedEventSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"MailboxACLUpdated\":{" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"mailboxPath\":{" +
                     "       \"namespace\":\"#private\"," +
                     "       \"user\":\"bob\"," +
@@ -165,6 +193,7 @@ class MailboxACLUpdatedEventSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"MailboxACLUpdated\":{" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"mailboxPath\":{" +
                     "       \"namespace\":230192.06," +
                     "       \"user\":\"bob\"," +

http://git-wip-us.apache.org/repos/asf/james-project/blob/60919d85/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxAddedSerializationTest.java
----------------------------------------------------------------------
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 d8e58b1..09056d3 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
@@ -20,6 +20,7 @@
 package org.apache.james.event.json;
 
 import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
+import static org.apache.james.event.json.SerializerFixture.EVENT_ID;
 import static org.apache.james.event.json.SerializerFixture.EVENT_SERIALIZER;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -41,9 +42,11 @@ class MailboxAddedSerializationTest {
         MailboxSession.SessionId.of(42),
         USER,
         new MailboxPath(MailboxConstants.USER_NAMESPACE, "bob", "mailboxName"),
-        TestId.of(18));
+        TestId.of(18),
+        EVENT_ID);
     private static final String JSON_1 = "{" +
         "  \"MailboxAdded\":{" +
+        "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
         "    \"mailboxPath\":{" +
         "      \"namespace\":\"#private\"," +
         "      \"user\":\"bob\"," +
@@ -74,6 +77,24 @@ class MailboxAddedSerializationTest {
         void fromJsonShouldRejectMissingSessionId() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson("{" +
                 "  \"MailboxAdded\":{" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
+                "    \"mailboxPath\":{" +
+                "      \"namespace\":\"#private\"," +
+                "      \"user\":\"bob\"" +
+                "     }," +
+                "     \"mailboxId\":\"18\"," +
+                "     \"user\":\"user\"," +
+                "     \"sessionId\":18" +
+                "  }" +
+                "}").get())
+                .isInstanceOf(NoSuchElementException.class);
+        }
+
+        @Test
+        void fromJsonShouldRejectMissingEventId() {
+            assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson("{" +
+                "  \"MailboxAdded\":{" +
+                "    \"sessionId\":42," +
                 "    \"mailboxPath\":{" +
                 "      \"namespace\":\"#private\"," +
                 "      \"user\":\"bob\"" +
@@ -90,6 +111,7 @@ class MailboxAddedSerializationTest {
         void fromJsonShouldRejectMissingMailboxId() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson("{" +
                 "  \"MailboxAdded\":{" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                 "    \"mailboxPath\":{" +
                 "      \"namespace\":\"#private\"," +
                 "      \"user\":\"bob\"," +
@@ -106,6 +128,7 @@ class MailboxAddedSerializationTest {
         void fromJsonShouldRejectMissingUser() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson("{" +
                 "  \"MailboxAdded\":{" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                 "    \"mailboxPath\":{" +
                 "      \"namespace\":\"#private\"," +
                 "      \"user\":\"bob\"," +
@@ -122,6 +145,7 @@ class MailboxAddedSerializationTest {
         void fromJsonShouldRejectMissingMailboxPath() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson("{" +
                 "  \"MailboxAdded\":{" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                 "     \"mailboxId\":\"18\"," +
                 "     \"user\":\"user\"," +
                 "     \"sessionId\":18" +

http://git-wip-us.apache.org/repos/asf/james-project/blob/60919d85/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxDeletionSerializationTest.java
----------------------------------------------------------------------
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 b601f48..ef20655 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
@@ -20,6 +20,7 @@
 package org.apache.james.event.json;
 
 import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
+import static org.apache.james.event.json.SerializerFixture.EVENT_ID;
 import static org.apache.james.event.json.SerializerFixture.EVENT_SERIALIZER;
 import static org.apache.james.mailbox.model.MailboxConstants.USER_NAMESPACE;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -56,11 +57,13 @@ class MailboxDeletionSerializationTest {
         QUOTA_ROOT,
         DELETED_MESSAGE_COUNT,
         TOTAL_DELETED_SIZE,
-        MAILBOX_ID);
+        MAILBOX_ID,
+        EVENT_ID);
 
     private static final String DEFAULT_EVEN_JSON =
         "{" +
         "  \"MailboxDeletion\":{" +
+        "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
         "    \"sessionId\":3652," +
         "    \"user\":\"user\"," +
         "    \"path\":{" +
@@ -94,6 +97,28 @@ class MailboxDeletionSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"MailboxDeletion\":{" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
+                    "    \"user\":\"user\"," +
+                    "    \"path\":{" +
+                    "      \"namespace\":\"#private\"," +
+                    "      \"user\":\"user\"," +
+                    "      \"name\":\"mailboxName\"" +
+                    "    }," +
+                    "    \"quotaRoot\":\"user@domain\"," +
+                    "    \"deletedMessageCount\":60," +
+                    "    \"totalDeletedSize\":100," +
+                    "    \"mailboxId\":\"789\"" +
+                    "  }" +
+                    "}").get())
+                .isInstanceOf(NoSuchElementException.class);
+        }
+
+        @Test
+        void mailboxAddedShouldThrowWhenMissingEventId() {
+            assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                "{" +
+                    "  \"MailboxDeletion\":{" +
+                    "    \"sessionId\":42," +
                     "    \"user\":\"user\"," +
                     "    \"path\":{" +
                     "      \"namespace\":\"#private\"," +
@@ -114,6 +139,7 @@ class MailboxDeletionSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"MailboxDeletion\":{" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"sessionId\":3652," +
                     "    \"path\":{" +
                     "      \"namespace\":\"#private\"," +
@@ -134,6 +160,7 @@ class MailboxDeletionSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"MailboxDeletion\":{" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"sessionId\":3652," +
                     "    \"user\":\"user\"," +
                     "    \"path\":{" +
@@ -154,6 +181,7 @@ class MailboxDeletionSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"MailboxDeletion\":{" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"sessionId\":3652," +
                     "    \"user\":\"user\"," +
                     "    \"path\":{" +
@@ -174,6 +202,7 @@ class MailboxDeletionSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"MailboxDeletion\":{" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"sessionId\":3652," +
                     "    \"user\":\"user\"," +
                     "    \"path\":{" +
@@ -194,6 +223,7 @@ class MailboxDeletionSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"MailboxDeletion\":{" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"sessionId\":3652," +
                     "    \"user\":\"user\"," +
                     "    \"path\":{" +
@@ -214,6 +244,7 @@ class MailboxDeletionSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"MailboxDeletion\":{" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"sessionId\":3652," +
                     "    \"user\":\"user\"," +
                     "    \"quotaRoot\":\"user@domain\"," +

http://git-wip-us.apache.org/repos/asf/james-project/blob/60919d85/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxRenamedSerializationTest.java
----------------------------------------------------------------------
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 de65db2..94ec114 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
@@ -20,6 +20,7 @@
 package org.apache.james.event.json;
 
 import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
+import static org.apache.james.event.json.SerializerFixture.EVENT_ID;
 import static org.apache.james.event.json.SerializerFixture.EVENT_SERIALIZER;
 import static org.apache.james.mailbox.model.MailboxConstants.USER_NAMESPACE;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -50,11 +51,13 @@ class MailboxRenamedSerializationTest {
         DEFAULT_USER,
         DEFAULT_OLD_MAILBOX_PATH,
         DEFAULT_MAILBOX_ID,
-        DEFAULT_NEW_MAILBOX_PATH);
+        DEFAULT_NEW_MAILBOX_PATH,
+        EVENT_ID);
 
     private static final String DEFAULT_MAILBOX_RENAMED_EVENT_JSON =
             "{" +
             "  \"MailboxRenamed\":{" +
+            "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
             "    \"sessionId\":123456789," +
             "    \"user\":\"user\"," +
             "    \"path\":{" +
@@ -90,6 +93,7 @@ class MailboxRenamedSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"MailboxRenamed\":{" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"sessionId\":123456789," +
                     "    \"path\":{" +
                     "      \"namespace\":\"#private\"," +
@@ -112,6 +116,31 @@ class MailboxRenamedSerializationTest {
             String eventWithNullSessionId =
                 "{" +
                     "  \"MailboxRenamed\":{" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
+                    "    \"user\":\"user\"," +
+                    "    \"path\":{" +
+                    "      \"namespace\":\"#private\"," +
+                    "      \"user\":\"user\"," +
+                    "      \"name\":\"oldMailboxName\"" +
+                    "     }," +
+                    "    \"mailboxId\":\"123456\"," +
+                    "    \"newPath\":{" +
+                    "      \"namespace\":\"#private\"," +
+                    "      \"user\":\"user\"," +
+                    "      \"name\":\"newMailboxName\"" +
+                    "     }" +
+                    "  }" +
+                    "}";
+            assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(eventWithNullSessionId).get())
+                .isInstanceOf(NoSuchElementException.class);
+        }
+
+        @Test
+        void mailboxRenamedDeSerializeShouldThrowWhenMissingEventId() {
+            String eventWithNullSessionId =
+                "{" +
+                    "  \"MailboxRenamed\":{" +
+                    "    \"sessionId\":42," +
                     "    \"user\":\"user\"," +
                     "    \"path\":{" +
                     "      \"namespace\":\"#private\"," +
@@ -135,6 +164,7 @@ class MailboxRenamedSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"MailboxRenamed\":{" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"sessionId\":123456789," +
                     "    \"user\":\"user\"," +
                     "    \"path\":{" +
@@ -157,6 +187,7 @@ class MailboxRenamedSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"MailboxRenamed\":{" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"sessionId\":123456789," +
                     "    \"user\":\"user\"," +
                     "    \"mailboxId\":123456," +
@@ -175,6 +206,7 @@ class MailboxRenamedSerializationTest {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                 "{" +
                     "  \"MailboxRenamed\":{" +
+                    "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                     "    \"sessionId\":123456789," +
                     "    \"user\":\"user\"," +
                     "    \"path\":{" +

http://git-wip-us.apache.org/repos/asf/james-project/blob/60919d85/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageMoveEventSerializationTest.java
----------------------------------------------------------------------
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 8110215..95190f4 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
@@ -20,6 +20,7 @@
 package org.apache.james.event.json;
 
 import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
+import static org.apache.james.event.json.SerializerFixture.EVENT_ID;
 import static org.apache.james.event.json.SerializerFixture.EVENT_SERIALIZER;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -37,6 +38,7 @@ import org.junit.jupiter.api.Test;
 
 class MessageMoveEventSerializationTest {
     private static final Event EVENT = MessageMoveEvent.builder()
+        .eventId(EVENT_ID)
         .user(User.fromUsername("bob@domain.tld"))
         .messageId(TestMessageId.of(42))
         .messageMoves(
@@ -47,6 +49,7 @@ class MessageMoveEventSerializationTest {
         .build();
     private static final String JSON = "{" +
         "  \"MessageMoveEvent\": {" +
+        "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
         "    \"user\": \"bob@domain.tld\"," +
         "    \"previousMailboxIds\": [\"18\", \"24\"]," +
         "    \"targetMailboxIds\": [\"36\"]," +
@@ -71,6 +74,7 @@ class MessageMoveEventSerializationTest {
         @Nested
         class EmptyTargetMailboxIds {
             private final Event event = MessageMoveEvent.builder()
+                .eventId(EVENT_ID)
                 .user(User.fromUsername("bob"))
                 .messageId(TestMessageId.of(42))
                 .messageMoves(
@@ -80,6 +84,7 @@ class MessageMoveEventSerializationTest {
                 .build();
             private final String json = "{" +
                 "  \"MessageMoveEvent\": {" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                 "    \"user\": \"bob\"," +
                 "    \"previousMailboxIds\": [\"18\", \"24\"]," +
                 "    \"targetMailboxIds\": []," +
@@ -103,6 +108,7 @@ class MessageMoveEventSerializationTest {
         @Nested
         class EmptyPreviousMailboxIds {
             private final Event event = MessageMoveEvent.builder()
+                .eventId(EVENT_ID)
                 .user(User.fromUsername("bob"))
                 .messageId(TestMessageId.of(42))
                 .messageMoves(
@@ -112,6 +118,7 @@ class MessageMoveEventSerializationTest {
                 .build();
             private final String json = "{" +
                 "  \"MessageMoveEvent\": {" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                 "    \"user\": \"bob\"," +
                 "    \"previousMailboxIds\": []," +
                 "    \"targetMailboxIds\": [\"36\"]," +
@@ -135,6 +142,7 @@ class MessageMoveEventSerializationTest {
         @Nested
         class EmptyMessagesIds {
             private final Event event = MessageMoveEvent.builder()
+                .eventId(EVENT_ID)
                 .user(User.fromUsername("bob"))
                 .messageMoves(
                     MessageMoves.builder()
@@ -144,6 +152,7 @@ class MessageMoveEventSerializationTest {
                 .build();
             private final String json = "{" +
                 "  \"MessageMoveEvent\": {" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                 "    \"user\": \"bob\"," +
                 "    \"previousMailboxIds\": [\"18\", \"24\"]," +
                 "    \"targetMailboxIds\": [\"36\"]," +
@@ -172,6 +181,20 @@ class MessageMoveEventSerializationTest {
         void nullPreviousMailboxIdsShouldBeRejected() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson("{" +
                 "  \"MessageMoveEvent\": {" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
+                "    \"user\": \"bob@domain.tld\"," +
+                "    \"previousMailboxIds\": null," +
+                "    \"targetMailboxIds\": [\"36\"]," +
+                "    \"messageIds\": [\"42\"]" +
+                "  }" +
+                "}").get())
+                .isInstanceOf(NoSuchElementException.class);
+        }
+
+        @Test
+        void missingEventIdMailboxIdsShouldBeRejected() {
+            assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson("{" +
+                "  \"MessageMoveEvent\": {" +
                 "    \"user\": \"bob@domain.tld\"," +
                 "    \"previousMailboxIds\": null," +
                 "    \"targetMailboxIds\": [\"36\"]," +
@@ -185,6 +208,7 @@ class MessageMoveEventSerializationTest {
         void nonCollectionPreviousMailboxIdsShouldBeRejected() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson("{" +
                 "  \"MessageMoveEvent\": {" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                 "    \"user\": \"bob@domain.tld\"," +
                 "    \"previousMailboxIds\": 42," +
                 "    \"targetMailboxIds\": [\"36\"]," +
@@ -198,6 +222,7 @@ class MessageMoveEventSerializationTest {
         void nonStringElementInPreviousMailboxIdsShouldBeRejected() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson("{" +
                 "  \"MessageMoveEvent\": {" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                 "    \"user\": \"bob@domain.tld\"," +
                 "    \"previousMailboxIds\": [42]," +
                 "    \"targetMailboxIds\": [\"36\"]," +
@@ -211,6 +236,7 @@ class MessageMoveEventSerializationTest {
         void nullElementInPreviousMailboxIdsShouldBeRejected() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson("{" +
                 "  \"MessageMoveEvent\": {" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                 "    \"user\": \"bob@domain.tld\"," +
                 "    \"previousMailboxIds\": [null]," +
                 "    \"targetMailboxIds\": [\"36\"]," +
@@ -224,6 +250,7 @@ class MessageMoveEventSerializationTest {
         void nullTargetMailboxIdsShouldBeRejected() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson("{" +
                 "  \"MessageMoveEvent\": {" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                 "    \"user\": \"bob@domain.tld\"," +
                 "    \"previousMailboxIds\": [\"36\"]," +
                 "    \"targetMailboxIds\": null," +
@@ -237,6 +264,7 @@ class MessageMoveEventSerializationTest {
         void nonCollectionTargetMailboxIdsShouldBeRejected() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson("{" +
                 "  \"MessageMoveEvent\": {" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                 "    \"user\": \"bob@domain.tld\"," +
                 "    \"previousMailboxIds\": [\"36\"]," +
                 "    \"targetMailboxIds\": 42," +
@@ -250,6 +278,7 @@ class MessageMoveEventSerializationTest {
         void nonStringElementInTargetMailboxIdsShouldBeRejected() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson("{" +
                 "  \"MessageMoveEvent\": {" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                 "    \"user\": \"bob@domain.tld\"," +
                 "    \"previousMailboxIds\": [\"36\"]," +
                 "    \"targetMailboxIds\": [42]," +
@@ -263,6 +292,7 @@ class MessageMoveEventSerializationTest {
         void nullElementInTargetMailboxIdsShouldBeRejected() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson("{" +
                 "  \"MessageMoveEvent\": {" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                 "    \"user\": \"bob@domain.tld\"," +
                 "    \"previousMailboxIds\": [\"36\"]," +
                 "    \"targetMailboxIds\": [null]," +
@@ -289,6 +319,7 @@ class MessageMoveEventSerializationTest {
         void nonCollectionMessageIdsShouldBeRejected() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson("{" +
                 "  \"MessageMoveEvent\": {" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                 "    \"user\": \"bob@domain.tld\"," +
                 "    \"previousMailboxIds\": [\"36\"]," +
                 "    \"targetMailboxIds\": [\"42\"]," +
@@ -302,6 +333,7 @@ class MessageMoveEventSerializationTest {
         void nonStringElementInMessageIdsShouldBeRejected() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson("{" +
                 "  \"MessageMoveEvent\": {" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                 "    \"user\": \"bob@domain.tld\"," +
                 "    \"previousMailboxIds\": [\"36\"]," +
                 "    \"targetMailboxIds\": [\"42\"]," +
@@ -315,6 +347,7 @@ class MessageMoveEventSerializationTest {
         void nullElementInMessageIdsShouldBeRejected() {
             assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson("{" +
                 "  \"MessageMoveEvent\": {" +
+                "    \"eventId\":\"6e0dd59d-660e-4d9b-b22f-0354479f47b4\"," +
                 "    \"user\": \"bob@domain.tld\"," +
                 "    \"previousMailboxIds\": [\"36\"]," +
                 "    \"targetMailboxIds\": [\"42\"]," +


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