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 f29f69a60227268bc5817dedd7cbf1ac6d6eebfc
Author: tran tien duc <[email protected]>
AuthorDate: Wed Feb 20 15:20:19 2019 +0700

    MAILBOX-379 Plug PreDeletionHooks to StoreMessageIdManager
---
 .../james/mailbox/extension/PreDeletionHook.java   |   5 +
 .../CassandraCombinationManagerTestSystem.java     |   3 +-
 .../CassandraMessageIdManagerSideEffectTest.java   |   7 +-
 .../CassandraMessageIdManagerStorageTest.java      |   3 +-
 .../CassandraMessageIdManagerTestSystem.java       |  11 +-
 .../cassandra/CassandraTestSystemFixture.java      |   9 +-
 .../ElasticSearchIntegrationTest.java              |   4 +-
 .../search/LuceneMessageSearchIndexTest.java       |   4 +-
 .../manager/InMemoryIntegrationResources.java      |   4 +-
 .../InMemoryMessageIdManagerSideEffectTest.java    |   8 +-
 .../store/search/SimpleMessageSearchIndexTest.java |   4 +-
 .../james/mailbox/store/StoreMessageIdManager.java |  24 +++-
 .../AbstractMessageIdManagerSideEffectTest.java    | 150 ++++++++++++++++++++-
 .../org/apache/james/modules/MailboxModule.java    |   3 +
 14 files changed, 217 insertions(+), 22 deletions(-)

diff --git 
a/mailbox/api/src/main/java/org/apache/james/mailbox/extension/PreDeletionHook.java
 
b/mailbox/api/src/main/java/org/apache/james/mailbox/extension/PreDeletionHook.java
index 41df20d..022e511 100644
--- 
a/mailbox/api/src/main/java/org/apache/james/mailbox/extension/PreDeletionHook.java
+++ 
b/mailbox/api/src/main/java/org/apache/james/mailbox/extension/PreDeletionHook.java
@@ -21,11 +21,14 @@ package org.apache.james.mailbox.extension;
 
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 import java.util.UUID;
 
 import org.apache.james.mailbox.MetadataWithMailboxId;
 import org.reactivestreams.Publisher;
 
+import com.google.common.collect.ImmutableSet;
+
 public interface PreDeletionHook {
 
     class DeletionId {
@@ -102,5 +105,7 @@ public interface PreDeletionHook {
         }
     }
 
+    Set<PreDeletionHook> NO_PRE_DELETION_HOOK = ImmutableSet.of();
+
     Publisher<Void> notifyDelete(DeleteOperation deleteOperation);
 }
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 4878a9b..31e3c87 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
@@ -26,6 +26,7 @@ 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.extension.PreDeletionHook;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.store.CombinationManagerTestSystem;
@@ -39,7 +40,7 @@ public class CassandraCombinationManagerTestSystem extends 
CombinationManagerTes
     public static CombinationManagerTestSystem 
createTestingData(CassandraCluster cassandra, QuotaManager quotaManager, 
EventBus eventBus) {
         CassandraMailboxSessionMapperFactory mapperFactory = 
CassandraTestSystemFixture.createMapperFactory(cassandra);
 
-        return new 
CassandraCombinationManagerTestSystem(CassandraTestSystemFixture.createMessageIdManager(mapperFactory,
 quotaManager, eventBus),
+        return new 
CassandraCombinationManagerTestSystem(CassandraTestSystemFixture.createMessageIdManager(mapperFactory,
 quotaManager, eventBus, PreDeletionHook.NO_PRE_DELETION_HOOK),
             mapperFactory,
             CassandraTestSystemFixture.createMailboxManager(mapperFactory));
     }
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 3b70449..2d76328 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
@@ -19,10 +19,13 @@
 
 package org.apache.james.mailbox.cassandra;
 
+import java.util.Set;
+
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.DockerCassandraRule;
 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.quota.QuotaManager;
 import org.apache.james.mailbox.store.AbstractMessageIdManagerSideEffectTest;
 import org.apache.james.mailbox.store.MessageIdManagerTestSystem;
@@ -60,7 +63,7 @@ public class CassandraMessageIdManagerSideEffectTest extends 
AbstractMessageIdMa
     }
 
     @Override
-    protected MessageIdManagerTestSystem createTestSystem(QuotaManager 
quotaManager, EventBus eventBus) {
-        return 
CassandraMessageIdManagerTestSystem.createTestingData(cassandra, quotaManager, 
eventBus);
+    protected MessageIdManagerTestSystem createTestSystem(QuotaManager 
quotaManager, EventBus eventBus, Set<PreDeletionHook> preDeletionHooks) {
+        return 
CassandraMessageIdManagerTestSystem.createTestingData(cassandra, quotaManager, 
eventBus, preDeletionHooks);
     }
 }
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 0902dce..99a9093 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
@@ -24,6 +24,7 @@ import 
org.apache.james.backends.cassandra.DockerCassandraRule;
 import org.apache.james.mailbox.cassandra.mail.MailboxAggregateModule;
 import org.apache.james.mailbox.events.InVMEventBus;
 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;
 import org.apache.james.mailbox.store.quota.NoQuotaManager;
@@ -64,6 +65,6 @@ public class CassandraMessageIdManagerStorageTest extends 
AbstractMessageIdManag
     @Override
     protected MessageIdManagerTestSystem createTestingData() {
         InVMEventBus eventBus = new InVMEventBus(new InVmEventDelivery(new 
NoopMetricFactory()));
-        return 
CassandraMessageIdManagerTestSystem.createTestingData(cassandra, new 
NoQuotaManager(), eventBus);
+        return 
CassandraMessageIdManagerTestSystem.createTestingData(cassandra, new 
NoQuotaManager(), eventBus, PreDeletionHook.NO_PRE_DELETION_HOOK);
     }
 }
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 0bdeb45..c0dd20d 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
@@ -19,9 +19,12 @@
 
 package org.apache.james.mailbox.cassandra;
 
+import java.util.Set;
+
 import org.apache.james.backends.cassandra.CassandraCluster;
 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;
 import org.apache.james.mailbox.store.MessageIdManagerTestSystem;
@@ -30,10 +33,11 @@ import 
org.apache.james.mailbox.store.quota.StoreCurrentQuotaManager;
 
 class CassandraMessageIdManagerTestSystem {
 
-    static MessageIdManagerTestSystem createTestingData(CassandraCluster 
cassandra, QuotaManager quotaManager, EventBus eventBus) {
+    static MessageIdManagerTestSystem createTestingData(CassandraCluster 
cassandra, QuotaManager quotaManager, EventBus eventBus,
+                                                        Set<PreDeletionHook> 
preDeletionHooks) {
         CassandraMailboxSessionMapperFactory mapperFactory = 
CassandraTestSystemFixture.createMapperFactory(cassandra);
 
-        return new 
MessageIdManagerTestSystem(CassandraTestSystemFixture.createMessageIdManager(mapperFactory,
 quotaManager, eventBus),
+        return new 
MessageIdManagerTestSystem(CassandraTestSystemFixture.createMessageIdManager(mapperFactory,
 quotaManager, eventBus, preDeletionHooks),
             new CassandraMessageId.Factory(),
             mapperFactory,
             CassandraTestSystemFixture.createMailboxManager(mapperFactory)) {
@@ -48,7 +52,8 @@ class CassandraMessageIdManagerTestSystem {
             (StoreCurrentQuotaManager) currentQuotaManager,
             mailboxManager.getQuotaComponents().getQuotaRootResolver(), 
mailboxManager.getEventBus(), quotaManager);
         mailboxManager.getEventBus().register(listeningCurrentQuotaUpdater);
-        return new 
MessageIdManagerTestSystem(CassandraTestSystemFixture.createMessageIdManager(mapperFactory,
 quotaManager, mailboxManager.getEventBus()),
+        return new 
MessageIdManagerTestSystem(CassandraTestSystemFixture.createMessageIdManager(mapperFactory,
 quotaManager, mailboxManager.getEventBus(),
+            PreDeletionHook.NO_PRE_DELETION_HOOK),
             new CassandraMessageId.Factory(),
             mapperFactory,
             mailboxManager);
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 b1bef0a..4c32722 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
@@ -21,6 +21,8 @@ package org.apache.james.mailbox.cassandra;
 
 import static org.mockito.Mockito.mock;
 
+import java.util.Set;
+
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
 import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
@@ -33,6 +35,7 @@ import 
org.apache.james.mailbox.cassandra.quota.CassandraPerUserMaxQuotaManager;
 import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.InVMEventBus;
 import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
+import org.apache.james.mailbox.extension.PreDeletionHook;
 import org.apache.james.mailbox.quota.CurrentQuotaManager;
 import org.apache.james.mailbox.quota.MaxQuotaManager;
 import org.apache.james.mailbox.quota.QuotaManager;
@@ -82,7 +85,8 @@ class CassandraTestSystemFixture {
         return cassandraMailboxManager;
     }
 
-    static StoreMessageIdManager 
createMessageIdManager(CassandraMailboxSessionMapperFactory mapperFactory, 
QuotaManager quotaManager, EventBus eventBus) {
+    static StoreMessageIdManager 
createMessageIdManager(CassandraMailboxSessionMapperFactory mapperFactory, 
QuotaManager quotaManager, EventBus eventBus,
+                                                        Set<PreDeletionHook> 
preDeletionHooks) {
         CassandraMailboxManager mailboxManager = 
createMailboxManager(mapperFactory);
         return new StoreMessageIdManager(
             mailboxManager,
@@ -90,7 +94,8 @@ class CassandraTestSystemFixture {
             eventBus,
             new CassandraMessageId.Factory(),
             quotaManager,
-            new 
DefaultUserQuotaRootResolver(mailboxManager.getSessionProvider(), 
mapperFactory));
+            new 
DefaultUserQuotaRootResolver(mailboxManager.getSessionProvider(), 
mapperFactory),
+            preDeletionHooks);
     }
 
     static MaxQuotaManager createMaxQuotaManager(CassandraCluster cassandra) {
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 4556681..e49c063 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
@@ -42,6 +42,7 @@ import 
org.apache.james.mailbox.elasticsearch.query.QueryConverter;
 import org.apache.james.mailbox.elasticsearch.search.ElasticSearchSearcher;
 import org.apache.james.mailbox.events.InVMEventBus;
 import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
+import org.apache.james.mailbox.extension.PreDeletionHook;
 import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.inmemory.InMemoryMailboxManager;
 import org.apache.james.mailbox.inmemory.InMemoryMailboxSessionMapperFactory;
@@ -159,7 +160,8 @@ public class ElasticSearchIntegrationTest extends 
AbstractMessageSearchIndexTest
             eventBus,
             storeMailboxManager.getMessageIdFactory(),
             quotaComponents.getQuotaManager(),
-            quotaComponents.getQuotaRootResolver());
+            quotaComponents.getQuotaRootResolver(),
+            PreDeletionHook.NO_PRE_DELETION_HOOK);
 
         eventBus.register(elasticSearchListeningMessageSearchIndex);
         this.messageSearchIndex = elasticSearchListeningMessageSearchIndex;
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 9dffa1d..d82be9c 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
@@ -24,6 +24,7 @@ import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
 import org.apache.james.mailbox.events.InVMEventBus;
 import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.extension.PreDeletionHook;
 import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.inmemory.InMemoryMailboxManager;
 import org.apache.james.mailbox.inmemory.InMemoryMailboxSessionMapperFactory;
@@ -85,7 +86,8 @@ public class LuceneMessageSearchIndexTest extends 
AbstractMessageSearchIndexTest
             eventBus,
             storeMailboxManager.getMessageIdFactory(),
             quotaComponents.getQuotaManager(),
-            quotaComponents.getQuotaRootResolver());
+            quotaComponents.getQuotaRootResolver(),
+            PreDeletionHook.NO_PRE_DELETION_HOOK);
 
         eventBus.register(luceneMessageSearchIndex);
         this.messageSearchIndex = luceneMessageSearchIndex;
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 1f5beff..9e5e5a5 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
@@ -26,6 +26,7 @@ import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
 import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.InVMEventBus;
 import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
+import org.apache.james.mailbox.extension.PreDeletionHook;
 import org.apache.james.mailbox.inmemory.InMemoryMailboxManager;
 import org.apache.james.mailbox.inmemory.InMemoryMailboxSessionMapperFactory;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
@@ -193,7 +194,8 @@ public class InMemoryIntegrationResources implements 
IntegrationResources<StoreM
             mailboxManager.getEventBus(),
             factory,
             quotaComponents.getQuotaManager(),
-            quotaComponents.getQuotaRootResolver());
+            quotaComponents.getQuotaRootResolver(),
+            PreDeletionHook.NO_PRE_DELETION_HOOK);
     }
     
     @Override
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 e270749..c99bb6b 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
@@ -19,9 +19,12 @@
 
 package org.apache.james.mailbox.inmemory.manager;
 
+import java.util.Set;
+
 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.extension.PreDeletionHook;
 import org.apache.james.mailbox.inmemory.InMemoryMailboxManager;
 import org.apache.james.mailbox.inmemory.InMemoryMailboxSessionMapperFactory;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
@@ -55,7 +58,7 @@ public class InMemoryMessageIdManagerSideEffectTest extends 
AbstractMessageIdMan
     }
 
     @Override
-    protected MessageIdManagerTestSystem createTestSystem(QuotaManager 
quotaManager, EventBus eventBus) {
+    protected MessageIdManagerTestSystem createTestSystem(QuotaManager 
quotaManager, EventBus eventBus, Set<PreDeletionHook> preDeletionHooks) {
         InMemoryMailboxSessionMapperFactory mapperFactory = new 
InMemoryMailboxSessionMapperFactory();
 
         FakeAuthenticator fakeAuthenticator = new FakeAuthenticator();
@@ -87,7 +90,8 @@ public class InMemoryMessageIdManagerSideEffectTest extends 
AbstractMessageIdMan
             eventBus,
             messageIdFactory,
             quotaManager,
-            quotaComponents.getQuotaRootResolver());
+            quotaComponents.getQuotaRootResolver(),
+            preDeletionHooks);
         return new MessageIdManagerTestSystem(messageIdManager, 
messageIdFactory, mapperFactory, mailboxManager);
     }
 }
diff --git 
a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
 
b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
index 38cd886..8b423d6 100644
--- 
a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
+++ 
b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
@@ -21,6 +21,7 @@ package org.apache.james.mailbox.store.search;
 
 import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
 import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.extension.PreDeletionHook;
 import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
 import org.apache.james.mailbox.store.StoreMessageIdManager;
 import org.junit.Ignore;
@@ -47,7 +48,8 @@ public class SimpleMessageSearchIndexTest extends 
AbstractMessageSearchIndexTest
             storeMailboxManager.getEventBus(),
             storeMailboxManager.getMessageIdFactory(),
             storeMailboxManager.getQuotaComponents().getQuotaManager(),
-            storeMailboxManager.getQuotaComponents().getQuotaRootResolver());
+            storeMailboxManager.getQuotaComponents().getQuotaRootResolver(),
+            PreDeletionHook.NO_PRE_DELETION_HOOK);
     }
 
     /**
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 3031b9b..808f8aa 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
@@ -37,10 +37,12 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.MetadataWithMailboxId;
 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;
+import org.apache.james.mailbox.extension.PreDeletionHook;
 import org.apache.james.mailbox.model.DeleteResult;
 import org.apache.james.mailbox.model.MailboxACL.Right;
 import org.apache.james.mailbox.model.MailboxId;
@@ -95,17 +97,19 @@ public class StoreMessageIdManager implements 
MessageIdManager {
     private final MessageId.Factory messageIdFactory;
     private final QuotaManager quotaManager;
     private final QuotaRootResolver quotaRootResolver;
+    private final Set<PreDeletionHook> preDeletionHooks;
 
     @Inject
     public StoreMessageIdManager(MailboxManager mailboxManager, 
MailboxSessionMapperFactory mailboxSessionMapperFactory,
                                  EventBus eventBus, MessageId.Factory 
messageIdFactory,
-                                 QuotaManager quotaManager, QuotaRootResolver 
quotaRootResolver) {
+                                 QuotaManager quotaManager, QuotaRootResolver 
quotaRootResolver, Set<PreDeletionHook> preDeletionHooks) {
         this.mailboxManager = mailboxManager;
         this.mailboxSessionMapperFactory = mailboxSessionMapperFactory;
         this.eventBus = eventBus;
         this.messageIdFactory = messageIdFactory;
         this.quotaManager = quotaManager;
         this.quotaRootResolver = quotaRootResolver;
+        this.preDeletionHooks = preDeletionHooks;
     }
 
     @Override
@@ -167,7 +171,7 @@ public class StoreMessageIdManager implements 
MessageIdManager {
             .collect(Guavate.toImmutableList());
 
         if (!messageList.isEmpty()) {
-            delete(messageIdMapper, messageList, mailboxSession);
+            deleteWithPreHooks(messageIdMapper, messageList, mailboxSession);
             return DeleteResult.destroyed(messageId);
         }
         return DeleteResult.notFound(messageId);
@@ -187,7 +191,7 @@ public class StoreMessageIdManager implements 
MessageIdManager {
             .collect(Guavate.toImmutableSet());
         Sets.SetView<MessageId> nonAccessibleMessages = 
Sets.difference(ImmutableSet.copyOf(messageIds), accessibleMessages);
 
-        delete(messageIdMapper, messageList, mailboxSession);
+        deleteWithPreHooks(messageIdMapper, messageList, mailboxSession);
 
         return DeleteResult.builder()
             .addDestroyed(accessibleMessages)
@@ -195,11 +199,21 @@ public class StoreMessageIdManager implements 
MessageIdManager {
             .build();
     }
 
-    private void delete(MessageIdMapper messageIdMapper, List<MailboxMessage> 
messageList, MailboxSession mailboxSession) throws MailboxException {
+    private void deleteWithPreHooks(MessageIdMapper messageIdMapper, 
List<MailboxMessage> messageList, MailboxSession mailboxSession) throws 
MailboxException {
         ImmutableList<MetadataWithMailboxId> metadataWithMailbox = 
messageList.stream()
-            .map(MetadataWithMailboxId::from)
+            .map(mailboxMessage -> 
MetadataWithMailboxId.from(mailboxMessage.metaData(), 
mailboxMessage.getMailboxId()))
             .collect(Guavate.toImmutableList());
 
+        PreDeletionHook.DeleteOperation deleteOperation = 
PreDeletionHook.DeleteOperation.from(metadataWithMailbox);
+        Flux.fromIterable(preDeletionHooks)
+            .flatMap(preDeletionHook -> 
preDeletionHook.notifyDelete(deleteOperation))
+            .then(Mono.fromRunnable(Throwing.runnable(
+                () -> delete(messageIdMapper, messageList, mailboxSession, 
metadataWithMailbox))))
+            .block();
+    }
+
+    private void delete(MessageIdMapper messageIdMapper, List<MailboxMessage> 
messageList, MailboxSession mailboxSession,
+                        ImmutableList<MetadataWithMailboxId> 
metadataWithMailbox) throws MailboxException {
         messageIdMapper.delete(
             messageList.stream()
                 .collect(Guavate.toImmutableListMultimap(
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 b798123..f26e772 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
@@ -21,11 +21,16 @@ package org.apache.james.mailbox.store;
 
 import static org.apache.james.mailbox.fixture.MailboxFixture.ALICE;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
 
 import javax.mail.Flags;
 
@@ -37,6 +42,7 @@ import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageManager.FlagsUpdateMode;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.MetadataWithMailboxId;
 import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.InVMEventBus;
 import org.apache.james.mailbox.events.MailboxListener;
@@ -44,6 +50,7 @@ import org.apache.james.mailbox.events.MessageMoveEvent;
 import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.OverQuotaException;
+import org.apache.james.mailbox.extension.PreDeletionHook;
 import org.apache.james.mailbox.fixture.MailboxFixture;
 import org.apache.james.mailbox.model.FetchGroupImpl;
 import org.apache.james.mailbox.model.MessageId;
@@ -58,13 +65,18 @@ import org.apache.james.mailbox.util.EventCollector;
 import org.apache.james.metrics.api.NoopMetricFactory;
 import org.assertj.core.api.AbstractListAssert;
 import org.assertj.core.api.ObjectAssert;
+import org.assertj.core.api.SoftAssertions;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.mockito.ArgumentCaptor;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSortedMap;
 
+import reactor.core.publisher.Mono;
+
 public abstract class AbstractMessageIdManagerSideEffectTest {
     private static final Quota<QuotaCount> OVER_QUOTA = 
Quota.<QuotaCount>builder()
         .used(QuotaCount.count(102))
@@ -87,8 +99,10 @@ public abstract class AbstractMessageIdManagerSideEffectTest 
{
     private MessageIdManagerTestSystem testingData;
     private EventCollector eventCollector;
     private EventBus eventBus;
+    private PreDeletionHook preDeletionHook1;
+    private PreDeletionHook preDeletionHook2;
 
-    protected abstract MessageIdManagerTestSystem 
createTestSystem(QuotaManager quotaManager, EventBus eventBus) throws Exception;
+    protected abstract MessageIdManagerTestSystem 
createTestSystem(QuotaManager quotaManager, EventBus eventBus, 
Set<PreDeletionHook> preDeletionHooks) throws Exception;
 
     public void setUp() throws Exception {
         eventBus = new InVMEventBus(new InVmEventDelivery(new 
NoopMetricFactory()));
@@ -96,7 +110,8 @@ public abstract class AbstractMessageIdManagerSideEffectTest 
{
         quotaManager = mock(QuotaManager.class);
 
         session = MailboxSessionUtil.create(ALICE);
-        testingData = createTestSystem(quotaManager, eventBus);
+        setupMockForPreDeletionHooks();
+        testingData = createTestSystem(quotaManager, eventBus, 
ImmutableSet.of(preDeletionHook1, preDeletionHook2));
         messageIdManager = testingData.getMessageIdManager();
 
         mailbox1 = testingData.createMailbox(MailboxFixture.INBOX_ALICE, 
session);
@@ -104,6 +119,15 @@ public abstract class 
AbstractMessageIdManagerSideEffectTest {
         mailbox3 = testingData.createMailbox(MailboxFixture.SENT_ALICE, 
session);
     }
 
+    private void setupMockForPreDeletionHooks() {
+        preDeletionHook1 = mock(PreDeletionHook.class);
+        
when(preDeletionHook1.notifyDelete(any(PreDeletionHook.DeleteOperation.class)))
+            .thenReturn(Mono.empty());
+
+        preDeletionHook2 = mock(PreDeletionHook.class);
+        
when(preDeletionHook2.notifyDelete(any(PreDeletionHook.DeleteOperation.class)))
+            .thenReturn(Mono.empty());
+    }
     @Test
     public void deleteShouldCallEventDispatcher() throws Exception {
         givenUnlimitedQuota();
@@ -164,6 +188,128 @@ public abstract class 
AbstractMessageIdManagerSideEffectTest {
     }
 
     @Test
+    public void deletesShouldCallAllPreDeletionHooks() throws Exception {
+        givenUnlimitedQuota();
+
+        MessageId messageId = testingData.persist(mailbox1.getMailboxId(), 
messageUid1, FLAGS, session);
+        messageIdManager.delete(messageId, 
ImmutableList.of(mailbox1.getMailboxId()), session);
+
+        ArgumentCaptor<PreDeletionHook.DeleteOperation> preDeleteCaptor1 = 
ArgumentCaptor.forClass(PreDeletionHook.DeleteOperation.class);
+        ArgumentCaptor<PreDeletionHook.DeleteOperation> preDeleteCaptor2 = 
ArgumentCaptor.forClass(PreDeletionHook.DeleteOperation.class);
+        verify(preDeletionHook1, 
times(1)).notifyDelete(preDeleteCaptor1.capture());
+        verify(preDeletionHook2, 
times(1)).notifyDelete(preDeleteCaptor2.capture());
+
+        assertThat(preDeleteCaptor1.getValue().getDeletionMetadataList())
+            .hasSize(1)
+            
.hasSameElementsAs(preDeleteCaptor2.getValue().getDeletionMetadataList())
+            .allSatisfy(deleteMetadata -> SoftAssertions.assertSoftly(softy -> 
{
+                
softy.assertThat(deleteMetadata.getMailboxId()).isEqualTo(mailbox1.getMailboxId());
+                
softy.assertThat(deleteMetadata.getMessageMetaData().getMessageId()).isEqualTo(messageId);
+                
softy.assertThat(deleteMetadata.getMessageMetaData().getFlags()).isEqualTo(FLAGS);
+            }));
+
+    }
+
+    @Test
+    public void 
deletesShouldCallAllPreDeletionHooksOnEachMessageDeletionCall() throws 
Exception {
+        givenUnlimitedQuota();
+
+        MessageId messageId1 = testingData.persist(mailbox1.getMailboxId(), 
messageUid1, FLAGS, session);
+        MessageId messageId2 = testingData.persist(mailbox1.getMailboxId(), 
messageUid1, FLAGS, session);
+        messageIdManager.delete(messageId1, 
ImmutableList.of(mailbox1.getMailboxId()), session);
+        messageIdManager.delete(messageId2, 
ImmutableList.of(mailbox1.getMailboxId()), session);
+
+        ArgumentCaptor<PreDeletionHook.DeleteOperation> preDeleteCaptor1 = 
ArgumentCaptor.forClass(PreDeletionHook.DeleteOperation.class);
+        ArgumentCaptor<PreDeletionHook.DeleteOperation> preDeleteCaptor2 = 
ArgumentCaptor.forClass(PreDeletionHook.DeleteOperation.class);
+        verify(preDeletionHook1, 
times(2)).notifyDelete(preDeleteCaptor1.capture());
+        verify(preDeletionHook2, 
times(2)).notifyDelete(preDeleteCaptor2.capture());
+
+        assertThat(preDeleteCaptor1.getAllValues())
+            .hasSize(2)
+            .hasSameElementsAs(preDeleteCaptor2.getAllValues())
+            
.flatExtracting(PreDeletionHook.DeleteOperation::getDeletionMetadataList)
+            .allSatisfy(deleteMetadata -> SoftAssertions.assertSoftly(softy -> 
{
+                
softy.assertThat(deleteMetadata.getMailboxId()).isEqualTo(mailbox1.getMailboxId());
+                
softy.assertThat(deleteMetadata.getMessageMetaData().getFlags()).isEqualTo(FLAGS);
+            }))
+            .extracting(deleteMetadata -> 
deleteMetadata.getMessageMetaData().getMessageId())
+            .containsOnly(messageId1, messageId2);
+
+    }
+
+    @Test
+    public void 
deletesShouldCallAllPreDeletionHooksOnEachMessageDeletionOnDifferentMailboxes() 
throws Exception {
+        givenUnlimitedQuota();
+
+        MessageId messageId1 = testingData.persist(mailbox1.getMailboxId(), 
messageUid1, FLAGS, session);
+        MessageId messageId2 = testingData.persist(mailbox2.getMailboxId(), 
messageUid1, FLAGS, session);
+        messageIdManager.delete(messageId1, 
ImmutableList.of(mailbox1.getMailboxId()), session);
+        messageIdManager.delete(messageId2, 
ImmutableList.of(mailbox2.getMailboxId()), session);
+
+        ArgumentCaptor<PreDeletionHook.DeleteOperation> preDeleteCaptor1 = 
ArgumentCaptor.forClass(PreDeletionHook.DeleteOperation.class);
+        ArgumentCaptor<PreDeletionHook.DeleteOperation> preDeleteCaptor2 = 
ArgumentCaptor.forClass(PreDeletionHook.DeleteOperation.class);
+        verify(preDeletionHook1, 
times(2)).notifyDelete(preDeleteCaptor1.capture());
+        verify(preDeletionHook2, 
times(2)).notifyDelete(preDeleteCaptor2.capture());
+
+        assertThat(preDeleteCaptor1.getAllValues())
+            .hasSameElementsAs(preDeleteCaptor2.getAllValues())
+            
.flatExtracting(PreDeletionHook.DeleteOperation::getDeletionMetadataList)
+            .extracting(deleteMetadata -> 
deleteMetadata.getMessageMetaData().getMessageId())
+            .containsOnly(messageId1, messageId2);
+
+        assertThat(preDeleteCaptor1.getAllValues())
+            .hasSameElementsAs(preDeleteCaptor2.getAllValues())
+            
.flatExtracting(PreDeletionHook.DeleteOperation::getDeletionMetadataList)
+            .extracting(MetadataWithMailboxId::getMailboxId)
+            .containsOnly(mailbox1.getMailboxId(), mailbox2.getMailboxId());
+    }
+
+    @Test
+    public void deletesShouldNotBeExecutedWhenOneOfPreDeleteHooksFails() 
throws Exception {
+        givenUnlimitedQuota();
+        
when(preDeletionHook1.notifyDelete(any(PreDeletionHook.DeleteOperation.class)))
+            .thenThrow(new RuntimeException("throw at hook 1"));
+
+        MessageId messageId = testingData.persist(mailbox1.getMailboxId(), 
messageUid1, FLAGS, session);
+        assertThatThrownBy(() -> messageIdManager.delete(messageId, 
ImmutableList.of(mailbox1.getMailboxId()), session))
+            .isInstanceOf(RuntimeException.class);
+
+        assertThat(messageIdManager.getMessages(ImmutableList.of(messageId), 
FetchGroupImpl.MINIMAL, session)
+                .stream()
+                .map(MessageResult::getMessageId))
+            .hasSize(1)
+            .containsOnly(messageId);
+    }
+
+    @Test
+    public void deletesShouldBeExecutedAfterAllHooksFinish() throws Exception {
+        givenUnlimitedQuota();
+
+        CountDownLatch latchForHook1 = new CountDownLatch(1);
+        
when(preDeletionHook1.notifyDelete(any(PreDeletionHook.DeleteOperation.class)))
+            .thenAnswer(invocation -> {
+                latchForHook1.countDown();
+                return Mono.empty();
+            });
+
+        CountDownLatch latchForHook2 = new CountDownLatch(1);
+        
when(preDeletionHook2.notifyDelete(any(PreDeletionHook.DeleteOperation.class)))
+            .thenAnswer(invocation -> {
+                latchForHook2.countDown();
+                return Mono.empty();
+            });
+
+        MessageId messageId = testingData.persist(mailbox1.getMailboxId(), 
messageUid1, FLAGS, session);
+        messageIdManager.delete(messageId, 
ImmutableList.of(mailbox1.getMailboxId()), session);
+
+        latchForHook1.await();
+        latchForHook2.await();
+
+        assertThat(messageIdManager.getMessages(ImmutableList.of(messageId), 
FetchGroupImpl.MINIMAL, session))
+            .isEmpty();
+    }
+
+    @Test
     public void 
setInMailboxesShouldNotCallDispatcherWhenMessageAlreadyInMailbox() throws 
Exception {
         givenUnlimitedQuota();
         MessageId messageId = testingData.persist(mailbox1.getMailboxId(), 
messageUid1, FLAGS, session);
diff --git 
a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxModule.java
 
b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxModule.java
index f95e235..82ba294 100644
--- 
a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxModule.java
+++ 
b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxModule.java
@@ -23,6 +23,7 @@ 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.extension.PreDeletionHook;
 import org.apache.james.mailbox.store.SystemMailboxesProviderImpl;
 import org.apache.james.utils.GuiceProbe;
 
@@ -48,6 +49,8 @@ public class MailboxModule extends AbstractModule {
 
         bind(SystemMailboxesProviderImpl.class).in(Scopes.SINGLETON);
         
bind(SystemMailboxesProvider.class).to(SystemMailboxesProviderImpl.class);
+
+        Multibinder<PreDeletionHook> noPreDeletionHooks = 
Multibinder.newSetBinder(binder(), PreDeletionHook.class);
     }
 
 }


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

Reply via email to